第19章 プログラムに対する免疫付与

目次

19.1. AppArmor フレームワークの紹介
19.2. 免疫を与えるプログラムの判断
19.3. cron ジョブへの免疫付与
19.4. ネットワークアプリケーションへの免疫付与

コンピュータシステムを効率よく堅牢にするには、権限を媒介するプログラムの 数を最小化し、可能な限りプログラムの機密性を高める必要があります。 AppArmor では、お使いの環境で攻撃に晒される可能性のあるプログラムをプロファイルする だけで作業は終わるため、お使いのコンピュータを堅牢にする作業の量を劇的に 減らすことができます。また AppArmor はプログラムが実行する可能性のある処理を 確かめるためにプロファイルを行なうだけで、それ以外にはプロファイルを使用 することはありません。

AppArmor® はアプリケーションに対して、生まれながらに持っているような脆弱性 から保護するための免疫技術を提供します。 AppArmor をインストールしてプロファイル の設定を完了し、コンピュータを再起動すれば、 AppArmor のセキュリティポリシーが 強制されることから、お使いのシステムに免疫が備わることになります。 AppArmor を利用したプログラムの保護は、 免疫 と呼びます。

管理者は、攻撃に対して脆弱なアプリケーションに対して、プロファイルの生成に のみ注力するだけで済みます。つまり、システムを堅牢にする作業は、 AppArmor のプロファイルセットを構築または管理し、ポリシー違反を監視するか、 AppArmor の レポート機能で例外を記録するなどの作業に置き換わることになります。

ユーザは AppArmor を全く気にする必要はありません。 AppArmor は 裏でこっそり 動作しているもので、ユーザ側に問い合わせを行なうようなことはありません。 AppArmor の使用によって性能が顕著に落ちるようなこともありませんし、 何らかのアプリケーション動作が AppArmor のプロファイル側で考慮範囲外のもので あったり、禁止されているものであったりした場合も、管理者がプロファイルを 調整して、そのような振る舞いに対応するようにするだけです。

AppArmor は標準の Linux サービスを保護するため、多数のアプリケーションに 対して、既定のプロファイル集を設定します。他のアプリケーションを保護するには、 AppArmor ツールを利用して、保護したいアプリケーションのプロファイルを作成して ください。この章では、プログラムに免疫を与えるための考え方を紹介しています。 既に AppArmor のプロファイルを構築していたり管理していたりする場合は、 第20章 プロファイルの構成と文法, 第22章 YaST を利用したプロファイルの構築と管理, 第23章 コマンドラインからのプロファイル構築 を読み進めてください。

また、AppArmor はネットワークサービスに対して、それぞれのプログラムがどのファイルに 読み込み/書き込み/実行を許可するのか、そしてどの種類のネットワークに アクセスを許可するのかを指定することで、合理的なアクセス制御を行なうことが できます。この仕組みにより、それぞれのプログラムが実行する可能性のある 処理を確認するだけで堅牢性を高めることができます。 AppArmor はプログラムを 検疫し、危険な処理によってシステム全体にダメージを与えてしまうようなこと からも保護することができます。

AppArmor はホスト侵入阻止と強制アクセス制御機能の両方を備えたシステムです。 従来、アクセス制御は巨大なタイムシェアリング (時間共有型の) システム向けに 構築された、ユーザにとっては集中管理型の仕組みでした。その後、ネットワーク サーバは直接的なログインを許可する代わりに、様々なネットワークサービス (Web, メール, ファイル共有, 印刷サービスなど) をユーザ向けに提供するように なりました。 AppArmor はこのようなネットワークサービスに対するアクセスを制御し、 その他のプログラムの弱点を突かれるようなことが無いように保護します。

[Tip]AppArmor の背景となる情報について

AppArmor に関するより深い概要や全体的な考え方について、詳しくは 17.1項 「AppArmor プロファイリングの関連情報」 をお読みください。

19.1. AppArmor フレームワークの紹介

この章では、 AppArmor を動作させている際に 裏側で何が行なわれている のか (および YaST インターフェイスの仕組み) について、非常に 基本的な部分を説明しています。

AppArmor のプロファイルは単純なテキストファイル形式で、パス項目とそれに対する アクセス権が書かれています。プロファイルについて、詳しくは 20.1項 「AppArmor プロファイルの構成」 をお読みください。この テキストファイル内に含まれている設定は AppArmor ルーチン側で読み取られた あと、プロセスやプログラムを検疫するために利用されます。

AppArmor のプロファイルやポリシーを構築したり強制したりするにあたって、 下記のようなツールを利用することができます:

aa-unconfined / unconfined

aa-unconfined はお使いのシステムでネットワーク接続を 待ち受けていて、かつ AppArmor のプロファイルで保護されていないアプリケーションを 検出します。このツールについて、詳しくは 23.6.3.8項 「aa-unconfined—保護されていないアクセスの検出」 をお読みください。

