mod_process_security – Apache上でスレッド単位で権限分離を行うファイルのアクセス制御アーキテクチャ(前半編)

「スレッド単位で権限分離を行うWebサーバ上のアクセス制御アーキテクチャ」として、3月15日16日に開催されたIA/IOT/SITE/ISMS合同研究会で発表してきた。概ね、好評だったように思う。ただ、やらないといけないことはいくつかあるので、そこはこれから大学で適宜やっていこうと思う。

まずは、この論文の概要としては、

    • 大規模Webサーバ上で大多数のユーザー(仮想ホスト)を一つのサーバで処理するようなマルチテナント環境において、ユーザー間のセキュリティを担保するためのアクセス制御を行う技術

である。(これまではsuEXECが使われていた)

これは、Webサービスが高度化していく時代において、低価格化がより望まれてきており、以前に増してマルチテナントで少ないサーバで多くのユーザー領域(仮想ホスト等)を共有して、かつ、セキュアな仕組みにしておきたいという背景がある。

実際のユースケースとしては、以下のような状況で使えるように思う。

    • モジュール版PHPやPerl等(DSO版)を安全かつ高速に仮想ホスト環境で実行可能
    • CGIやDSOのアクセス制御を統一的に扱うことが可能(suEXECとかいらない)
    • FastCGIももちろんアクセス制御された状態で動作可能

結局何ができるかというと、CGIやDSO及びFastCGI等の実行方式に関わらず、仮想ホスト環境においてsuEXECのような動的コンテンツをファイルのユーザー権限で実行することが可能であるということ。さらに、DSOを実行させた場合でも性能劣化が非常に少なくなっている。

では、具体的にどういう処理をしているのかを簡単に説明する。(詳しくは論文で

 

実行方式について

 

まずは、CGI実行方式とDSO実行方式は以下の図のような差がある。

CGIは実行時に、シェバン行からインタプリタのバイナリを探して、fork()してexecve()するため、実行毎に新規でプロセスの生成及び実行後のプロセス破棄が生じるため、性能が低い。一方で、DSOはインタプリタをサーバプロセスに組み込んでおく事で、サーバプロセスが直接プログラムを実行できる仕組みをとっている。

 

従来のCGIのアクセス制御について

 

では、CGIにアクセス制御、例えばsuEXECを導入した場合は、どのようにプログラムをファイルのユーザー権限で動作させているのか。それが以下の図となる。

このように、CGIを実行する際にsuEXECのラッパープログラムを介して実行することで、一旦setuid-rootなラッパープログラムによってroot権限のプロセスになり、そしてプロセス自分自身をファイルのユーザー権限(この場合はuser1)に変更してプログラムを実行する。これによって、ユーザー権限で実行され、仮想ホストのマルチテナント環境でも、仮想ホスト間でのアクセスを制御しセキュリティを担保している。

しかし、CGIは遅い。マルチテナント環境であってもDSOで実行したい。現状、DSOのアクセス制御としてはmod_ruid2があり、それを適応するとどうなるか。

 

従来のDSOのアクセス制御とその問題について

 

まず、サーバプロセスにLinuxCapabilityを与えておく。これは、rootの権限を細分化したもので、今回の場合は一般ユーザーであっても権限変更可能な特権を子サーバプロセスに与える。これによって、リクエストのあったプログラムの権限に子サーバプロセス自体の権限を変更し、プログラムを実行する。さらに、子サーバプロセスの生成・破棄は非常に処理に時間がかかるので、プロセスを再利用するために、再度元のapacheユーザー権限にプロセスの権限を変更して、次のリクエストを待ち受ける。これが、mod_ruid2のアーキテクチャである。

しかし、これは一つ大きな脆弱性を抱えている。子サーバプロセスに権限変更の特権を保持させていることは、index.php経由で権限変更が可能なことを意味する。これでは、プログラム経由で自由に権限変更をして、悪い事が沢山できてしまう。

そこでこれを防ぐために、以下のような実装変更を行う。

子サーバプロセスの権限をプログラムの権限に変更した段階で、きちんと権限変更の特権であるCapabilityを破棄しておく。これによって、プログラム経由で権限変更できなくなる。しかし、同時に元の子サーバプロセスの権限であるapacheに変更できなくなるので、子サーバプロセスを破棄しなければならない。このように、結局子サーバプロセスの生成・破棄が生じて、大幅に処理が低下する。せっかく、処理を早くするためにDSO実行方式を使っているのに、アクセス制御を組み込むことで、性能が大幅に劣化してしまっては意味がない。実験してみると、CGIよりも性能が低い程度にまで落ち込む

では、どうするか。

これらを解決するためにmod_process_securityが生まれたのである。

意外と多くなってしまったので、次回に続く・・・

書きました: mod_process_security – Apache上でスレッド単位で権限分離を行うファイルのアクセス制御アーキテクチャ(後半編)