]>
&header;

## はじめに

このページは、FreeBSD のセキュリティに関して、 初心者、ベテランを問わず手助けになるよう書かれています。 FreeBSD では、セキュリティを非常に重要なものと捉えており、 OS をできる限りセキュアなものにしようと常に努力しています。

ここではどのようにしてさまざまな攻撃からあなたのシステムを守るか、 またセキュリティに関わるバグを発見した場合に誰に連絡すれば良いのか、 などについて、多くの情報や情報へのリンクを掲載しています。 また、システムプログラマ向けに、セキュリティ上の弱点を作成しないようにするための さまざまな手法を紹介する項も含まれています。

## 目次

- FreeBSD セキュリティオフィサについて
- 情報の取り扱いに関する方針
- FreeBSD のセキュリティ勧告
- FreeBSD セキュリティメーリングリストについて
- FreeBSD セキュリティの Tips と Tricks
- 安全なプログラミングのためのガイドライン
- その他の関連するセキュリティ情報

## FreeBSD セキュリティオフィサとセキュリティオフィサチーム

セキュリティに関して取り組んでいる人たちとの情報交換を円滑にするため、 FreeBSD ではセキュリティ関係の窓口としてセキュリティオフィサを設けています。

もしセキュリティに関するバグの可能性について FreeBSD プロジェクトと連絡をとる必要が生じたら、 発見したことの詳細と、何が問題となっているのかを書いて セキュリティオフィサに メールを送ってください。

FreeBSD プロジェクトでは、脆弱性の報告に対して臨機応変に対応する目的で セキュリティオフィサのメールエイリアスに 4 人 (セキュリティオフィサ、セキュリティオフィサ補佐、コアチームメンバ 2 人) が登録されています。つまり、 <security-officer@FreeBSD.org> へ送られたメールは、現在以下のメールアドレスへ届くようになっています。

Jacques Vidrine <nectar@FreeBSD.org> | セキュリティオフィサ
Chris Faulhaber <jedgar@FreeBSD.org> | セキュリティオフィサ補佐
Robert Watson <rwatson@FreeBSD.org> | FreeBSD コアチームメンバ、リリースエンジニアリング渉外、 TrustedBSD プロジェクト渉外、システムセキュリティアーキテクチャの専門家
Warner Losh <imp@FreeBSD.org> | FreeBSD コアチーム渉外、名誉セキュリティオフィサ

また、セキュリティオフィサが選出したコミッターグループである セキュリティオフィサチーム <security-team@FreeBSD.org> が、 セキュリティオフィサをサポートしています。

セキュリティオフィサ宛のメッセージに暗号化が必要な場合には、 セキュリティオフィサの PGP 公開鍵を使って暗号化してください。

## 情報の取り扱いに関する方針

セキュリティオフィサは一般的な方針として、 脆弱性の発見から、その危険性の解析と修正、修正のテスト、 関係する他の組織との調整などに必要と思われる時間が経過した後に、 その問題に関するすべての情報を公開することを原則とします。

セキュリティオフィサは、 FreeBSD プロジェクトの資源を脅かすような緊急性の高い脆弱性を FreeBSD クラスタ管理者の一人ないし複数の人たちにかならず通知します。

セキュリティオフィサは、 問題を完全に理解したり修正するために専門的知識や意見が必要とされる場合、 報告されたセキュリティ上の脆弱性について議論を行なうために セキュリティオフィサ以外の FreeBSD の開発者や外部の開発者に協力を求めることがあります。 報告された脆弱性に関する情報には不必要な流出を最小限に抑える努力を行い、また、 議論に参加する専門家はセキュリティオフィサの方針に従います。 過去、議論に参加した専門家たちは、FFS、VM システム、ネットワークスタックなど、 オペレーティングシステムの非常に複雑なコンポーネントについて 豊富な経験を持っていることを理由に選ばれています。

