AppArmor® のプロファイルは本来、個別のプログラムやプロセスに対するセキュリティポリシーを表すものです。つまり、実行可能なプログラムに対してプロファイルを割り当てることになります。ところが、プログラムの一部では他の部分とは異なるアクセス許可が必要となることもあります。このような場合は、 「チェンジハット」 の機能を利用して、メインのプログラムに対して適用されているものとは異なるセキュリティコンテキストを適用するように設定します。このような 「異なるセキュリティコンテキスト」 のことを、 ハット や サブプロファイル などと呼び、 これを変更する行為を チェンジハット と呼びます。
チェンジハット機能は、 AppArmor のプロファイルの中からプログラムに対して ハット を変更する機能を提供します。これにより、プロセスごとの制限よりもずっと精密なセキュリティを設定することができます。また、この機能はそれぞれのアプリケーションが 「チェンジハット対応」 として作られている必要があります。これはアプリケーションの実行時、特定のタイミングで AppArmor のモジュールに要求を送信して、ドメインを切り替える処理のことを指します。チェンジハット対応のアプリケーションの例としては、 Apache Web サーバなどがあります。
1 つのプロファイルに対しては、任意の数のサブプロファイルを作成することができますが、 2 段階までしか対応していないことに注意する必要があります。つまり、サブプロファイルから更に子となるプロファイルを作成することはできません。また、サブプロファイルは個別のプロファイルとして作成する必要があります。サブプロファイルの名前は、元々のプロファイル名の末尾に ^
を付け、その後ろにサブプロファイルそのものの名前を指定します。
サブプロファイルは親のプロファイル内に含まれていてもかまいませんし、個別のファイルとして存在していてもかまいません。特に多数のハットを必要とするようなサイトであれば、後者のほうがお勧めです。これにより、ハット単位でポリシーキャッシュ機能が働くため、サブプロファイル側の変更を行った場合に処理を減らすことができるためです。逆にすべてのハットが親のプロファイル内に含まれている場合、親プロファイル全体を再コンパイルしなければならなくなります。
ハットとして使用する予定の外部サブプロファイルがある場合、そのサブプロファイルの冒頭には hat
もしくは ^
文字で始まらなければなりません。
下記の 2 つのサブプロファイルは、いずれもハットとして使用 できない ものです:
/foo//bar { }
"\n \n"
profile /foo//bar { }
逆に、下記の 2 つはいずれもハットとして扱われます:
^/foo//bar { }
"\n \n"
hat /foo//bar { } # (vim では、この書式はハイライト表示されません)
なお、ハットを使用する場合のセキュリティは、完全なプロファイルを使用する場合に比べると、比較的弱くなることに注意してください。プログラム内に特定の種類のバグが存在した場合、攻撃者はプロファイル内に含まれるハットに退避することができてしまいます。これは、ハットのセキュリティがプロセス側で保持される機密鍵のみによって成り立っているためで、ハット側内のコードからは鍵に対するアクセスを許可してはならないことによるものです。そのためチェンジハット機能は、プロセス内に含まれるメモリに対して直接的にアクセスする手段のない、インタプリタ型の言語 (Perl, PHP, Java など) で作成されたアプリケーションサーバに対して、最も便利な仕組みとなっています。
本章の以下の項目では、 Apache でのチェンジハット機能の使用方法について説明しています。この Apache では mod_perl
および mod_php
を利用して、 Web サーバコンポーネントを動作させているものとします。同様のアプローチで、 Apache における mod_apparmor
と同様 (詳しくは 34.1.2項 「Location ディレクティブと Directory ディレクティブ」 で説明しています) に、その他のアプリケーションサーバでもチェンジハット機能を利用することができます。
更に詳しい情報をご希望の場合は、 change_hat
のマニュアルページをお読みください。
mod_apparmor
を利用するための Apache の設定 #Edit sourceAppArmor には、 Apache Web サーバ 向けの mod_apparmor
(apache2-mod-apparmor
パッケージ) が提供されています。このモジュールを使用することで、 Apache Web サーバをチェンジハット対応にすることができます。 Apache Web サーバと共にインストールしてください。
Apache がチェンジハット対応になることで、受信したそれぞれの URI に対して、下記のような AppArmor セキュリティプロファイルが存在していないかどうかを調べます。
URI 固有のハット。例: ^www_app_name/templates/classic/images/bar_left.gif
DEFAULT_URI
HANDLING_UNTRUSTED_INPUT
apache2-mod-apparmor
をインストールしたあとは、モジュールを有効化してから、下記のように実行して Apache を再起動します:
>
a2enmod apparmor && sudo systemctl reload apache2
Apache は純粋なテキスト形式の設定ファイルにディレクティブを配置することで、設定を行うことができます。メインとなる設定ファイルは /etc/apache2/httpd.conf
です。 Apache を独自にコンパイルして使用している場合は、コンパイル時の設定にあわせてファイルを選択してください。ディレクティブは Apache の動作を変更するためのもので、設定ファイル内の任意の場所に配置することができます。メインの設定ファイルを変更したあとは、 sudo systemctl reload apache2
を実行することで、変更点を反映させることができます。
<VirtualHost> と </VirtualHost> のディレクティブを利用して、特定の仮想ホストにのみ適用されるディレクティブの範囲を指定します。 Apache における仮想ホストの設定方法について、詳しくは https://httpd.apache.org/docs/2.4/mod/core.html#virtualhost をお読みください。
チェンジハット機能固有の設定キーワードは AADefaultHatName
です。これは AAHatName
に似た設定で、 AADefaultHatName My_Funky_Default_Hat
のように指定します。
これを設定することで、仮想ホストやその他の Apache サーバディレクティブに対して、使用すべき既定のハットを設定することができます。もちろん仮想ホストごとに異なる既定のハットを設定することもできます。この設定は AAHatName
で上書きすることができます。逆に言えば、該当する AAHatName
や URI でのハットに当てはまるものが存在しない場合の、既定のハットとなります。 AADefaultHatName
でのハット指定が存在しない場合は、 DEFAULT_URI
ハット (存在すれば) を使用するようになります。
全くどのハットも設定されていない場合は、 「親」 プロセスである Apache のハットが適用されます。
設定ファイル内の Location および Directory のディレクティブの中でハット名を指定することで、 Apache が URI やディレクトリを処理する際、指定したセキュリティプロファイルを適用するようになります。 Apache における Location および Directory ディレクティブの使い方について、詳しくは https://httpd.apache.org/docs/2.4/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 ディレクティブも上記と同様ですが、こちらのディレクティブはファイルシステム内のディレクトリを指定する点が異なることに注意してください:
<Directory "/srv/www/www.example.org/docs"> # 末尾にスラッシュが無いことに注意 AAHatName example.org </Directory>
前の章では mod_apparmor
に関する情報と、特定の Web アプリケーションのセキュリティを向上させる方法について学んできました。この章では、 Web アプリケーションに対してハットを作成するための現実的な例と、 AppArmor のチェンジハット機能の使用方法について説明しています。なお、本章では AppArmor のコマンドラインツールを利用して説明を行っていますが、これは YaST の AppArmor モジュールではすべての機能を提供しているわけではないためのものです。
本章では、例として Adminer ( https://www.adminer.org/ja/ ) と呼ばれる Web アプリケーションのセキュリティを向上させます。これは PHP で書かれた完全機能の SQL データベース管理ツールで、たった 1 つの PHP ファイルだけで作られています。 Adminer を動作させるには、まず Apache Web サーバと PHP のほか、 PHP の Apache モジュールと PHP に対応したデータベースドライバを用意する必要があります。今回は MariaDB を利用することにします。必要なパッケージをインストールするには、下記のように入力して実行します:
zypper in apache2 apache2-mod_apparmor apache2-mod_php5 php5 php5-mysql
Adminer を動作させるための Web 環境の構築は、下記のようにして行います:
まずは Apache 向けの apparmor
と php5
のモジュールを有効化します。有効化を行うには、下記のように実行します:
>
a2enmod apparmor php5
あとは Apache を再起動します:
>
sudo
systemctl restart apache2
MariaDB が動作していることを確認します。動作しているかどうかが分からない場合は、下記を実行して再起動します:
>
sudo
systemctl restart mariadb
https://www.adminer.org から Adminer をダウンロードして、 /srv/www/htdocs/adminer/
にコピーしたあと、ファイル名を adminer.php
に変更します。スクリプトのフルパスは /srv/www/htdocs/adminer/adminer.php
であることになります。
Web ブラウザを起動して URI 欄に http://localhost/adminer/adminer.php
と入力し、 Adminer の動作確認を行います。 Adminer をリモートのサーバにインストールしている場合は、 localhost
の部分をサーバのホスト名に置き換えてください。
Adminer のログインページの表示時に何らかの問題が発生した場合は、まず /var/log/apache2/error.log
にある Apache のエラーログファイルをご覧になることをお勧めします。 Web ページにアクセスできない理由として考えられる理由としては、既に Apache が AppArmor の制御下にあり、適用されているプロファイルが Adminer を動作させるには厳しすぎることも考えられます。この場合は、 aa-status
を実行して確認を行い、必要であれば下記を実行し、 Apache を一時的に不平モードに設定してください:
#
sudo aa-complain usr.sbin.httpd2-prefork
Adminer を動作させるための Web 環境が整ったら、次に Apache の mod_apparmor
を設定します。これにより、 AppArmor が Adminer に対するアクセスを検知して、固有の 「ハット」 に対する変更を行うことができるようになります。
mod_apparmor
の設定 #Apache には、 /etc/apache2/
と /etc/apache2/conf.d/
という設定ファイルのディレクトリが存在しています。どちらのディレクトリ内でもかまいませんので、テキストエディタを利用してファイルを作成してください。この例では、 vim
エディタを利用して設定ファイル /etc/apache2/conf.d/apparmor.conf
を作成することにします。
>
sudo
vim /etc/apache2/conf.d/apparmor.conf
テキストエディタ内で、下記のとおり入力します。
<Directory /srv/www/htdocs/adminer> AAHatName adminer </Directory>
上記の設定を追加することで、 Apache に対して /adminer
のディレクトリ (およびそれ以下のサブディレクトリやファイル) 宛のアクセスがあった際、 AppArmor 側でチェンジハットを行うことを指示します。このディレクトリ内には、既に adminer.php
があるはずです。
ファイルを保存して、テキストエディタを終了します。あとは下記のように実行して Apache を再起動します:
>
sudo
systemctl restart apache2
これで Apache に対する Adminer の設定が完了し、 Adminer の実行時には 「ハット」 を変更することができるようになります。あとは AppArmor の設定で、 Adminer 向けのハットを作成することになります。この時点までに AppArmor のプロファイルを作成していない場合は、以下の手順を実施する前に作成しておいてください。 Apache のメインバイナリは /usr/sbin/httpd2-prefork
ですから、対応するプロファイルは /etc/apparmor.d/usr.sbin.httpd2-prefork
というファイル名で存在しているはずです。
テキストエディタを利用して、 /etc/apparmor.d/usr.sbin.httpd2-prefork
というファイル名のファイルを開いて (存在していない場合は作成して) ください。ファイルの内容は下記のようになっているはずです:
#include <tunables/global> /usr/sbin/httpd2-prefork { #include <abstractions/apache2-common> #include <abstractions/base> #include <abstractions/php5> capability kill, capability setgid, capability setuid, /etc/apache2/** r, /run/httpd.pid rw, /usr/lib{,32,64}/apache2*/** mr, /var/log/apache2/** rw, ^DEFAULT_URI { #include <abstractions/apache2-common> /var/log/apache2/** rw, } ^HANDLING_UNTRUSTED_INPUT { #include <abstractions/apache2-common> /var/log/apache2/** w, } }
末尾の閉じ中括弧 ( }
) の前に、下記のような行を挿入します:
^adminer flags=(complain) { }
ここでは、ハット名の後ろに (complain)
を指定していることに注意してください。これにより、 AppArmor での adminer
ハットを不平モードに設定することになります。これは、この時点では Adminer のアクセス要件がわかっていないため、それを調べるための設定です。
ファイルを保存して AppArmor を再起動し、 Apache を再起動します。
>
sudo
systemctl reload apparmor apache2
続いて adminer
ハットが正しく不平モードになっていることを確認します。
>
sudo
aa-status apparmor module is loaded. 39 profiles are loaded. 37 profiles are in enforce mode. [...] /usr/sbin/httpd2-prefork /usr/sbin/httpd2-prefork//DEFAULT_URI /usr/sbin/httpd2-prefork//HANDLING_UNTRUSTED_INPUT [...] 2 profiles are in complain mode. /usr/bin/getopt /usr/sbin/httpd2-prefork//adminer [...]
上記のとおり、 httpd2-prefork//adminer
が不平モードになっていることがわかります。
あとは adminer
ハットに対して、必要なアクセス権限を見つけ出していく作業になります。この時点では adminer
ハットは不平モードに設定されているため、ログ内にポリシーへの違反が記録されているものの、実際の拒否は発動されていません。そのため、 Web ブラウザから adminer.php
の機能を一通り試して、必要な権限を収集していってください。収集が終わったら、 aa-logprof
を実行することで、ハットのプロファイルの作成支援を行います。
adminer
ハット向けのルールの生成 #Adminer を Web ブラウザで開きます。ローカルにインストールした場合は、 URI は http://localhost/adminer/adminer.php
になるはずです。
まずは使用するデータベースエンジン (ここでは MariaDB) を選択し、既存のデータベースにユーザ名とパスワードを入力してログインします。なお、データベース名については、ログイン後に指定することもできますので、指定する必要はありません。あとは Adminer の機能を一通り試してください。新しいデータベースを作成したり、新しいテーブルを作成したり、ユーザ権限を設定したりなどです。
ひととおり Adminer のユーザインターフェイスをテストしたら、コンソールに戻って収集したログの調査を行います。
>
sudo
aa-logprof Reading log entries from /var/log/audit/audit.log. Updating AppArmor profiles in /etc/apparmor.d. Complain-mode changes: Profile: /usr/sbin/httpd2-prefork^adminer Path: /dev/urandom Mode: r Severity: 3 1 - #include <abstractions/apache2-common> [...] [8 - /dev/urandom] [(A)llow] / (D)eny / (G)lob / Glob w/(E)xt / (N)ew / Abo(r)t / (F)inish / (O)pts
aa-logprof
のメッセージによると、下記のとおり adminer
のハットが正しく認識されていることが分かります:
Profile: /usr/sbin/httpd2-prefork^adminer
aa-logprof
は、検出されたそれぞれの AppArmor イベントから、適切なルールを選択するよう依頼します。使用したいルールを指定したあと を選択します。 aa-genprof
と aa-logprof
の使用方法について、詳しくは 33.7.3.8項 「aa-genprof: プロファイルの生成」 をお読みください。
aa-logprof
では、特定のイベントに対して複数のルール候補を提示して選択を求めます。場合によっては 抽象 と呼ばれる、特定の目的向けのルールセットをまとめた仕組みを提案することもあります。このような場合は、直接のルールではなく抽象を選択したほうが便利な場合があります:
1 - #include <abstractions/php5> [2 - /var/lib/php5/sess_3jdmii9cacj1e3jnahbtopajl7p064ai242]
上記の例では、
を押して を押すことで、抽象の取り込みを設定することができます。最後に、下記のとおり保存を行うかどうかを尋ねられます。
The following local profiles were changed. Would you like to save them? [1 - /usr/sbin/httpd2-prefork] (S)ave Changes / [(V)iew Changes] / Abo(r)t
を押して変更を保存してください。
変更が終わったら、 aa-enforce
を実行してプロファイルを強制モードに設定します:
>
sudo
aa-enforce usr.sbin.httpd2-prefork
aa-status
で状態を確認します:
>
sudo
aa-status apparmor module is loaded. 39 profiles are loaded. 38 profiles are in enforce mode. [...] /usr/sbin/httpd2-prefork /usr/sbin/httpd2-prefork//DEFAULT_URI /usr/sbin/httpd2-prefork//HANDLING_UNTRUSTED_INPUT /usr/sbin/httpd2-prefork//adminer [...]
上記のとおり、 //adminer
のハットが complain (不平) から enforce (強制) モードに切り替えられています。
あとは再度 Adminer を Web ブラウザで開いて動作を確認してください。何らかの問題を見つけた場合は、不平モードに戻して手順を繰り返し、 aa-logprof
でプロファイルを更新してください。
^adminer
プロファイルは、親プロファイルである usr.sbin.httpd2-prefork
の中で動作するプロセスから見た場合にのみ利用することができます。
32.2項 「プロファイルの編集」 を参照) を使用するか、もしくは (手順に関する詳細は 32.1項 「プロファイルの手動追加」 を参照) を使用することで、 AppArmor のプロファイル内にハット (サブプロファイル) を追加することができます。 ウインドウ内でチェンジハットのサブプロファイルを追加するには、下記のようにして行います。
(手順に関する詳細は