この講演 特権分離について、Theo de Raadtは、OpenBSDのntpdには、DNSサーバーのクエリを担当するDNSプロセスであるsettimeofday()
を呼び出すマスタープロセスと、NTP UDPをNTPサーバーに話す責任があるプロトコルプロセス。彼はDNSプロセスについて次のように言っています:
もう1つは、別個のDNSサービサープロセスです。DNSを実行できるようにしたかったのですが、DNSライブラリにバグがあることがあるため、マスタープロセスに実行させたくありませんでした。また、インターネットスピーカーがそれをするのは...それは...それは意味がなかったからです。
誓約が存在しないと仮定しましょう(私が理解しているように、この設計はそれよりも前のものです)。明らかに、この設計は、ネットワークに面したサービスが危険にさらされているかのように、それ自体ではかなり無意味です。攻撃者はシステムにルートを持っています。したがって、マスタープロセスは両方のサブプロセスをフォークし、特権をnobody
などに即座にドロップします。そうすれば、DNSライブラリまたはNTPコード)のいずれかにセキュリティバグがある場合、攻撃者はシステムファイルやホームディレクトリなどへの書き込みアクセス権を持ちません。
それはすべて私には理にかなっています。しかし、私が理解していないのは、DNSプロセスとUDPプロセスを分離することがなぜ役立つのかということです。どちらが危険にさらされているかは関係ありません。攻撃者はどちらの方法でも同じユーザーとして実行されています。 DNSプロセスをたとえばに置くことができます。 nobody2
ユーザーですが、それでもnobody2
はnobody
と同じように非特権になります。
誓約により、利益は明らかです。 DNSプロセスは、DNSクエリのみを作成することを約束できます。これは、攻撃者にとってはまったく役に立たないものです。ただし、この設計は誓約の前に導入されたため、誓約は要因ではないと想定しています。
私が見逃している3プロセスのntpd設計にセキュリティ上の利点はありますか?それとも、セキュリティとは関係のない設計上の決定でしたか(おそらく将来の誓約のようなシステムの可能性を考慮して)?
(私はOpenBSD ntpdの設計について何も知らないことに注意してください。私は、プロセスの分離に関する一般的な質問に答えているだけです。)
あなたの引用から、UDPプロセスとDNSプロセスの分離は、セキュリティ上の懸念ではなく、アーキテクチャ上の懸念によって動機付けられたと私は思います。「なぜなら...それは...それは意味がなかったからです」。 UDPプロセスとDNSプロセスは、まったく異なるイベントに反応します。それらが同じプロセスにある場合、それらは別々のスレッドを使用します(明示的に、または暗黙的にselect
呼び出しの周りのイベントループを使用して)。 UDPプロセスとDNSプロセスは独立して動作するため、同じプロセスに配置すると設計が複雑になり、デフォルトでは別々のプロセスになります。
NTPサーバーが単一のプロセスとして設計されていた場合、設計はサブシステムのさまざまな相互作用パターンに対応する必要がありました。その場合、スレッドは理にかなっています。しかし、とにかくプロセスの分離がある場合は、次に、関連のないサブシステムを同じプロセスにグループ化すると、設計が複雑になります。
それでも、個別のプロセスを持つことでセキュリティ上のメリットが得られる可能性があります。 1つの利点は、すべてのエクスプロイトが攻撃者に任意のコードの実行を許可するわけではないことです。一部のエクスプロイトは、ローカライズされたデータの破損、または一部の秘密データの公開のみを許可するか、クラッシュを引き起こす可能性がありますが、常に制御された方法で行われます(たとえば、nullポインターの逆参照のみで、任意のポインターの逆参照はありません)。脆弱性によって任意のコードが実行される場合でも、エクスプロイトの作成が複雑になることがあります。エクスプロイトをより複雑にすると、防御側はバグを修正して更新を展開する時間を節約できます。
脆弱性によりプロセス内で任意のコードが実行される可能性がある場合でも、OSレベルのメカニズムによってプロセスが制限される可能性があります。 pledge
の前でさえ、OpenBSDはptrace
に対するOS全体の制限を許可していました。これは、実稼働サーバーで有効にする必要があります。 nobody
として実行されているプロセスは、他のプロセスを追跡できない場合、他のプロセスに直接害を及ぼすことはできません。攻撃者はいくつかの間接的な手段を見つける必要があり、DoSの機会はたくさんありますが、DNSの違反は、攻撃者が偽のNTPトラフィックを生成することを許可しません(そうではありません)ポートをバインドできます)。
誓約が存在しないと仮定しましょう(私が理解しているように、この設計はそれよりも前のものです)。明らかに、この設計は、ネットワークに面したサービスが危険にさらされているかのように、それ自体ではかなり無意味です。攻撃者はシステムにルートを持っています。
pledge
がなくても、デザインは無意味ではありません。ネットワークに直接接続されたサービスが侵害された場合、攻撃者はシステム上にroot
を持っていませんnot-それがポイントです。
マスタープロセスはNTPD子プロセスを生成し、UDPソケットをNTPサーバー(ポート123)として開き、子プロセスは特権を削除します。
この場合、子プロセスは、実際の有効な保存済みユーザーIDを__ntp
_ユーザーのIDに変更することを意味します。
マスタープロセスはroot
のままなので、必要に応じてadjtime(2)
システムコールを呼び出すことができます。
ネットワークに面したプロセスはもはやroot
ではなく、あなたが言及したリスクを正確に排除します。 root
であるプロセスは、adjtime(2)
の呼び出しのみを許可するために、(IMSGシステムを介して)厳密に制御されたインターフェースを備えています。したがって、子プロセスを侵害する攻撃者は、システムに対して__ntp
_特権を持っています。また、ホスト上でのみadjtime(2)
呼び出しを発行できます。完全なroot
妥協よりも機能を低くする必要があります。
pledge(2)
の前の初期バージョンの設計については、 OpenBSDのセキュリティ制御に関する講演のこのスライド を参照してください。