FreeBSD のリリース作業が進行中の場合、セキュリティオフィサは 適切なリリースサイクルや、予定されているリリースに深刻なセキュリティ上の バグが含まれているかどうかといった情報を判断材料として提供する目的で、 リリースエンジニアに脆弱性の存在やその影響の大きさを知らせることがあります。 ただしそれが必要だと判断された場合には、 脆弱性の存在やその影響に関する情報の不必要な漏洩を防ぐために、 リリースエンジニアに脆弱性の情報を提供しない場合もあります。

FreeBSD セキュリティオフィサは、FreeBSD とコードを共有しているサードパーティベンダ (OpenBSD および NetBSD プロジェクト、Apple、FreeBSD に由来するソフトウェアのベンダ、 Linux ベンダのセキュリティリスト) はもちろんのこと、 他の団体や CERT (訳注: 日本では JPCERT/CC) のような、脆弱性やセキュリティに関する出来事を追跡する組織と 緊密に協調して作業を行っています。 脆弱性は FreeBSD 以外の実装にも影響することがあり、(頻繁ではありませんが) 世界中のネットワークコミュニティに影響する可能性もあります。 そのような際、セキュリティオフィサは脆弱性に関する情報を他の団体へ公開することがあります。 もしそれが不都合な場合は、脆弱性の報告にその旨を明記してください。

あなたが情報を提供する際に、提供する情報に何か特別な扱いが必要ならば、 それを明記するのを忘れないようにお願いします。

脆弱性の報告を行なう際に、報告者が他のベンダとの間で公開の日程を調整したいと考えている場合は、 脆弱性の報告にその旨を明記してください。明確な指定がない場合、 FreeBSD セキュリティオフィサは、解決策の検証が十分に行なわれ次第、 可能な限り迅速に情報を公開できるような時期を選びます。 ただし、もし脆弱性が (bugtraq のような) 公的なフォーラムで活発に議論されているとか、 すでに積極的に悪用されているといった状態ならば、 セキュリティオフィサはユーザコミュニティの安全を最大限に確保するため、 報告者の指定した公開スケジュールを無視する可能性があることに注意してください。

報告者は FreeBSD プロジェクトがオープンソースプロジェクトだということ、 また、FreeBSD のソースツリーに加えられたあらゆる変更が 記録されているリビジョン管理情報は、世界中からアクセス可能であるということに 注意してください。 公開スケジュールの指定は、セキュリティ勧告、修正パッチ、更新情報の公開に加え、 ソースツリーへの最初の修正も考慮したものである必要があります。 なお、セキュリティ勧告、修正パッチ、バイナリアップデートの生成にはリビジョン管理システムが利用されるため、 ツリーへの修正とこれらの作業の間には必然的に時間的な遅れが生じます。

情報を提供する際は、PGP を使って暗号化しても構いません。 また、その旨を明記すれば、それに対する返信も PGP を用いて暗号化されます。

## FreeBSD のセキュリティ勧告

FreeBSD セキュリティオフィサは、以下の FreeBSD 開発ブランチに対してセキュリティ勧告を提供しています。 これには -STABLE ブランチ と セキュリティブランチ が含まれます (-CURRENT ブランチ に対する勧告は提供されません)。

- 通常、-STABLE ブランチは一つだけですが、 (たとえば FreeBSD 4.x から 5.x のように) 開発の中心となるブランチが新しいものへと移行する期間は 二つの -STABLE ブランチが存在することになります。 -STABLE ブランチには `RELENG_4` のような CVS タグ名が付けられています。 これに対応する構築物は `FreeBSD 4.6-STABLE` のような名前になります。

- FreeBSD の各リリースには、 対応するセキュリティブランチがひとつ用意されています。 セキュリティブランチには `RELENG_4_6` のような CVS タグ名が付けられています。 これに対応する構築物は `FreeBSD 4.6-RELEASE-p7` のような名前になります。

各ブランチに対するセキュリティオフィサのサポートには、 「原則としてリリース後 12 ヵ月間」という期限があります。 現在サポートされているブランチの保守終了予定日は、次のとおりです。 保守終了予定日の列には、 そのブランチに対応する最も早い保守終了予定日が記入されています。ただし、 これらの予定日は延長される可能性があること、また、そうするにふさわしい理由があれば ブランチの保守が記載されている日付よりも早く終了する可能性もあるということに ご注意ください。

