第24章 ハット変更を利用した Web アプリケーションのプロファイル作成

目次

24.1. Apache のハット変更
24.2. mod_apparmor 向けの Apache 設定

AppArmor® のプロファイルは個別のプログラムインスタンスやプロセスに対する セキュリティポリシーを表現するためのものです。これは実行可能なプログラムに 対して適用されるものですが、プログラムの一部分で他の部分とは異なるアクセス 許可を必要とする場合、プログラムに対して ハット変更 を適用 して、メインプログラムのアクセス許可とは異なるセキュリティコンテキストを 使用するように設定することができます。これを ハットサブプロファイル と呼びます。

ハット変更を利用すると、 AppArmor のプロファイル内からプログラムに対する ハット を変更することができます。これはプロセス単位の ものよりも、詳しくセキュリティレベルを設定することができます。この機能を 利用するには、各アプリケーションが ハット変更に対応した 作りになっている必要があります。これは AppArmor モジュールに対して、セキュリティ 領域を切り替えるように要求する機能のことを指します。ハット変更に対応した アプリケーションには、たとえば Apache Web サーバや Tomcat などがあります。

プロファイルには任意の数のサブプロファイルを設定することができますが、 2 段階しか存在しないことに注意する必要があります。つまり、サブプロファイルに 対するサブプロファイルは設定することができません。また、サブプロファイルは 個別のプロファイルとして記述するもので、プロファイル名に続いて ^ を付け、続けてサブプロファイル名を記述します。 なお、サブプロファイルは親のプロファイルと同じファイルに保存しなければ なりません。

また、ハットを利用する場合のセキュリティは、完全な (ハットではない) プロファイルに比べるとかなり弱いものであることにも注意する必要があります。 例を挙げると、もしも攻撃者がプログラムに対する完全なバグを見つけた場合、 プロファイル内に含まれるハットの適用から逃げることができてしまいます。 これは、ハットのセキュリティはそのプロセスが処理する機密鍵によって決定 される仕組みであり、ハット内で動作するコードからは鍵へのアクセス方法が 用意されないためです。そのためハット変更は、言語のインタプリタ (Perl, PHP, Java など) を含むアプリケーションサーバで使用するのがもっとも 便利です。このようなアプリケーションサーバでは、親プロセスのメモリに 直接アクセスできないような形でコードが分離されるため、ハットを利用する には都合が良いためです。

以降では、 mod_perl と mod_php の各 Web サーバコンポーネントを含む Apache で、 ハット変更機能を利用した場合について説明を行なっています。 mod_apparmor に 似たアプリケーションモジュールを利用することで、他のアプリケーションサーバ でも同様のアプローチでハット変更を実施できます。詳しくは 24.2.2項 「Location ディレクティブと Directory ディレクティブ」 をお読みください。

[Note]さらなる情報

詳しくは change_hat のマニュアルページをお読みください。

24.1. Apache のハット変更

AppArmor では、 Apache 向けのモジュールとして mod_apparmor (apache2-mod_apparmor パッケージ) が提供されています。 このモジュールは Apache Web サーバをハット変更に対応させるためのものです。 Apache とともにインストールしておいてください。

Apache がハット変更に対応していれば、受信した各 URI 要求に対して、下記の 順序でカスタマイズ済みの AppArmor セキュリティプロファイルを確認します。

  • URI 固有のハット。たとえば ^phpsysinfo/templates/classic/images/bar_left.gif など。

  • DEFAULT_URI

  • HANDLING_UNTRUSTED_INPUT

[Note]Apache の設定

apache2-mod_apparmor をインストール済みであれば、下記のコマンドを実行することで Apache 内にモジュールを読み込むことができます:

a2enmod apparmor

24.1.1. ハット変更に対応したアプリケーションの管理

AppArmor の大部分のツールと同様に、ハット変更に対しても YaST とコマンド ラインツールの 2 種類の方法で管理を行なうことができます。ハット変更に 対応したアプリケーションをコマンドラインから管理すると、非常に柔軟に 対応することができますが、作業は少し複雑になります。いずれの方法でも アプリケーションのハットを管理できるほか、プロファイル項目への反映も 行なうことができます。

下記に示す手順は、 YaST を利用して Apache のプロファイルにハットを 追加するまでのデモンストレーションです。 AppArmor プロファイルウイザード では、 AppArmor のプロファイル作成ユーティリティが個別の URI 要求に対して、 新しいハットを作成するかどうかを尋ねます。新しいハットを作成するように 選択すると、それぞれの URI に対して個別のプロファイルを作成することが できます。これにより、要求ごとにより厳しいルールを作成することができます。