aa-autodep / autodep

aa-autodep は、本番の環境で使用する前に肉付けを行なう 必要があるような、プロファイルの基本的なフレームワークを作成します。 作成されたプロファイルは読み込まれたあと不平 (complain) モードに置かれ、 AppArmor のルールではカバーしていないアプリケーションの動作を報告します。 このツールについて、詳しくは 23.6.3.1項 「aa-autodep—概要プロファイルの作成」 をお読みください。

aa-genprof / genprof

aa-genprof は基本的なプロファイルを生成し、対象の アプリケーションを起動してプロファイルを改良したあと、 AppArmor のポリシー で注意する必要のある項目についてログを生成します。なお、アプリケーション の実行中に発生したログイベントについては、これらをどのように扱うのかに ついて、質問が表示されるようになっています。プロファイルが生成された 後は、これを読み込んで強制モードに移行します。このツールについて、詳しくは 23.6.3.4項 「aa-genprof—プロファイルの生成」 をお読みください。

aa-logprof / logprof

aa-logprof は、不平 (complain) モードのプロファイルで 制限しているアプリケーションに対し、そこから生成されたログを対話的に スキャンして確認するためのツールです。プロファイルが生成したログ から、新しい設定項目の作成を支援するツールです。このツールについて、 詳しくは 23.6.3.5項 「aa-logprof—システムログのスキャン」 をお読みください。

aa-complain / complain

aa-complain は AppArmor プロファイルのモードを、 強制モードから不平 (complain) モードに切り替えるためのツールです。 プロファイル内に設定されたルールの例外は記録されますが、強制され なくなります。このツールについて、詳しくは 23.6.3.2項 「aa-complain—不平モード/学習モードへの突入」 をお読みください。

aa-enforce / enforce

aa-enforce は AppArmor プロファイルのモードを、 不平 (complain) モードから強制モードに切り替えるためのツールです。 プロファイル内に設定されたルールの例外は記録されますが、許可されなく なり、プロファイルが強制されるようになります。このツールについて、 詳しくは 23.6.3.3項 「aa-enforce—強制モードへの突入」 をお読みください。

いったんプロファイルを構築して読み込むと、そのプロファイルに対する処理 方法を下記のいずれかから選択できるようになります:

aa-complain / complain

不平 (complain) モードでは、 AppArmor のプロファイルルールに対する違反、 たとえば対象のプログラムが、プロファイルで許可していないファイルに アクセスしようとした場合、違反内容は許可されますが記録されるように なります。プロファイルを改善するには、不平モードを有効にしてから プログラムの機能を一通り使ってみて、プログラムの動作特性に関する ログを生成させてください。生成されたログは AppArmor のツール (YaST または aa-logprof) を使用して後処理することで、ログイベントを 改善済みのプロファイルに変換することができます。

aa-enforce / enforce

強制モードでは AppArmor のプロファイルルールに対する違反、たとえば対象の プログラムが、プロファイルで許可していないファイルにアクセスしようと した場合、違反内容は記録されて禁止されるようになります。なお、既定では 強制モードが有効になるようになっています。違反事例の記録だけを行ない、 禁止させたくない場合は、不平 (complain) モードをお使いください。

19.2. 免疫を与えるプログラムの判断

AppArmor に関して基本的な知識を得ることができたら、次はプロファイルを生成する アプリケーションを選択する番です。プロファイル処理が必要なプログラムは 特権を取り扱うもので、下記のようにプログラムを使用するユーザはその資源 へのアクセス許可を持っていないものの、そのツールの使用時にそれらへの アクセスが許可されるようなプログラムが該当します:

cron ジョブ

cron で定期的に実行されるプログラムです。このようなプログラムでは、 様々な情報源から入力を受け取り、特別な権利 (時には root の権利) でプログラムを実行します。たとえば cron では /usr/sbin/logrotate を日々実行し、システムログを ローテートさせたり圧縮したり、場合によってはメールで送信したりします。 この種類のプログラムを発見する方法について、詳しくは 19.3項 「cron ジョブへの免疫付与」 をお読みください。

Web アプリケーション

Web ブラウザからのアクセスによって実行されるタイプのプログラムです。 CGI Perl スクリプトや PHP のページ、もしくはさらに複雑な Web アプリケーション も該当します。この種類のプログラムを発見する方法について、詳しくは 19.4.1項 「Web アプリケーションへの免疫付与」 をお読みください。

ネットワークエージェント

