コンピュータシステムのセキュリティを効率的に強化するには、まず権限を仲介するプログラムをできる限り少なくした後、それらのプログラムをできるだけ強く保護する流れで行います。 AppArmor は、お使いの環境下で攻撃にさらされるプログラムに対してプロファイルを作成するだけで保護が実現できる仕組みであることから、セキュリティを強化する際の手間を劇的に減らすことができます。 AppArmor ではポリシーの仕組みによって、プログラムが想定通りの動作のみを実行するよう強制することができます。
AppArmor では予防接種技術により、アプリケーションが直面する可能性のあるプログラム固有の脆弱性から身を守ることができます。 AppArmor をインストールしてプロファイルを構築し、コンピュータを再起動するだけで、 AppArmor のセキュリティポリシーを強制することができますので、システムを保護することができるようになります。ちなみに、 AppArmor によるプログラムの保護を 予防接種 (immunizing) と呼びます。
このような構造により、管理者は攻撃に対して脆弱なアプリケーションに対して関心を持っておいて、それらに対してプロファイルを作成するだけでよいことになります。つまりシステムの保護は、 AppArmor のプロファイルの作成と運用、そしてそこから発生し AppArmor のレポート機能によって報告される、ポリシー違反や例外の監視を行うだけの作業となるわけです。
ユーザ側では AppArmor の存在に気がつくことはありません。 AppArmor は 「裏方で」 動作している仕組みであり、ユーザ側での操作は何も必要としないためです。 AppArmor での性能劣化もほとんど発生しません。 AppArmor のプロファイルでカバーしていない動作や、 AppArmor によって禁止されているアプリケーションの動作が発生したような場合でも、管理者がそれに気づいてプロファイルの調整を行うだけであるためです。
AppArmor には、様々な既定のアプリケーションプロファイル集が用意されていて、標準的な Linux サービスを保護しています。他のアプリケーションを保護したい場合は、 AppArmor のツールを利用して、保護対象のアプリケーションに対してプロファイルを作成してください。本章では、プログラムに対する予防接種の考え方について説明しています。既に一通りの知識をお持ちで、 AppArmor のプロファイルを作成したり管理したりしたい場合は、 第30章 「プロファイルのコンポーネントと文法」 , 第32章 「YaST を利用したプロファイルの構築と管理」 , 第33章 「コマンドラインからのプロファイル構築」 などをお読みください。
AppArmor では、ネットワークサービスに対する直感的なアクセス制御の仕組みが提供されています。この仕組みでは、それぞれのプログラムが読み込んだり書き込んだり、実行したりすることを許すファイルのほか、どの種類のネットワークに接続できるのかを制御します。このような仕組みにより、それぞれのプログラムが期待通りの動作をするように強制することができます。また、 AppArmor ではプログラムを検疫することで、不正な処理によるダメージからシステムを保護することができるようになっています。
AppArmor はホストへの侵入保護や強制アクセス制御の仕組みを提供するものです。従来のアクセス制御では、コンピュータを巨大なタイムシェアリングシステムとして使用してきた経緯から、ユーザを中心にして構成されてきました。現在のネットワークサーバでは、ユーザに対して直接的なログインを許可することはなく、ユーザに対して様々なネットワークサービス (Web, メール, ファイル, 印刷などの各サーバ) を提供する存在へと変遷しています。 AppArmor では、ネットワークサービスやその他のプログラムに対するアクセス制御を設定し、脆弱性を突かれないように保護します。
AppArmor に関するより深い情報のほか、全体的な考え方については、 27.2項 「AppArmor プロファイリングに関する背景となる情報」 をお読みください。
本章では、 「舞台裏」 で何が起こっているのか (および YaST の裏では何を行っているのか) について、非常に基本的な部分を説明しています。
AppArmor のプロファイルは純粋なテキストファイル形式で、ここにはパス表記とアクセス許可が書かれています。プロファイルに関する詳細な書式情報については、 30.1項 「AppArmor プロファイル内の各部の意味」 をお読みください。また、このテキストファイル内にはディレクティブも含まれていて、ここには AppArmor のルーチンがプロセスやプログラムを検疫する際に強制される仕組みも設定されています。
AppArmor のプロファイルやポリシーを構築したり強制したりするにあたって、下記のようなツールが提供されています:
aa-status
aa-status
は、現時点での AppArmor の制限について、様々な内容をレポートします。
aa-unconfined
aa-unconfined
はお使いのシステムで動作しているアプリケーションのうち、ネットワーク接続を待ち受けていながら、 AppArmor のプロファイルで保護されていないものを検出します。このツールに関する詳細については、 33.7.3.12項 「aa-unconfined: 保護されていないプロセスの識別」 をお読みください。
aa-autodep
aa-autodep
はプロファイルに対する基本フレームワークで、本番環境で使用する前に肉付けを行う必要があるものです。生成されたプロファイルを読み込んで不平モードに設定すると、 AppArmor のルールでカバーされていないアプリケーションの挙動をレポートします。このツールに関する詳しい使い方については、 33.7.3.1項 「aa-autodep: 近似プロファイルの作成」 をお読みください。
aa-genprof
aa-genprof
は基本的なプロファイルを作成して、そのプロファイルを元にしてアプリケーションを実行し、プロファイルを改良するよう求めて、 AppArmor ポリシーで配慮する必要のある箇所をイベントとして報告します。アプリケーションの実行時に生成されたそれぞれのログイベントに対しては質問が表示され、どのように扱うべきかを判断することになります。プロファイルの生成が終わったあとは、そのまま強制モードに配置されます。このツールの詳しい使い方については、 33.7.3.8項 「aa-genprof: プロファイルの生成」 をお読みください。
aa-logprof
aa-logprof
は、アプリケーションが不平モードと強制モードの両方の制限で生成したログ項目を読み込んで確認することができるツールです。プロファイル内に新しい項目を生成する支援を行います。このツールの詳しい使い方については、 33.7.3.9項 「aa-logprof: システムログのスキャン」 をお読みください。
aa-easyprof
aa-easyprof
は AppArmor のプロファイル生成に関して使いやすいインターフェイスを提供します。 aa-easyprof
では雛形とポリシーグループを利用して、アプリケーションのプロファイルを素早く作成できるようにします。ただし、このツールはポリシーの生成支援までは行いますが、雛形とポリシーグループ、そして抽象化の仕組みに大きく依存していることに注意してください。 aa-genprof
や aa-logprof
と比較すると、 aa-easyprof
では制限の緩いプロファイルを作成することになります。
aa-complain
aa-complain
は AppArmor のプロファイルを強制モードから不平モードに切り替えます。プロファイル内に書かれたルールへの違反はログ内に記録されるものの、プロファイルは強制されません。このツールに関する詳しい使い方については、 33.7.3.2項 「aa-complain: 不平モード (学習モード) への突入」 をお読みください。
aa-enforce
aa-enforce
は AppArmor のプロファイルを不平モードから強制モードに切り替えます。プロファイル内に書かれたルールへの違反は記録され拒否されるようになり、結果としてプロファイルを強制することになります。この津ルールに関する詳しい使い方については、 33.7.3.6項 「aa-enforce: 強制モードへの突入」 をお読みください。
aa-disable
aa-disable
は、 1 つもしくは複数の AppArmor プロファイルに対して、強制モードを無効化することができます。このコマンドはカーネルからプロファイルの読み込みを解除するだけでなく、 AppArmor の起動時に読み込まれないようにもします。 aa-enforce
および aa-complain
を使用することで、この動作を変更することができます。
aa-exec
aa-exec
は指定した AppArmor プロファイルやネームスペースで制限した状態でプログラムを起動します。プロファイルとネームスペースの両方を指定すると、コマンドは新しいポリシーネームスペース内のプロファイルで制限されることになります。ネームスペースのみを指定した場合は、現在の制限のプロファイル名を使用します。プロファイルもネームスペースも指定しない場合は、標準的なプロファイル適用 (つまり aa-exec
を使用せずに実行した場合) と同じ動作になります。
aa-notify
aa-notify
はお使いのデスクトップ環境内に AppArmor の通知を表示することのできる、使いやすいユーティリティです。指定した日数の直近の通知に関して、概要を表示するように設定することもできます。詳しくは 33.7.3.13項 「aa-notify」 をお読みください。
AppArmor に関するある程度の知識を得たら、次にプロファイルを作成するアプリケーションの選択を行いましょう。プロファイルを作成する必要のあるプログラムとは、権限を仲介するタイプのプログラムです。下記のようなプログラムでは、一般ユーザが保持していない資源へのアクセスを行うことがありますので、実質的に権限を仲介していることになります:
cron
ジョブcron
で定期的に実行されるタイプのプログラムです。これらのプログラムは様々な情報源から入力を受け付け、特別な (場合によっては root
の) 権限で動作します。たとえば cron
では /usr/sbin/logrotate
を実行することがありますが、これはシステムログのローテーション (一定時間以上古いログを廃棄する) のほか、圧縮やメール送信などを行うことがあります。これらの種類のプログラムを見つける方法について、詳しくは 29.3項 「cron
ジョブへの予防接種」 をお読みください。
CGI スクリプトや PHP のページ、その他の複雑な Web アプリケーションなど、 Web ブラウザ経由で実行されるプログラムです。これらの種類のプログラムを見つける方法について、詳しくは 29.4.1項 「Web アプリケーションへの予防接種」 をお読みください。
ネットワークポートを開いて通信するプログラム (クライアントやサーバ) です。電子メールクライアントや Web ブラウザなどのユーザクライアントでも、権限を仲介していることになります。これらのプログラムは、ユーザのホームディレクトリに書き込むことのできる権限を保有していて、場合によっては不正な Web サイトや電子メール内に埋め込まれた不正なコードにアクセスすることで、潜在的に攻撃を受ける可能性があるためです。これらの種類のプログラムを見つける方法について、詳しくは 29.4.2項 「ネットワークエージェントに対する予防接種」 をお読みください。
逆に、権限を使用しないプログラムに対しては、プロファイルを作成する必要はありません。たとえばシェルスクリプトでは cp
プログラムを利用してファイルのコピーを行いますが、 cp
プログラムには既定のプロファイルやサブプロファイルが提供されていません。これは cp
プログラムが単純にファイルコピーの機能しか提供しないためで、呼び出し元のシェルスクリプトのプロファイルを引き継ぐだけで十分であるためです。そのため、 cp
プログラムは、呼び出し元のシェルスクリプトのプロファイルに書かれた許可内容に応じてファイルをコピーすることになります。
cron
ジョブへの予防接種 #Edit sourcecron
ジョブ内で実行されるプログラムを見つけるには、ご利用の環境内の cron
の設定をご確認ください。残念ながら、 cron
の設定は比較的複雑で、様々なファイルを調べる必要があります。それぞれ下記のファイルをご覧ください:
/etc/crontab /etc/cron.d/* /etc/cron.daily/* /etc/cron.hourly/* /etc/cron.monthly/* /etc/cron.weekly/*
crontab
コマンドを実行すると、現在のユーザに対する cron ジョブの一覧を表示したり編集したりすることができます。 root
に対する cron
ジョブの一覧を表示/編集したい場合は、 root
になってから crontab -e
を実行することで編集を、 crontab -l
を実行することで一覧表示をすることができます。
aa-unconfined
ツールを使用することで、プロファイルを作成すべきネットワークサーバデーモンを自動的に見つけることができます。
aa-unconfined
ツールは netstat -nlp
コマンドを利用して、コンピュータ内でポートを開いているプログラムを検出します。このツールでは、開いているポート番号と対応するプログラム、そして読み込まれている AppArmor のプロファイルセットをそれぞれ検出することができます。検出が完了すると、 aa-unconfined
ツールはそれぞれのプログラムと、対応する AppArmor のプロファイルが存在していればそれを、存在していなければ 「none」 (つまり制限が課されていない) を表示します。
新しいプロファイルを作成した場合、 AppArmor で正しく制限を受けるようにするため、プロファイルを作成したプログラムを再起動しなければなりません。
下記は aa-unconfined
の出力例です:
37021 /usr/sbin/sshd2 confined by '/usr/sbin/sshd3 (enforce)' 4040 /usr/sbin/smbd confined by '/usr/sbin/smbd (enforce)' 4373 /usr/lib/postfix/master confined by '/usr/lib/postfix/master (enforce)' 4505 /usr/sbin/httpd2-prefork confined by '/usr/sbin/httpd2-prefork (enforce)' 646 /usr/lib/wicked/bin/wickedd-dhcp4 not confined 647 /usr/lib/wicked/bin/wickedd-dhcp6 not confined 5592 /usr/bin/ssh not confined 7146 /usr/sbin/cupsd confined by '/usr/sbin/cupsd (complain)'
最初に表示されるのが番号です。この番号は、接続を待ち受けているプログラムのプロセス ID 番号 (PID) です。 | |
次に表示されるのが文字列で、接続を待ち受けているプログラムの絶対パスです。 | |
最後に表示されるのが、プログラムの権限を制限しているプロファイル (もしあれば) です。 |
aa-unconfined
は root
の権限が必要なプログラムであり、 AppArmor のプロファイルによる制限が課されたシェルからは、実行すべきではありません。
aa-unconfined
ではネットワークインターフェイスを区別せずに扱います。そのため、内部の LAN インターフェイスのみで待ち受けているプロセスに対しても、ポートを開いていれば一覧に記載されることになります。
ユーザが使用しているネットワーククライアントアプリケーションの検出は、お使いの環境によって異なる方法になります。 aa-unconfined
ツールは、クライアントアプリケーションが開いているネットワークポートに対しても報告を行いますが、 aa-unconfined
で分析している最中に動作していたアプリケーションのみが検出されます。一般に、ネットワークサーバアプリケーションは常に動作させておくものですが、クライアントアプリケーションは必要に応じて起動する仕組みであることから、常に検出されるとは限らないことになります。
AppArmor のプロファイルによるネットワーククライアントアプリケーションへの適用は、ユーザ側の希望に応じて行ってください。そのため、クライアントアプリケーションのプロファイル作成については、ここでは説明しません。
デスクトップアプリケーションを積極的に制限したい場合は、 aa-unconfined
コマンドに --paranoid
オプションを追加して実行してください。これにより、動作中の全てのプロセスを一覧で表示し、それらに対して関連づけられている可能性のある AppArmor プロファイルを表示することができます。これにより、 AppArmor のプロファイルを必要とするプログラムを判断することができるようになります。
新しくプロファイルを作成した場合やプロファイルを修正した場合、可能であれば、実施したアプリケーションの使用範囲を添えて <apparmor@lists.ubuntu.com> のメーリングリストに送信していただければ幸いです。 AppArmor チームではその内容を精査して、 openSUSE Leap の一部として組み込むかもしれません。ただし、お送りいただいたプロファイルを全て組み込むことは保証できませんが、できる限りの努力はさせていただきます。
Web アプリケーションを見つけたい場合は、まず Web サーバの設定ファイルを調査することをお勧めします。 Apache Web サーバであれば、非常に細かく設定することができるシステムであるため、設定によって Web アプリケーションを様々なディレクトリ内に配置することができます。 openSUSE Leap の既定では、 Web アプリケーションは /srv/www/cgi-bin/
内に配置されます。なお、可能な限りそれぞれの Web アプリケーションに AppArmor プロファイルを作成してください。
これらのプロクラムが見つかったら、あとは aa-genprof
ツールと aa-logprof
ツールを使用することで、それらに対する AppArmor のプロファイルを作成することができます。
CGI プログラムは Apache Web サーバが実行する仕組みであることから、 openSUSE Leap 向けの Apache2 それ自身用に作成されている usr.sbin.httpd2-prefork
というプロファイルは、 CGI プログラムにあわせて実行許可を追加するよう変更しなければなりません。たとえば /srv/www/cgi-bin/my_hit_counter.pl rPx
という行を追加すると、 my_hit_counter.pl
という Perl スクリプトを Apache から実行する許可を与え、 my_hit_counter.pl
用のプロファイルを別途に用意することになります。 my_hit_counter.pl
に専用のプロファイルを用意していない場合は、 /srv/www/cgi-bin/my_hit_counter.pl rix
のように指定して、 my_hit_counter.pl
が usr.sbin.httpd2-prefork
のプロファイルを引き継ぐように設定してください。
Apache が実行するそれぞれの CGI スクリプトに対していちいち実行許可を設定するのは、ユーザにとっては不便に感じるかもしれません。その代わりに管理者は、複数の CGI スクリプトに対してアクセスを制御することができます。たとえば /srv/www/cgi-bin/*.{pl,py,pyc} rix
のように指定すると、 /srv/www/cgi-bin/
ディレクトリ内にあって .pl
(Perl スクリプト) もしくは .py
や .pyc
(Python スクリプト) で終わるファイル名のスクリプト全てを含めることができるようになります。この設定では、 ix
と書かれていることから、 Python スクリプトが Apache のプロファイルを引き継ぐようになります。このような設定は、それぞれの CGI スクリプトに対して、いちいち個別のプロファイルを作成したくない場合に便利です。
Apache モジュール ( mod_perl
や mod_php
) で Web アプリケーションを動作させていて、サブプロセスを制限するモジュール ( apache2-mod-apparmor
) の機能を使用したい場合は、 YaST 内もしくはコマンドラインでプロファイルを追加する際に、 ChangeHat の機能をお使いください。サブプロセス制限に関する利点について、詳しくは 34.2項 「チェンジハット対応のアプリケーションの管理」 をお読みください。
mod_perl
や mod_php
を使用する Web アプリケーションのプロファイルを作成する場合は、少し異なる作業が必要となります。この場合の 「プログラム」 は、 Apache プロセス内のモジュールが直接解釈して実行するスクリプトとなりますので、プログラムの実行が発生しないためです。この場合は、 AppArmor に対応した Apache が要求先の URI の名前からサブプロファイル (「ハット」) を判断して change_hat()
を呼び出します。
Apache がモジュールのスクリプトを探す際の設定にもよりますが、スクリプトに対する名前と URI とが無関係になってしまうことがあります。 Apache 側で異なる場所にスクリプトを配置するように設定している場合は、 AppArmor がアクセス違反を報告する際、ログファイル内に異なる名前で記録されてしまうことがあります。詳しくは 第36章 「プロファイルを作成したアプリケーションの管理」 をお読みください。
mod_perl
や mod_php
のスクリプトの場合、これはリクエストした Perl スクリプトや PHP ページの名前になります。たとえば下記のようなサブプロファイルを設定したとすると、 localtime.php
のページからローカルのシステム時刻とロケールファイルへのアクセスができるようになります:
/usr/bin/httpd2-prefork { # ... ^/cgi-bin/localtime.php { /etc/localtime r, /srv/www/cgi-bin/localtime.php r, /usr/lib/locale/** r, } }
何もサブプロファイルを指定しない場合、 Apache の AppArmor 対応版は DEFAULT_URI
ハットを適用します。このサブプロファイルは Web ページを表示するだけであれば十分なサブプロファイルです。 AppArmor が提供する DEFAULT_URI
は、下記のようになっています:
^DEFAULT_URI { /usr/sbin/suexec2 mixr, /var/log/apache2/** rwl, @{HOME}/public_html r, @{HOME}/public_html/** r, /srv/www/htdocs r, /srv/www/htdocs/** r, /srv/www/icons/*.{gif,jpg,png} r, /srv/www/vhosts r, /srv/www/vhosts/** r, /usr/share/apache2/** r, /var/lib/php/sess_* rwl }
Apache が提供する全ての Web ページと CGI スクリプトに対して、単一の AppArmor プロファイルを使用したい場合は、 DEFAULT_URI
サブプロファイルを編集することをお勧めします。 Apache 内での Web アプリケーションの制限について、詳しくは 第34章 「チェンジハット機能による Web アプリケーションのプロファイル作成」 をお読みください。
プロファイルを作成する必要のあるネットワークサーバデーモンやネットワーククライアント (fetchmail
や Firefox など) を見つけるには、まずお使いのマシンで開いているポートを探してください。その後、これらのポートを使用しているプログラムを探して、できる限り多くのプログラムに対してプロファイルを作成してください。ネットワークポートを開いている全てのプログラムに対してプロファイルを設定すれば、攻撃者は AppArmor のプロファイルポリシーで許可されていない限り、マシン内のファイルシステムには全くアクセスできなくなります。
スキャナ (nmap など) を使用すれば、サーバの外側から開いているネットワークポートを調べることができますし、内部からであれば root
で netstat --inet -n -p
を実行することで、調べることができます。その後、それらのポートで待ち受けているプログラムが何であるのかを調査します。
利用可能なオプションについて、詳しくは netstat
コマンドのマニュアルページをお読みください。