ブランチ | リリース | 保守終了予定日
--- | --- | ---
RELENG_4 | なし | 2004 年 10 月 31 日
RELENG_4_8 | 4.8-RELEASE | 2004 年 3 月 31日
RELENG_4_9 | 4.9-RELEASE | 2004 年 10 月 31日
RELENG_5_1 | 5.1-RELEASE | 2004 年 2 月 28 日
RELENG_5_2 | 5.2-RELEASE | 2004 年 7 月 31 日

これ以前の古いリリースについては、 積極的にメンテナンスされることはありませんので、 上記のサポートされているリリースのいずれかへのアップグレードを強く推奨します。

セキュリティに関する修正は FreeBSD の開発と同様に、まず FreeBSD-current ブランチに導入されます。 そして数日間のテストを経て、わたしたちのカバーしている FreeBSD-stable ブランチに対応するように修正内容が持ち込まれ、 勧告が公表されることになります。

2002 年に発行された勧告に関する統計情報:

- ベースシステムに関するセキュリティ勧告は、(さまざまな緊急度のものが) 44 発行されました。
- FreeBSD のみが影響を受けるセキュリティ上の弱点を扱った勧告は、12 ありました。 残りの 32 勧告は、他の少なくとも一つ以上の OS も影響を受けるものです (これの原因の多くは、ソースコードを共有していることによるものでした)。
- セキュリティ情報は、6 発行されました。これは、オプションとして Ports Collection に含まれているサードパーティ製アプリケーションの、 全部で 95 ある問題を扱っています。

セキュリティ勧告は、以下の FreeBSD メーリングリストを通じて公表されます。

- FreeBSD-security-notifications@FreeBSD.org
- FreeBSD-security@FreeBSD.org
- FreeBSD-announce@FreeBSD.org (訳注: この内容は announce-jp@jp.FreeBSD.org にも配送されます)

勧告は、常に FreeBSD セキュリティオフィサの PGP 鍵 で署名され、 FTP CERT リポジトリ に関連パッチとともにアーカイブされます。 これ (訳注: 原文のこと) を書いている時点では、以下の勧告が公開されています (このリストは数日ほど情報が古い場合があります。 最新の勧告は FTP サイト をチェックしてください):

訳注:いくつかのセキュリティ勧告には、FreeBSD 日本語ドキュメンテーションプロジェクト(doc-jp)による日本語版が存在します。 この翻訳は以下のリンクから読むことができますが、 announce-jp@jp.FreeBSD.org にも配送されます。 ただし、これらは doc-jp が参考のために提供するもので、 翻訳者および doc-jp は、その内容についていかなる保証もいたしません。

日本語訳についてのお問い合わせは、 doc-jp@jp.FreeBSD.org までお願いします。この日本語訳は PGP 署名されていませんので、 パッチ等の内容が改竄されていないことを確認するために PGP のチェックを行なう場合には、原文を参照するようにお願いします。

&advisories.html.inc;

## FreeBSD のセキュリティメーリングリストについて

もしいくつかの FreeBSD システムを管理/利用しているのなら、 以下のメーリングリストのうち少なくとも一つに参加するべきです:

freebsd-security | セキュリティ一般に関する議論
freebsd-security-notifications | セキュリティ告知 (流量の少ないモデレートメーリングリスト)

## 安全なプログラミングのためのガイドライン