ネットワークポートを開くプログラム (サーバとクライアント) です。 メールクライアントや Web ブラウザなど、特権を取り扱うユーザ クライアントを含みます。これらのプログラムは、ユーザのホーム ディレクトリに書き込む際に特権を利用する場合があるほか、悪意を 持ったリモートからの情報、たとえば Web サイトに対する攻撃や不正な コードを含む電子メールなどを受け付ける可能性があります。 この種類のプログラムを発見する方法について、詳しくは 19.4.2項 「ネットワークエージェントへの免疫付与」 をお読みください。

その一方、特権を使用しないプログラムはプロファイルを行なう必要は ありません。たとえばシェルスクリプトは cp プログラム を使用する場合があります。 cp プログラムは独自の プロファイルを持たないため、呼び出し元のシェルスクリプトのプロファイルを 引き継ぐことになりますので、親のシェルスクリプトで読み込みや書き込みを 許可しているファイルであれば、任意のファイルをコピーすることができます。

19.3. cron ジョブへの免疫付与

cron で実行するプログラムを調べるには、まずお使いの環境で cron の設定を 調べる必要があります。残念ながら cron の設定は若干複雑な仕組みになって いるため、調査対象のファイルは複数存在します。定期的な cron ジョブは、 下記のファイルに書かれています:

