少し前に、apache2プロセスを効果的に分離できるようにすることを自分で決めました。 システムユーザーに代わって各リクエストを処理できるようになりました。 今日、このソリューションを共有したいと思います。
これが私たちが話していることです:
<VirtualHost *:80> ServerName host1.example.com ServerAdmin webmaster1@example.com ServerUserGroup user1 group1 DocumentRoot /var/www/host1 </VirtualHost> <VirtualHost *:80> ServerName host2.example.com ServerAdmin webmaster2@example.com ServerUserGroup user2 group2 DocumentRoot /var/www/host2 </VirtualHost>
同時に、仮想ホストのルートディレクトリには、適切なユーザーのみがアクセスできます。
これらは、マルチスレッド、ルートからのプロセスの開始などに関するタンバリンを使用した定期的なダンスではありません。 主なアイデアは、プロセスがリクエストを処理するために必要な権利を独自に決定し、これらの権利を自分自身に取得して処理し、メインのApacheユーザーの権利を再び返すということです。
同時に、起動時の構成に記述されているユーザーのリストに最初にapacheを制限したかったため、リクエストの処理中に、プロセスがスイッチングメカニズムと適切な他の人の権利を「クラック」することは非常に困難(またはほとんど不可能)でした。
私にとっての主なアプリケーションはlinuxですが、そのコアにある既存のメカニズムは、ユーザーの環境でのみ私のアイデアを実装するには不十分です。 したがって、ソリューションは、カーネルモジュールとApacheモジュールの2つの部分で構成されます。 カーネルモジュールはデバイス/ dev / ugidctlを提供します。これにより、ioctl(2)システムコールを使用して、特権モードでプロセスの許可ユーザーのリストを管理し、実際には非特権モードでユーザーを切り替えることができます。 Apacheの一部では、別のメカニズムがこのメカニズムを使用しており、この機能をすべて実装しています。
操作アルゴリズムはもう少し詳細です。
ルートApacheプロセス:
- デバイス/ dev / ugidctlを開きます
- 構成ファイルを読み取るプロセスで、必要なユーザーのリストを収集します
- このリストをugidctlにロードします
- カーネルからランダムキーを取得してユーザーを切り替えます
子プロセス:
- プライマリユーザーの特権をリセットします
- リクエストを待って、どの権利を提供する必要があるかを調べます
- 初期化中に取得したキーを使用して、ユーザーを切り替えます
- リクエストを処理します
- キーを使用して、メインユーザーの権限を返します
- 後藤2
子プロセスがハッキングされた場合、スイッチキーが受信された場合でも、ユーザーのリストに対する制限により、攻撃者はシステムの特権を増やすことができません。 最大で、任意の仮想ホストの任意のルートディレクトリにアクセスできます。これは、MPM preforkを使用した変更されていないApacheがすべての要求を処理するのと同じです。 同時に、子プロセスのメモリでキーを見つける複雑さは、mod_sslモジュールのメモリで秘密キーを見つける複雑さに似ています。
当然、私の考えでは、このモジュールはMPMプリフォークでのみ動作するように設計されています。 また、可能であれば、Apacheプロセス内でリクエストを処理する際にマルチスレッドを回避する価値があります-私のモジュールは、プロセスのメインスレッドのみの権限を切り替えます。
こちらからダウンロードできます:
カーネルモジュールApacheモジュールCentOS 7でのアセンブリの簡単な説明:
アセンブリに必要なパッケージを配置します。
[root@el7 ~]
ソースをダウンロードして解凍します。
[root@el7 ~]
カーネルモジュールをビルドしてロードします。
[root@el7 ~]
apache2モジュールを収集してロードします。
[root@el7 ~]
または、
el6 (RHEL 6u2 + / CentOS 6.2 +、x86_64のみ)および
el7 (RHEL 7 / CentOS 7)の既製ビルドを使用できます。 複数のel6サーバーで、このソリューションは1年以上にわたって確実に機能しています。