- いかなる場合も入力の源 (source of input) を信用しないでください。 例えばコマンドライン引数、環境変数、設定ファイル、入ってくる TCP/UDP/ICMP パケット、ホスト名の lookup、関数の引数などです。 もし受け取ったデータの長さ、内容が自分の制御下にないなら、 内容をコピーするプログラム、関数は十分に注意しなければなりません。 特に注意しなければならないのは以下のようなことです:

  - 境界のわからないデータによる strcpy() や sprintf() の呼び出し。 長さが分かっている場合には strncpy や snprintf() を使います。 (長さが分からない場合には何らかの境界チェックを実装します。) 要するに、gets() や sprintf() は決して使ってはいけない、ということです、以上。 もし使ったとしたら、邪悪な小人があなたの後ろから忍び寄ることでしょう。

  - もし特定の文字を禁止したユーザの入力を必要とした場合には、 決してそれらの禁止した文字をチェックしてはいけません。 代りに、あなたが許可した文字でのみ構成されているかどうかを チェックします。 基本的には、明示的に許可したもの以外は すべて禁止する、とします。

  - strncpy() と strncat() のマニュアルページを良く読むこと。 これらがどのように働くのか良く理解してください!!! strncpy() が末端の \0 を付け加えないかもしれないのに対して、 strncat() は \0 を付け加えます。

  - strvis() と getenv() の誤用に注意する。 strvis() では、コピー先の文字列を簡単に駄目にしてしまいます。 getenv() はプログラムが予想する長さよりも長い文字列を返すことがあります。 これらの二つの関数は、プログラムへの攻撃に際し鍵となる手法のひとつで、 環境変数に予想外の値を設定しスタックや変数を上書きします。 もしあなたのプログラムが環境変数を読み込むなら、偏執症になってください。 しつこいくらいの偏執症に。

  - open() や stat() を使うときは、毎回自問自答してください: 「これがシンボリックリンクだったらどうなる？」

  - mktemp()、tempnam() などの代りに mkstemp() を使うようにする。 一般的に /tmp で起こる競合に注意することはもちろんのこと、 めったに起こらない状況にも注意を払ってください:
    - ディレクトリを作成する。 これは成功も失敗も有り得る。
    - O_CREAT | O_EXCL でファイルをオープンする
    mkstemp() を使った場合、これらのケースもうまく面倒を見てくれます。 よってすべての一時的なファイルは、競合条件を排除し、 パーミッションが適切かどうかを保証するために mkstemp() を使うべきです。

  - 攻撃者が他の任意のシステムへ/からパケットを送る/受け取ることができる 場合、攻撃者は私たちが受け取るデータを完全に制御できるようになり、 一切のデータは信用できなくなります。

  - 設定ファイルが正しい書式で書かれているとか、適切なユーティリティで出 力されていることを仮定してはいけません。 ユーザが指定する端末名や言語指定文字列など、パス名に使う可能性のあるものでは、 '/' や '../../../' などの文字列が含まれる可能性を考慮する必要があります。 setuid root で動くプログラムの場合には、ユーザにより指定されたパスを 絶対に信用してはいけません。

  - データが格納される方法にセキュリティホール/弱点がないかどうか 探してください。 詮索好きな眼から保護するために、すべての一時ファイルのパーミッション は 600 にするべきです。

  - 特権で動作するプログラムは、ありきたりの問題を grep するだけ ではいけません。 strcpy() やその類似関数の誤用による、バッファオーバーフローを 引き起こす方法は数多く存在するので、 そのようなプログラムではすべての行でオーバーフローの可能性を 探ってください。

  - ある個所で特権を放棄したからといって、それで exploit が なくなるというわけではありません。 攻撃者は、あとで /bin/sh を実行する際に再び特権が得られるように、 スタックに必要なコードを置いておくかもしれません。

- uid で管理しましょう。 できる限り早く特権を放棄しましょう(しかも完全に)。 euid と uid を入れ替えるだけでは十分ではありません。 可能なら setuid() を使いましょう。

- エラーが発生しても設定ファイルを表示しないようにします。 行番号と行内での位置が分かれば十分です。 これはすべてのライブラリ、suid/sgid プログラムに当てはまります。