処理された URI が特に意味のないものであったり、特にセキュリティリスクの 考えられるものではなかったりした場合は、既定のハット (つまり既定の セキュリティプロファイル) で対象の URI を処理するようにするため、 既定のハットの使用 を選択しておくことができます。

今回の例では、 phpsysinfo という URI とそれに続く アクセスに対して、新しいハットを作成しています。プロファイル作成ユーティリティ を使用することで、新しいハットに追加すべきものを代理で設定させることも できます。結果として生成されるハットは、 Apache Web サーバで phpsysinfo という URI が処理された際、対象のサーバ で行なわれる全ての処理に対して適用される、セキュリティの厳しいコンテナ になります。

URI は phpsysinfo (詳しくは http://phpsysinfo.sourceforge.net をお読みください) というアプリケーションを実行します。 phpsysinfo パッケージは新規インストールの openSUSE と AppArmor に対してインストールされたものとし、 /srv/www/htdocs/phpsysinfo ディレクトリに配置されている ものと仮定します。

  1. phpsysinfo をインストール すれば Apache プロファイル内にハットを追加する準備は完了です。 AppArmor の GUI から AppArmor プロファイルウイザード を選択してください。

  2. プロファイルを作成するアプリケーション では、 httpd2-prefork と入力します。

  3. プロファイルの作成 を押します。

    AppArmor プロファイルウイザード
  4. 端末ウインドウで rcapache2 restart と入力し、 Apache を再起動します。

    また、この時点でプロファイルを作成している全てのプログラムを再起動します。

  5. Web ブラウザのウインドウで http://localhost/phpsysinfo/ と入力します。ブラウザのウインドウにはネットワークの使用率とシステム情報が 表示されます。

    [Note]データのキャッシュ

    リクエストがサーバ側で間違いなく処理され、キャッシュされたデータを閲覧して しまうようなことをなくすため、お使いのブラウザではページの更新を行なって ください。これを行なうには、ブラウザの 更新 ボタンを 押します。

  6. システムログをスキャンして AppArmor イベントを検出 を押します。 AppArmor は aa-logprof ツールを起動し、 上記の手順で学習した情報を読み出します。これにより、プロファイルへの 設定について質問が表示されます。

  7. aa-logprof では、まず phpsysinfo の URI にアクセスされたことを検知し、 要求されたハットの追加既定のハットの使用 のどちらかを選択するように 促します。ここでは 要求されたハットの追加 を選択して ください。

  8. 続いて 許可 を押します。

    上記で 要求されたハットの追加 を選択すると、プロファイル 内に新しいハットを作成し、続く質問の回答は、このアプリケーションに対する 既定のハットではなく、新しく作成したハットに対して反映するようになります。

    次の画面では、 AppArmor はスクリプトが実行した外部プログラムを表示します。 ここでは phpsysinfo のハット (継承 を選択した場合) で 制限するか、もしくは個別のプロファイルで制限する (プロファイル を選択した場合) かを選択することができるほか、セキュリティプロファイルを 一切適用せずに無制限の動作を許す (無制限) 選択を 行なうことができます。 プロファイル の選択肢を 選択した場合は、そのプログラムに対するプロファイルが存在しない場合、 新規に作成することになります。

    [Note]セキュリティ面の考慮事項

    無制限 を選択すると、それは明示的なセキュリティ ホールを作成することになってしまいます。注意してお使いください。

    1. /bin/bash のパスに対しては 継承 を選択します。これにより /bin/bash (Apache からアクセスされるもの) は phpsysinfo のハットプロファイルが適用され、必要な許可が行なわれる ようになります。

    2. 続いて 許可 を押します。

  9. あとの質問は新しいハットを生成する旨の問い合わせと、プロファイルやハットに 追加する項目の問い合わせです。プロファイルに対する項目の追加については、 22.1項 「ウイザードを使用したプロファイルの追加」 で詳細を説明しています。

    全てのプロファイル生成時の質問に回答したら、 完了 を押すと設定を保存し、ウイザードを終了することができます。

下記は phpsysinfo のハット作成例です。

例24.1 phpsysinfo のハット例

/usr/sbin/httpd2-prefork {
  ...
  ^phpsysinfo {
    #include <abstractions/bash>
    #include <abstractions/nameservice>

    /bin/basename                        ixr,
    /bin/bash                            ixr,
    /bin/df                              ixr,
    /bin/grep                            ixr,
    /bin/mount                           Ux,
    /bin/sed                             ixr,
    /dev/bus/usb/                        r,
    /dev/bus/usb/**                      r,
    /dev/null                            w,
    /dev/tty                             rw,
    /dev/urandom                         r,
    /etc/SuSE-release                    r,
    /etc/ld.so.cache                     r,
    /etc/lsb-release                     r,
    /etc/lsb-release.d/                  r,
    /lib/ld-2.6.1.so                     ixr,
    /proc/**                             r,
    /sbin/lspci                          ixr,
    /srv/www/htdocs/phpsysinfo/**        r,
    /sys/bus/pci/**                      r,
    /sys/bus/scsi/devices/               r,
    /sys/devices/**                      r,
    /usr/bin/cut                         ixr,
    /usr/bin/getopt                      ixr,
    /usr/bin/head                        ixr,
    /usr/bin/lsb_release                 ixr,
    /usr/bin/lsscsi                      ixr,
    /usr/bin/tr                          ixr,
    /usr/bin/who                         ixr,
    /usr/lib/lib*so*                     mr,
    /usr/lib/locale/**                   r,
    /usr/sbin/lsusb                      ixr,
    /usr/share/locale/**                 r,
    /usr/share/pci.ids                   r,
    /usr/share/usb.ids                   r,
    /var/log/apache2/access_log          w,
    /var/run/utmp                        kr,
   }
}

[Note]ハットと親プロファイルの関係

プロファイル ^phpsysinfo は、親プロファイル である httpd2-prefork のプロセスが実行中で ある場合にのみ有効となります。

24.1.2. ハットの追加とハットへの項目追加

プロファイルの編集 を使用した場合 (手順については 22.3項 「プロファイルの編集」 を 参照してください) や 手作業でプロファイルを追加 (手順については 22.2項 「手作業でのプロファイル追加」 を参照してください) を使用した場合は、作業中の AppArmor プロファイルに 対してハット (サブプロファイル) を追加することができます。 下記のような AppArmor プロファイルダイアログ から、ハット 変更のサブプロファイルを追加してください。

AppArmor プロファイルダイアログ
  1. AppArmor プロファイルダイアログ のウインドウから、 項目の追加 を押したあと ハット を選択します。すると、 ハット名の入力 ダイアログが 表示されます:

    ハット名の入力
  2. AppArmor のプロファイルに追加するハット名を入力します。名前はハット内で 許可セットを受け取る際の URI を指定します。

  3. ハットの作成 を押します。すると AppArmor プロファイルダイアログ の画面に戻ります。

  4. 新しいハットを追加したら、 完了 を押せば終了です。

[Note]さらなる情報

AppArmor プロファイルの例について、詳しくは 例24.1「phpsysinfo のハット例」 をお読みください。

24.2. mod_apparmor 向けの Apache 設定

Apache はテキスト形式の設定ファイルに対してディレクティブを配置することで 設定を行ないます。主となる設定ファイルは通常、 httpd.conf です。この設定ファイル名は Apache をコンパイルする際、場所を指定することが できます。また Apache の動作を変更するためのディレクティブは、これらの設定 ファイル内のいずれかに配置します。主となる設定ファイルに対して変更を行なった 場合は、 APache を起動または再起動することで設定が認識されるようになります。

24.2.1. 仮想ホストのディレクティブ

仮想ホストのディレクティブでは、パス名情報とそれに続く実際のファイル名に ついて、これを受け入れるか拒否するかを制御します。 仮想ホストのディレクティブ に関する Apache のドキュメンテーションは、 http://httpd.apache.org/docs/2.2/mod/core.html#virtualhost をお読みください。

ハット変更関係の設定キーワードは AADefaultHatName です。これは AAHatName に似た仕組みで、たとえば AADefaultHatName My_Funky_Default_Hat のような形式で 既定のハット名を指定します。

上記の設定オプションはサーバディレクティブ内に書かれるべきもので、他の オプションの外側でも使用することができます。これにより、既定のサーバに 対するハット設定を行なうことができます。仮想ホストは Apache の内部で 別々の サーバ として扱われるため、既定のサーバに対する 既定のハット名のほか、必要であれば各仮想ホストに対する既定のハット名を 設定することもできます。

リクエストが到達すると、 mod_apparmor は下記の手順で 適用すべきハットを判断します。

  1. Location や Directory ディレクティブ内で AAHatName キーワードが指定されていれば、そのハット

  2. URI パス全体に対して命名されているハット

  3. AADefaultHatName キーワードで指定されている 既定のサーバのハット。

  4. DEFAULT_URI (何も指定されていない場合は となる Apache のハット)

24.2.2. Location ディレクティブと Directory ディレクティブ

設定ファイル内の Location と Directory の各ディレクティブでは、ハット名を 指定することができ、そこから対応するセキュリティ用のハットを選択すること ができます。 Apache の場合、 Location や Directory のディレクティブに 関する説明は http://httpd.apache.org/docs/2.2/sections.html に書かれています。

下記のような Location ディレクティブを指定すると、 mod_apparmor に対して指定のハットを使用するように指示 することができます:

<Location /foo/> AAHatName MY_HAT_NAME </Location>
   

上記の例では、 /foo/ で始まる全ての URI (/foo/, /foo/bar, /foo/cgi/path/blah_blah/blah など) に対して、 MY_HAT_NAME というハットを適用するように指示することに なります。

Directory ディレクティブでも Location ディレクティブと同様に動作します。 ただし下記の例のとおり、 Directory ディレクティブではファイルシステム 内のパスを参照する点が異なります:

<Directory "/srv/www/www.immunix.com/docs"> 
  # 最後のスラッシュが無いことに注意
  AAHatName immunix.com 
</Directory>

例:  下記の例では、 phpsysinfo というプログラムを例にして Location ディレクティブを使用しています。 phpsysinfo のソースコードは、 http://phpsysinfo.sourceforge.net からダウンロードできます。

  1. ソースコードをダウンロードしたら、 /srv/www/htdocs/phpsysinfo ディレクトリ内に インストールしてください。

  2. /etc/apache2/conf.d/phpsysinfo.conf ファイルを 作成し、下記のテキストを入力します:

    <Location "/phpsysinfo"> 
      AAHatName phpsysinfo
    </Location>

    あとは下記のようなハットを設定すれば、 phpsysinfo に対して 動作するようになります:

    /usr/sbin/httpd2-prefork {
      ...
      ^phpsysinfo {
        #include <abstractions/bash>
        #include <abstractions/nameservice>
    
        /bin/basename                        ixr,
        /bin/bash                            ixr,
        /bin/df                              ixr,
        /bin/grep                            ixr,
        /bin/mount                           Ux,
        /bin/sed                             ixr,
        /dev/bus/usb/                        r,
        /dev/bus/usb/**                      r,
        /dev/null                            w,
        /dev/tty                             rw,
        /dev/urandom                         r,
        /etc/SuSE-release                    r,
        /etc/ld.so.cache                     r,
        /etc/lsb-release                     r,
        /etc/lsb-release.d/                  r,
        /lib/ld-2.6.1.so                     ixr,
        /proc/**                             r,
        /sbin/lspci                          ixr,
        /srv/www/htdocs/phpsysinfo/**        r,
        /sys/bus/pci/**                      r,
        /sys/bus/scsi/devices/               r,
        /sys/devices/**                      r,
        /usr/bin/cut                         ixr,
        /usr/bin/getopt                      ixr,
        /usr/bin/head                        ixr,
        /usr/bin/lsb_release                 ixr,
        /usr/bin/lsscsi                      ixr,
        /usr/bin/tr                          ixr,
        /usr/bin/who                         ixr,
        /usr/lib/lib*so*                     mr,
        /usr/lib/locale/**                   r,
        /usr/sbin/lsusb                      ixr,
        /usr/share/locale/**                 r,
        /usr/share/pci.ids                   r,
        /usr/share/usb.ids                   r,
        /var/log/apache2/access_log          w,
        /var/run/utmp                        kr,
       }
    }
         
  3. root で端末ウインドウを開き、 rcapparmor restart と入力して AppArmor プロファイルの再読み込みを 行ないます。

  4. 同じく root で端末ウインドウから、 rcapache2 restart と入力し、 Apache を再起動します。

  5. Web ブラウザを開いて http://ホスト名/phpsysinfo/ と入力し、 phpsysinfo が配信するシステム情報を表示させます。

  6. 設定エラーについては /var/log/audit/audit.log ファイルに書かれるほか、 dmesg で拒否された情報を 確認することができます。


openSUSE セキュリティガイド 13.1