/etc/crontab 
/etc/cron.d/* 
/etc/cron.daily/* 
/etc/cron.hourly/*
/etc/cron.monthly/* 
/etc/cron.weekly/*

また、 root の cron ジョブについては crontab -e で編集を行なうことができるほか、 crontab -l でジョブの一覧を表示することができます。それぞれ root になった 状態で実行してください。

プログラムを見つけることができたら、あとは AppArmor プロファイル ウイザード でプロファイルを作成してください。ここから先は 22.1項 「ウイザードを使用したプロファイルの追加」 をお読みください。

19.4. ネットワークアプリケーションへの免疫付与

プロファイル対象とすべきネットワークサーバとして、動作しているデーモンを 発見する自動的な方法として、 aa-unconfined ツールが 用意されています。

aa-unconfined ツールは netstat -nlp コマンドを使用して、お使いのコンピュータの内側から接続可能なポートを調査 したあと、そのポートを使用しているプログラムを判断し、読み込んだ AppArmor の プロファイル集を調べます。調査が終了すると、 aa-unconfined プログラムは各プログラムとそれに関連する AppArmor のプロファイル (プロファイルが 無い場合は なし) を表示します。

[Note]

新しいプロファイルを作成する場合は、 AppArmor で効率よく制限を受けられるように するため、プロファイルされているプログラムを再起動しなければなりません。

下記は aa-unconfined の出力例です:

2325 /sbin/portmap not confined 
37021 /usr/sbin/sshd2 confined
   by '/usr/sbin/sshd3 (enforce)' 
4040 /usr/sbin/ntpd confined by '/usr/sbin/ntpd (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)'
5274 /sbin/dhcpcd not confined 
5592 /usr/bin/ssh not confined 
7146 /usr/sbin/cupsd confined by '/usr/sbin/cupsd (complain)'
  

1

表示の冒頭は番号で始まります。この番号は待ち受けているプログラムの プロセス ID (PID) を示しています。

2

2 つめは、待ち受けているプログラムの絶対パスを表わす文字列です。

3

3 つめは、プログラムを制限しているプロファイルを示します (もしあれば)。

[Note]

aa-unconfined を実行するには root の権限が 必要であるほか、 AppArmor のプロファイルで制限されたシェルから実行しては いけません。

aa-unconfined はネットワークインターフェイスを 識別することはしていないため、内部の LAN インターフェイスに対してのみ 待ち受けているプロセスであっても、 AppArmor で制限されていない場合は常に 表示されることに注意してください。

ネットワーククライアントとして動作しているアプリケーションの検出は、 お使いの環境に依存します。 aa-unconfined ツール でもクライアントアプリケーションで開いているネットワークポートを検出し、 報告する機能を備えていますが、 aa-unconfined による 分析を行なったタイミングで動作しているクライアントアプリケーションしか 検出することができません。これは、ネットワークサービスは常時稼働している のに対し、ネットワーククライアントは必要な時にしかネットワークに接続しない ためです。

AppArmor のプロファイルをお使いのネットワーククライアントアプリケーションに 適用する際も、お使いの環境に依存します。そのため、ネットワーククライアント に対するプロファイルについては、ユーザ側でさらに調整する余地を残した作り にしています。

デスクトップアプリケーションに対して積極的に制限を行ないたい場合、 aa-unconfined コマンドに対して paranoid (偏執) オプションを設定してください。これにより動作中のすべてのプロセスと それに対応する AppArmor のプロファイルが、各プロセスに関連しているかどうかに 関わらず表示されるようになります。ユーザはその情報から、それらのプログラム に対して AppArmor のプロファイルを設定する必要があるかどうかを判断できます。

また、新しく作成したプロファイルや修正済みのプロファイルをお持ちの場合は、 apparmor-general@forge.novell.com のメーリングリストに、アプリケーションの使用事例とともに送信することも できます。これにより AppArmor チームがプロファイルを分析し、 openSUSE 内に取り込んでもらうことができる場合があります。お送りいただいたすべての プロファイルを取り込む保証はできませんが、できる限り openSUSE に同梱できるように努力させていただきます。 なお、上記のメーリングリストは英語でのみサービスを提供させていただいて おります。あらかじめご注意ください。

上記以外にも、 AppArmor のプロファイルリポジトリを使用して、作成した プロファイルを他のユーザに公開したり、他の AppArmor ユーザや開発者が作成した プロファイルをダウンロードしたりすることもできます。 AppArmor のプロファイル リポジトリの使い方について、詳しくは 第21章 AppArmor のプロファイルリポジトリ をお読みください。

19.4.1. Web アプリケーションへの免疫付与

Web アプリケーションを見つけるには、お使いの Web サーバの設定を調査する ところから始まります。 Apache Web サーバは高度な設定を行なうことができる システムであるため、 Web アプリケーションを設定に応じて様々な場所に 配置することができます。 openSUSE では、 Web アプリケーションの既定の 配置場所として /srv/www/cgi-bin/ というディレクトリが 用意されています。なお、最大限の保護を行なう目的から、それぞれの Web アプリケーションに対して AppArmor のプロファイルを用意しておくことをお勧め します。

これらのプログラムを見つけることができたら、 AppArmor の AppArmor プロファイル ウイザード を使用して、それらに対するプロファイルを作成します。詳しくは 22.1項 「ウイザードを使用したプロファイルの追加」 をお読みください。

CGI プログラムは Apache Web サーバから実行される仕組みであるため、 Apache 自身に 対するプロファイル usr.sbin.httpd2-prefork (openSUSE 用の Apache2 の場合) を編集し、これら CGI プログラムに対する実行許可を追加しなければ なりません。たとえば /srv/www/cgi-bin/my_hit_counter.pl rpx を追加すると、 Apache に対して my_hit_counter.pl の実行を許可し、 my_hit_counter.pl に対する独自のプロファイルを適用するように 指定することになります。 my_hit_counter.pl に対する独自の プロファイルが存在しない場合、 /srv/www/cgi-bin/my_hit_counter.pl rixusr.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 側のプロファイルを継承する意味になります。

[Note]

Web アプリケーションが Apache のモジュール (mod_perlmod_php) で処理されている環境で、サブプロセス制限 モジュール (apache2-mod-apparmor) の機能を使用したい場合は、 YaST やコマンドラインでプロファイルを追加する際、 ChangeHat (ハット変更) 機能を 利用してください。サブプロセスの制限に対して、さらに詳しく知るには 24.1項 「Apache のハット変更」 をお読みください。

mod_perlmod_php を使用する Web アプリケーションのプロファイルは、通常とは少し異なる方法で行なう必要が あります。この場合、 プログラム はモジュールで直接解釈され Apache 内で実行されるスクリプトのことを指すため、プロセスの起動は行なわれ なくなります。その代わり、 Apache の AppArmor バージョンが、要求された URI の 名前に応じてサブプロファイル (ハット) を利用するよう、 change_hat() を呼び出します。

[Note]

実行するスクリプトに対する名前は、 URI と異なる場合があります。これは Apache のモジュールスクリプトの参照先に依存して決まります。 Apache で スクリプトの場所を異なる場所に指定した場合、 AppArmor がアクセス違反を報告 する際に異なる名前が表示されます。詳しくは 第26章 プロファイルを作成したアプリケーションの管理 をお読みください。

mod_perlmod_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 のハットを適用します。このサブ プロファイルは基本的に HTML の 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 サブプロファイルを編集するのが最も良い方法です。

19.4.2. ネットワークエージェントへの免疫付与

プロファイルすべきネットワークサーバデーモンやネットワーククライアント (たとえば fetchmail, Firefox, Amarok, Banshee など) を見つけるには、 まずお使いのマシンにおけるポートの使用状況を調べる必要があります。その後 それらのポートを待ち受けているプログラムを調査し、それらに対して可能な 限りプロファイルを設定します。ネットワークポートを開いている全てのプログラム に対してプロファイルを設定すると、攻撃者は AppArmor のプロファイルポリシーを 介することでしかシステムにアクセスできないようになります。

お使いのサーバで開いているポートを調べるには、マシンの外側から実施するには スキャナ (nmap など) を使用できるほか、マシン内から実施する場合は netstat --inet -n -p コマンドを利用することで調べる ことができます。その後、検出された各ポートに対して、応答しているプログラムが 何であるのかを調べます。

[Tip]

利用可能なオプションについての説明は、 netstat の マニュアルページをお読みください。


openSUSE セキュリティガイド 13.1