- 既存のコードのセキュリティ上の問題を発見するために、 コードを見直すときには以下の点に注意します:

  - 自分のセキュリティ上の修正に自信がない場合には、 あらかじめ同意を得ているレビュアーに送って、あなたのコードを 見直してもらってください。 セキュリティ上の修正と銘打って何かを壊してしまうと、 とても恥ずかしい思いをすることになりますので、 良く理解していないコードを commit しないでください。

  - あなたが commit 権限を持っていない場合、 権限を持ったレビュアーは、その変更をチェックする最後の人間となります。 その人がチェックと、最終バージョンをソースツリーに取り入れる作業の 両方を行うことになります。

  - レビュー用に変更点を送る際には、context diff もしくは unified diff を用いるようにします。 この diff は patch(1) に簡単に適用できます。 単純にファイル全体を送るようなことはしないでください。 diff の出力は読みやすく、 (複数の変更が同時に加えられたような場合でも) 手元のソースに簡単に適用できます。 すべての変更は -current ブランチに対して行うようにします。

  - レビュアーに変更点を送付する前に、必ず自分でその変更をテストするよう にします(関連するソースをビルドして実行する、など)。 明らかに壊れているものをレビューしたがる人はいません。 そのようなものは提出者が自分が何をしたかをよく確認していない、 ということをはっきりさせるにすぎません。 (そんなことでは信頼を得られませんね)。 もし特定のバージョンのものが入っているマシンのアカウントが必要なら、 そう尋ねてください。 プロジェクトはそのような目的のためのリソースを用意しています。

  - コミッターへの注意: -current へのパッチを -stable ブランチに 適切に適用することを忘れないでください。

  - あなたのスタイルに合うようにコードを書き直す必要はありません。 そんなことはレビュアーの仕事をより困難にするだけです。 明白な理由がない限りそのようなことはしないでください。

- シグナルハンドラの内部で複雑なことをしているプログラムを 探してください。 ライブラリ内の多くのコードは、このようなことを安全に行えるほど 再入可能ではありません。

- realloc() の使い方には特別な注意を払ってください。 多くの場合、この関数は正しく使われていません。

- 固定サイズのバッファを使うときには、バッファのサイズが変わっても コードの部分が変更されないということが無いように、sizeof() を 使うようにしてください。 たとえば:

              char buf[1024];
              struct foo { ...};
              ...
      BAD:
              xxx(buf, 1024)
              xxx(yyy, sizeof(struct foo))
      GOOD:
              xxx(buf, sizeof(buf))
              xxx(yyy, sizeof(yyy))

  ポインタが指しているもののサイズを知りたいときに、 ポインタの sizeof をとったりしないよう注意してください。

- "char foo[###]" のようなものを見たときには、 すべての foo の使い方が正しいかどうかを調べて、 オーバーフローする可能性がないかどうかをチェックしてください。 オーバーフローが避けられない場合には、 すくなくともバッファを malloc して、スタック上を動き回ることが できないようにしてください。

- ファイル識別子はできる限り早く close してください。 ライブラリルーチンでは、ファイル識別子は常に “使ったら close” するようにしてください。

有用なツールとして its4 の ports が /usr/ports/security/its4/ に あります。 これは自動化された C のコードの検査ツールで、コード中で 潜在的な問題点をハイライト表示します。 これは最初のチェックには 便利ですが盲信して頼りすぎてはいけません。 完全な監査は コード全体を人の目で確かめることが必要です。

確実なプログラミングテクニックとリソースに関する更なる情報は、 リソースセンターの How to Write Secure Code を見てください。

## FreeBSD セキュリティ Tips and Tricks

FreeBSD システム (実際にはどの &unix; システムでも) を セキュアにするにはいくつかのステップがあります:

- 潜在的に危険なソフトウェアを無効にする

  多くのソフトウェアは特定のリソースを使うために、 set-uid として実行可能にすることによって 特権ユーザとして実行されなければなりません。 たとえば UUCP や PPP はシリアルポートを使うために、 sendmail はメールスプールに書き込むために、 bind は特権ポートを使うために、特権ユーザとして実行されます。 UUCP を使わない場合には、 システムにソフトウェアがあっても役にたちません。 また、無効にしている方が得策といえます。 もちろん、これを行うには、将来的にその機能が必要かの見極めと、 必要なものと不要なものを分別する知識が必要です。

  swapinfo のように、セキュリティ上の危険性を高める可能性はあるが、 それほど有用ではないユーティリティに気がつくかと思います。 ('chmod ug-s ファイル名' コマンドを使い) プログラムの set-uid ビットを外しても、root の時は swapinfo を常に 使い続けることができます。 しかし、多くの s ビットを外すために、常時 root になっている、という ことはあまりよいことではありません。 不要なプログラムを削除するだけではなく、提供しないサービスも 取り除きます。 `/etc/inetd.conf` や `/etc/rc.conf` ファイルを編集し、 不要なサービスをすべて停止することで取り除くことができます。

- セキュリティ上のバグがあるソフトウェアを修正するには (または、クラッカーの一歩先を行くには)

  まずは、様々な FreeBSD Security メーリングリスト を購読して下さい。バグの最新情報や修正を入手することができます。 修正は、すぐに当てるようにして下さい。

- バックアップ - セキュリティ侵害が起こった場合は、 システムを修復して下さい。

  常時バックアップを取り、書き換えられていないことが確実な OS (例として、CD-Rom) を準備しておきましょう。 攻撃者によって変造されたり書き換えられたデータがバックアップに 含まないようにしてください。

- システムの状態を監視するソフトウェアのインストール

  (packages や ports にある) tcp wrappers や tripwire のようなプログラムを 用いて、システムを監視することができます。 このようなプログラムは、 侵入者を検知するのに役立ちます。また、毎日 root アカウントへ送られて くる /etc/security スクリプトの出力に目を通すようにして下さい。

- システムに携わる人の育成

  ユーザーは、自分が何をしているのか を理解しなくてはいけません。 自分のパスワードを他人に渡したり、簡単に推測できるパスワード の使用を避けることを教えます。システム/ネットワークの セキュリティは、ユーザー自身の手の中にあることを理解すれば いいのです。

システムのセキュリティを強化する方法の tips の応用編に ついては、以下の FreeBSD Security How-To サイトをご利用下さい。 http://www.FreeBSD.org/~jkb/howto.html

セキュリティとは、継続です。 セキュリティに関する、最新の開発状況を常に把握するようにしてください。

## セキュリティ上の問題を見つけてしまった時にすべきこと:

- セキュリティ侵害のレベルを決める
  攻撃者はどのような特権を得たのか? root 特権を得たのか、それともユー ザーレベルのアクセス権を得ただけなのか?
- システム (カーネルや userland) の状態が変更されていないか判断する
  どのソフトウェアが変更されたのか? 新しいカーネルはインストール されたのか? (telnetd、login のような) システムバイナリは編集されたのか? OS にたいして変更された疑いがある場合は、安全なメディアから OS の 再インストールを行います。
- 不正侵入の手口を見つける
  よく知られているセキュリティバグを通じて侵入はなされたのか? そうであれば、正しいパッチを当てて下さい。 設定ミスによって侵入がなされたのか? 侵入は新しいバグによるものなのか? もしそれが新しいバグによるものと思われる場合、 FreeBSD Security Officer までご連絡ください。
- セキュリティホールを修正する
  問題を解決するために、新しいソフトウェアをインストールするか、 古いソフトウェアにパッチを当てます。危険にさらされたアカウント全てを 無効にします。
- その他の情報源
  CERTにも、 システムに侵入された際に取るべき手順について 詳細が 載っています。

## その他の関連するセキュリティ情報

- The COAST archiveには、セキュリティに関する豊富なコレクション があります。
- CERIAS (Center for Education and Research in Information Assurance and Security) は、セキュリティ情報を探す際に最初に目を通すとよいでしょう。 役立つセキュリティリンクが多数あります。 あなたがセキュリティについて知りたいと思っていることすべてが ……いや、それ以上のことが載っています。
- http://www.cert.orgや http://www.auscert.org.au のような様々なCERTチーム
- Bugtraqや Firewall Wizardsのようなメーリングリスト

&footer;