第20章 プロファイルの構成と文法

目次

20.1. AppArmor プロファイルの構成
20.2. プロファイルの種類
20.3. #include ステートメント
20.4. 機能項目 (POSIX.1e)
20.5. ネットワークアクセス制御
20.6. パスとグロブ
20.7. ファイルのアクセス許可とアクセスモード
20.8. 実行モード
20.9. リソース制限制御
20.10. 監査ルール

アプリケーションの動作を制限するために AppArmor のプロファイルを構築する 作業は、非常に直感的に行なうことができます。また、 AppArmor にはプロファイル 作成のためのツールが複数個同梱されているため、プログラミングやスクリプト 作成の知識が無くても、プロファイルを作成できるようになっています。管理者 がやるべき作業は、セキュリティを高める目的で各アプリケーションに対し、 もっとも厳しいアクセス許可や実行許可を設定するよう、ポリシーの判断を 行なうだけです。

アプリケーションのプロファイルを更新したり修正したりする作業は、 ソフトウエアの設定や必要とする動作範囲の変更があった場合にのみ必要となります。 AppArmor では、プロファイルの更新や修正を扱うための直感的なツールも提供しています。

プロファイル対象のプログラムを選択した後は、 AppArmor のプロファイルを構築する 作業を行ないます。これには、プロファイルの構成や文法を理解することが重要です。 AppArmor のプロファイルには複数のブロックが含まれ、シンプルで再利用性の高い プロファイルが構築できるような仕組みになっています:

#include ファイル

#include ステートメントは、他の AppArmor プロファイル からの情報を引き出すためのもので、プロファイル構造を共通化して単純化 するために使用します。

アブストラクト (概要)

アブストラクト (概要) は複数の #include ステートメント から構成されるもので、一般的なアプリケーションでの作業をまとめたものです。

プログラムチャンク

プログラムチャンクも複数の #include ステートメントから 構成されるものですが、特定のプログラムスイート固有のプロファイル集を 含んでいるものです。

機能項目

機能項目とは POSIX.1e Linux ケーパビリティに対するプロファイル項目で、 制限されたプロセスから特権の必要なシステムコールを呼び出す際、どのような 呼び出しを許可するのかを詳しく制御することができるものです。

ネットワークアクセス許可項目

ネットワークアクセス許可項目は、アドレスの種類やファミリーをベースにして、 ネットワークアクセスを制御するための項目です。

ローカル変数設定

ローカル変数は、パスへのショートカットを設定するためのものです。

ファイルアクセス制御項目

ファイルアクセス制御項目は、アプリケーションがアクセスできるファイルを 指定するためのものです。

rlimit 項目

rlimit 項目は、アプリケーションのリソースを制限するための制御を行なう 項目です。

プロファイルを行なうべきアプリケーションの判断については 19.2項 「免疫を与えるプログラムの判断」 をお読みください。また、 YaST を利用した場合の AppArmor プロファイルの作成 方法については、 第22章 YaST を利用したプロファイルの構築と管理 をお読みください。 AppArmor のコマンドラインインターフェイスを利用した場合の AppArmor プロファイルの作成 方法については、 第23章 コマンドラインからのプロファイル構築 をお読みください。

20.1. AppArmor プロファイルの構成

プロファイルにどのような項目が含まれていて、どのように作成すべきなのかを 説明するのに最も簡単な方法は、サンプルのプロファイルについて詳細を説明する ことです。今回は /usr/bin/foo という名前のアプリケーションが あった場合を想定して説明します:

#include <tunables/global>1

# (対象のアプリケーションに関する説明)
/usr/bin/foo2
{3
   #include <abstractions/base>4

   capability setgid5,
   network inet tcp6,

   link /etc/sysconfig/foo -> /etc/foo.conf,7
   /bin/mount            ux,
   /dev/{,u}8random     r,
   /etc/ld.so.cache      r,
   /etc/foo/*            r,
   /lib/ld-*.so*         mr,
   /lib/lib*.so*         mr,
   /proc/[0-9]**         r,
   /usr/lib/**           mr,
   /tmp/9                r,
   /tmp/foo.pid          wr,
   /tmp/foo.*            lrw,
   /@{HOME}10/.foo_file   rw,
   /@{HOME}/.foo_lock    kw,
   owner11 /shared/foo/** rw,
   /usr/bin/foobar       cx,12
   /bin/**               px -> bin_generic,13


   # foo のローカル (子となる) /usr/bin/foobar 向けプロファイル。

   profile /usr/bin/foobar14 {
      /bin/bash          rmix,
      /bin/cat           rmix,
      /bin/more          rmix,
      /var/log/foobar*   rwl,
      /etc/foobar        r,
   } 

  # foo のハット "bar"
   ^bar15 {
    /lib/ld-*.so*         mr,
    /usr/bin/bar          px,
    /var/spool/*          rwl,
   } 
}

1

変数宣言を含むファイルを読み込んでいます。

2

制限されるべきプログラムのフルパスを指定しています。

3

中括弧 ({}) は、 include ステートメント/サブプロファイル/ パス項目/機能項目/ネットワーク項目に対するコンテナとして動作する記号です。

4

このディレクティブでは、プロファイルを簡略化するために AppArmor の プロファイルコンポーネントを取り込んでいます。

5

POSIX.1e ドラフトで規定されているケーパビリティ (capability) を 有効にする設定です。

6

アプリケーションに対してネットワークアクセスを許可する ディレクティブです。詳しくは 20.5項 「ネットワークアクセス制御」 をお読みください。

7

ソースとリンクの宛先を指定する、リンク対ルールです。詳しくは 20.7.6項 「リンク対」 をお読みください。

8

ここでの中括弧 ({}) は、カンマで区切られたそれぞれ の文字列について、これら両方のパターンをルールに含める意味になります。

9

プログラムに対して、ファイルシステムのどの領域へのアクセスを許可するかを 指定しています。最初の項目として指定するのはファイルに対する絶対パスで、 正規表現による一括指定も行なうことができます。 2 つめの項目は許可する アクセスモード (たとえば r は読み込みを、 w は書き込みを、 x は実行をそれぞれ 表わします) です。スペース類 (スペースまたはタブ) はファイル名の前にも 入力できるほか、ファイル名とアクセスモードの間にも入力できます。複数の アクセスモードを指定する場合のスペースやカンマは、入力してもしなくても かまいません。利用可能なアクセスモードについて、詳しい説明は 20.7項 「ファイルのアクセス許可とアクセスモード」 をお読みください。

10

ここで指定している変数は値に展開されるもので、プロファイル全体を変更する ことなく複数の設定を変更できるようになっています。

11

所有者条件ルールと呼ばれるもので、自分が所有するファイルへの読み書き許可を 与える意味になります。詳しくは 20.7.7項 「所有者条件ルール」 をお読みください。

12

この項目は、 /usr/bin/foobar のローカルプロファイルへの 遷移を指定しています。利用可能な実行モードについて、詳しくは 20.8項 「実行モード」 をお読みください。

13

名前付きのプロファイル遷移を指定しています。グローバルスコープにある bin_generic というプロファイルへの遷移を指定しています。詳しくは 20.8.7項 「名前付きプロファイル遷移」 をお読みください。

14

ここではローカルプロファイル /usr/bin/foobar を宣言 しています。

15

このセクションでは ハット と呼ばれる、アプリケーションの サブプロファイルを読み込む指定を行なっています。 AppArmor のハット変更機能 について、詳しくは 第24章 ハット変更を利用した Web アプリケーションのプロファイル作成 をお読みください。

プログラムに対してプロファイルが作成されると、プログラムはプロファイルに 書かれたファイルやモード、 POSIX ケーパビリティでのアクセスだけが許可される ようになります。これらの制限は Linux に元から備わっているアクセス制御機能に 追加される形で行なわれます。

例:  たとえばケーパビリティ CAP_CHOWN を利用した処理を 行なう場合、通常の Linux アクセス制御における CAP_CHOWN の権限 (通常は root) と、プロファイル内での chown 許可の両方が必要になります。同様に、プログラムが /foo/bar ファイルに書き込むには、ファイルのパーミッションで指定されたアクセス許可 (それぞれ chmodchown のマニュアルページをお読みください) が必要になるほか、それに加えてプロファイル内に /foo/bar w が書かれている必要があります。

AppArmor のルールに対する違反情報は、 audit パッケージがインストールされている場合は /var/log/audit/audit.log ファイルに、インストールされていない場合は /var/log/messages ファイルにそれぞれ書き込まれます。多くの場合、 AppArmor のルールは攻撃に 必要なファイルへのアクセスが禁止されることによって防ぐことができるほか、 少なくとも AppArmor の制限は AppArmor が許可するファイルにしかアクセスさせない 仕組みであるため、ダメージを軽減することができます。

20.2. プロファイルの種類

AppArmor では 4 種類のプロファイルが用意されています。それぞれ標準プロファイル、 独立プロファイル、ローカルプロファイル、ハットの 4 つです。標準プロファイルと 独立プロファイルは単独で動作するプロファイルで、それぞれ /etc/apparmor.d/ ディレクトリ内に配置されます。ローカル プロファイルとハットは、親となるプロファイルに含まれる形で存在するもので、 アプリケーション内の特定処理について、より厳しい制限や代替の制限を実施する ために使用します。

20.2.1. 標準プロファイル

既定の AppArmor プロファイルは指定した名前のプログラムに対して適用されるもの であるため、プロファイル名は制限を行なうアプリケーションに対するパスを 指定しなければなりません。

/usr/bin/foo {
...
}

このプロファイルは、制限を受けていないプロセスが /usr/bin/foo を実行すると、自動的に使用されます。

20.2.2. 独立プロファイル

独立プロファイルは、プロファイル名がファイルシステムのパス名では書かれて いないプロファイルのことで、これにより自動ではアプリケーションに割り当て られることがありません。独立プロファイルの名前は profile というキーワードで始まります。プロファイル名は自由に命名することができますが、 下記の制限に従う必要があります: 名前は :. の文字で始まってはならないこと。名前に空白を含む場合は、 引用符を付けて記すこと。名前が / で始まる場合は 標準プロファイルとして扱われること。そのため、下記に示す 2 種類の プロファイルは、同じ意味になります:

profile /usr/bin/foo {
...
}
/usr/bin/foo {
...
}

独立プロファイルは自動では使用されることがありませんし、 px のルールを介して遷移することもありません。独立 プロファイルを使用するには、名前付きプロファイル遷移 (詳しくは 20.8.7項 「名前付きプロファイル遷移」 をお読み ください) または change_profile ルール (詳しくは 20.2.5項 「ルール変更」 をお読みください) を使用する必要があります。

独立プロファイルは、通常システム全体のプロファイルでは制限できないような システムユーティリティ (たとえば /bin/bash など) に対して、特殊なプロファイルを設定する際に使用します。また、役割やユーザを 制限する際にも使用することができます。

20.2.3. ローカルプロファイル

ローカルプロファイルは、制限下にあるアプリケーションから起動するユーティリティ プログラムに対して、特殊な制限を行なうための便利な方法です。標準プロファイル のような形でプロファイルを指定するものの、それらの制限は親となるプロファイルに 組み込まれて動作します。また profile というキーワードを 付けるのも特徴です:

/parent/profile {
   ...
   profile local/profile {
      ...
   }
}

ローカルプロファイルへの遷移を行なうには、 cx (詳しくは 20.8.2項 「独立ローカルプロファイル実行モード (cx)」 をお読みください) または名前付きプロファイル遷移 (詳しくは 20.8.7項 「名前付きプロファイル遷移」 をお読みください) を使用します。

20.2.4. ハット

AppArmor の "ハット" とは、ローカルプロファイルに対していくつかの制限を付けた もので、それらへの遷移時に change_hat と呼ばれる間接的な ルールを使用するものです。詳しくは 第24章 ハット変更を利用した Web アプリケーションのプロファイル作成 をお読みください。

20.2.5. ルール変更

AppArmor では change_hat (ハット変更) と change_profile (プロファイル変更) というルールが用意されていて、これらは領域の遷移を制御するのに使用します。 change_hat はプロファイル内でハットを定義することで 指定するもの、 change_profile ルールは他のプロファイルを 参照する際に使用し、 change_profile というキーワードで 書き始めます:

change_profile /usr/bin/foobar,

change_hatchange_profile のいずれ ともアプリケーション主導のプロファイル遷移機能を提供するもので、個別の アプリケーションを立ち上げたりする必要はありません。 change_profile は、既に読み込まれている任意のプロファイルから一方向の遷移機能を提供する のに対して、 change_hat は親子型で復帰可能な遷移機能を 提供し、アプリケーションが親のプロファイルから子のハットに遷移した後、 正しい機密鍵が提供されていれば、後から親のプロファイルに戻ってくることが できるようになっています。

change_profile はアプリケーションの設定段階では信頼して おき、あとから権限レベルを落としたいような場合にベストな選択です。起動 フェーズでマップされているか、もしくは開いている任意のリソースは、プロファイル 変更が発生しても変わらずアクセス可能ですが、新しいプロファイルではリソース を開く際の制限を規定することになるほか、切り替え前から開いていたいくつかの リソースを制限することも行ないます。特にメモリ資源については、機能設定や ファイルリソースが制限されていても (それらがメモリマップ型のものでない 限り) 、以前と変わらずアクセスできるようになります。

change_hat は対象のアプリケーションを仮想マシンで動作 させるような場合や、アプリケーション資源に対する直接アクセスを提供しない ようなインタプリタ (たとえば mod_php など) を動作させる ような場合にベストな選択です。 change_hat はアプリケーション のメモリ内に戻り用の機密鍵を保存するので、制限された権限のもとではメモリへの 直接アクセスを行なうことができなくなります。ファイルアクセスについても、 ハットは閉じられていないファイルハンドルに対して制限を行なうことができるので、 同様に適切に区切ることができます。なお、アプリケーションが何らかのバッファ 処理を行なっていたり、バッファリング機能のあるファイルアクセス機能を提供 していたりするような場合は、これらのバッファリングされたファイルへのアクセスは カーネル側では検知できず、新しいプロファイルでは制限できないことに注意して ください。

[Warning]領域遷移の安全性について

change_hatchange_profile の 領域遷移は、 exec を利用した領域遷移ほど安全性が高くないことに注意して ください。これは、これらの領域遷移はメモリマッピングに対して作用することが できないほか、既に開いているリソースを閉じることもできないためです。

20.3. #include ステートメント

#include ステートメントは他の AppArmor プロファイルにある 内容を引き出すためのディレクティブで、プロファイルの単純化のために使用します。 #include ファイルではプログラムに対するアクセス許可を 取り出すもので、これを使用すると、他のプログラムでも同様に設定する必要の ある共通的なアクセス許可をまとめることができます。これにより、プロファイル 全体のサイズを小さくすることにもつながります。

既定では AppArmor は、 #include に書かれたファイルに対して /etc/apparmor.d のパスを設定します。つまり、取り込む #include で取り込むファイルがあれば、それを /etc/apparmor.d 内にあると期待する意味になります。 他のプロファイルステートメントとは異なり (C 言語のプログラムのように) 、 #include の行末はセミコロンで終わることはありません。

お使いのアプリケーションのプロファイル作業を支援する目的で、 AppArmor では #include に対して 3 種類の分類を用意しています。それぞれ アブストラクトとプログラムチャンク、チューナブルと呼ばれます。

20.3.1. アブストラクト (概要)

アブストラクトは一般的なアプリケーション処理を #include でまとめたものを指します。これらの処理には、認証機構へのアクセスやネーム サービスへのアクセス、一般的なグラフィック環境の使用やシステムアカウンティング などの処理が含まれます。これらアブストラクト内に一覧表示されているファイルは、 いずれも特定の処理に固有のものです。アブストラクトのうちの 1 つを必要とする プログラムでは、通常は他のアブストラクトファイルに書かれた他のファイルへの アクセスも必要となります (ローカル側の設定のほか、プログラムの要件に依存します) 。 アブストラクトは /etc/apparmor.d/abstractions 内に配置されて います。

20.3.2. プログラムチャンク

プログラムチャンクのディレクトリ (/etc/apparmor.d/program-chunks) には、プログラムスイート固有の複数のプロファイル部品 (チャンク) が含まれて いて、スイートの外側では有益ではないものになっています。そのため、プロファイル ウイザード (aa-logprof や aa-genprof) などから、この中にあるプロファイルの使用は提案されることはありません。現時点では postfix プログラムスイート向けのプログラムチャンクのみ利用できます。

20.3.3. チューナブル

チューナブル (/etc/apparmor.d/tunables) のディレクトリ には、いくつかのグローバル変数定義が書かれています。プロファイル内で使用する 場合、これらの変数はプロファイル全体を変更することなく値を変更できる仕組みに なっています。すべてのプロファイルから利用できるチューナブル定義は、 /etc/apparmor.d/tunables/global に配置します。

20.4. 機能項目 (POSIX.1e)

機能項目とは、単純に POSIX.1e で規定されている ケーパビリティ を設定するためのものです。詳しくは capabilities(7) のマニュアルページをお読みください。

20.5. ネットワークアクセス制御

AppArmor では、アドレスの種類やファミリを利用して、ネットワークアクセスを 制御することができます。下記にはネットワークアクセスルールの文法を 示します:

network [[<domain>1][<type2>][<protocol3>]]

1

サポートされるネットワーク領域: inet, ax25, ipx, appletalk, netrom, bridge, x25, inet6, rose, netbeui, security, key, packet, ash, econet, atmsvc, sna, irda, pppox, wanpipe, bluetooth

2

サポートされるネットワークタイプ: stream, dgram, seqpacket, rdm, raw, packet

3

サポートされるプロトコル: tcp, udp, icmp

なお、 AppArmor ツールはファミリとタイプの仕様のみに対応しています。また、 AppArmor のモジュールは access denied (アクセスが拒否されました) のメッセージで network ドメイン タイプ のメッセージのみを出力します。 これらはプロファイルの生成ツールである YaST とコマンドラインの両方で 出力させることができます。

下記では、 AppArmor のプロファイルで使用されるネットワーク関連のルールについて、 例を示しています。ただし、最後の 2 つのルールの文法は、現時点では AppArmor ツールで対応していないことに注意してください。

network1,
network inet2,
network inet63,
network inet stream4,
network inet tcp5,
network tcp6, 

1

すべてのネットワーク処理を許可します。ドメインやタイプ、プロトコルに 対して、制限はありません。

2

一般的な IPv4 ネットワーク処理を許可します。

3

一般的な IPv6 ネットワーク処理を許可します。

4

IPv4 の TCP ネットワーク処理を許可します。

5

IPv4 の TCP ネットワーク処理を許可します。上と同じ意味です。

6

IPv4, IPv6 両方の TCP ネットワーク処理を許可します。

20.6. パスとグロブ

AppArmor ではディレクトリのパス名とファイルのパス名を明示的に区別します。 ディレクトリパスを指定する場合は、末尾に / を付けて 明示的に区別してください:

/some/random/example/* r

/some/random/example ディレクトリ内に あるファイルに対して、読み込みアクセスを許可します。

/some/random/example/ r

ディレクトリに対してのみ読み込みアクセスを許可します。

/some/**/ r

/some ディレクトリ以下の任意のサブ ディレクトリに対して、読み込みアクセスを許可します。

/some/random/example/** r

/some/random/example 以下にある 任意のファイルやディレクトリに対して、読み込みアクセスを 許可します。

/some/random/example/**[^/] r

/some/random/example ディレクトリ以下に ある任意のファイルに対して、読み込みアクセスを許可します。 ディレクトリについては明示的に除外 ([^/]) しています。

グロブ (または正規表現のマッチング) は、ワイルドカードを利用してディレクトリ パスを修正し、複数のファイルやサブディレクトリをまとめて指定したい場合に 使用します。ファイルリソースの指定では、 csh, bash, zsh などの有名なシェルで 利用できるグロブ文法を利用できます。

*

/ を除く、任意の長さの文字列に置き換えることができます。

例: ファイルパス要素の指定などに使用します。

**

/ を含む、任意の長さの文字列に置き換えることができます。

例: ディレクトリ全体を含む、パス要素の任意箇所をまとめて表記できます。

?

/ を除く、任意の 1 文字に置き換えることができます。

[abc]

a, b, c のうちの、いずれか 1 文字に置き換えることができます。

例: /home[01]/*/.plan というルールがあった場合、 /home0/home1 の両方の ディレクトリ以下にある .plan ファイルが該当する ことになります。

[a-c]

a, b, c のうちの、いずれか 1 文字に置き換えることができます。

{ab,cd}

ab または cd のどちらかに 置き換えることができます。

例: /{usr,www}/pages/** というルールがあった場合、 /usr/pages/www/pages の両方のディレクトリ以下にある Web ページにアクセスを許可する意味に なります。

[ ^a ]

a を除く任意の 1 文字に置き換えることができます。

20.6.1. プロファイル内での変数の使用

AppArmor では、プロファイル内でパスを保持するのに変数を使用することができます。 グローバル変数はお使いのプロファイルに対して可搬性を与えるのに、ローカル 変数はパスに対するショートカットとして使用できます。

グローバル変数が便利になる一例として、ユーザのホームディレクトリが 異なる場所にマウントされるネットワークシナリオを考えてみます。影響する すべてのプロファイルに対してホームディレクトリのホームディレクトリを 書き換える代わりに、変数の値だけを書き換えれば作業が終わります。 グローバル変数は /etc/apparmor.d/tunables ディレクトリ以下で定義し、 #include ステートメント 経由で利用します。この使用例 (@{HOME}@{HOMEDIRS}) での変数定義は、 /etc/apparmor.d/tunables/home ファイル内に 書かれています。

対して、ローカル変数はプロファイルの冒頭で定義します。これはたとえば、 chroot 環境下のパスに対して、ベースを設定する際に便利です:

@{CHROOT_BASE}=/tmp/foo
/sbin/syslog-ng {
...
# chrooted applications
@{CHROOT_BASE}/var/lib/*/dev/log w,
@{CHROOT_BASE}/var/log/** w,
...
}
[Note]

現在の AppArmor ツールでは、変数は手作業でのプロファイル編集および管理でのみ 使用することができます。

20.6.2. 別名ルール

別名ルールは、プロファイルパスをサイト固有のレイアウトにマッピングする ための代替手段です。変数を使用してパスの書き換えを行なう方法もありますが、 こちらは変数を値に置き換えた後に作用します:

alias /home/ -> /mnt/users/
[Note]

現在の AppArmor ツールでは、変数は手作業でのプロファイル編集および管理でのみ 使用することができます。また、無効化するとルールが適用されなくなります。 別名ルールの定義は、 /etc/apparmor.d/tunables/alias ファイルを編集して行ないます。

20.7. ファイルのアクセス許可とアクセスモード

ファイルのアクセス許可は、下記のモードの組み合わせで表現します:

r

読み込みモード

w

書き込みモード (a モードとは相互に排他関係)

a

追記モード (w モードとは相互に排他関係)

k

ファイルロック (施錠) モード

l

リンクモード

link ファイル -> 宛先

リンク対ルール (他のアクセスモードとは同時に指定できません)

20.7.1. 読み込みモード (r)

プログラムに対して、特定のリソースへの読み込みアクセスを許可します。読み込み アクセスは、シェルスクリプトやその他のインタプリタ型言語を利用する場合に 必要となるほか、実行中のプロセスがコアダンプを出力できるかどうかを判断する 際にも必要となります。

20.7.2. 書き込みモード (w)

プログラムに対して、特定のリソースへの書き込みアクセスを許可します。 ファイルをアンリンク (削除) する場合、この許可が必要となります。

20.7.3. 追記モード (a)

プログラムに対して、特定のファイルへの追記を許可します。 w モードとは異なり、追記モードではデータの上書きやファイル名の変更、ファイルの削除を 行なうことができません。追記のアクセス許可は一般に、ログファイルへの書き込み 許可が必要なアプリケーションに対して付与されるもので、既存のログ情報を 操作させたくない場合に設定します。追記のアクセス許可は単純に書き込み モードのサブセットであるため、 wa の許可フラグを同時に指定することはできません (相互に排他の関係です) 。

20.7.4. ファイルロック (施錠) モード (k)

アプリケーションがロック (施錠) を行なうことができるようにします。 AppArmor の従来バージョンでは、アプリケーションから特定のリソースへアクセスする許可が あれば、ロックは特に何もすることなく許可されてきました。個別のファイルロック モードを使用することで、 AppArmor はロックを行なう必要のあるファイルに対してのみ ロックを許可し、サービス拒否攻撃 (DoS) のような状況に陥らないようにしています。

20.7.5. リンクモード (l)

リンクモードはハードリンクへのアクセスを制御するものです。リンクを作成すると、 リンク先のファイルと作成したリンクは同じアクセス許可を持つことになります (ただし、リンク先でリンクアクセスの許可が必要になることはありません) 。

20.7.6. リンク対

リンクモードは、任意のファイルに対してリンクを作成する許可を与えるもので、 リンクはリンク先のアクセス許可に対するサブセットの形になります (アクセス 許可テストのサブセット) 。リンク対では、リンク元とリンク先を指定すること で、どのような形でハードリンクの作成を許可するのかを制御することができます。 リンク対ルールは既定では、標準のリンク許可モードが必要とするようなアクセス 許可テストのサブセットを実施しません。このテストを強制するには、 subset キーワードを使用します。それぞれ下記に示す ルールは等価な意味を持ちます:

/link    l,
link subset /link -> /**,
[Note]

現時点では、リンク対ルールは YaST やコマンドラインツールで利用することは できません。これらを使用する際は、プロファイルを手作業で編集してお使い ください。リンク対ルールのあるプロファイルでも、これらのツールを利用した 更新であれば問題なく動作します。これは、リンク対ルールについてはツール側で 一切処理されず、そのままにされるためです。

20.7.7. 所有者条件ルール

ファイルルールを拡張して、対象のファイルに対して所有者であった場合 (fsuid がファイルの uid と一致した場合) のルールを設定することができます。これを 設定するには、ルールの前に owner というキーワードを設定 します。所有者条件ルールは通常のファイルルールとして動作します。

owner /home/*/** rw

リンクルールと所有者条件ルールを同時に利用すると、所有者の確認はリンク先と なるファイルに対して実施され、リンクを行なうには、リンク先のファイルに対して 所有者でなければならなくなります。

[Note]通常のファイルルールとの関係性について

所有者条件ルールは、通常のファイルルールに対するサブセットとして扱われます。 通常のファイルルールが所有者条件ルールと重複すると、結果として適用される ルールは通常のファイルルールと同じものになります。

20.7.8. 拒否ルール

拒否ルールは通知を行なう拒否を設定することができるほか、通知を行なわない 拒否を設定することもできます。プロファイル生成ツールでは、拒否ルールの 取り扱いとして既知の拒否かどうかを尋ねることはありません。このような拒否 を設定したい場合は、拒否時の監査ルールについても表示されることはなく、 ログファイルの肥大化を防いでいます。このような動作がお望みのものでない 場合は、拒否項目に対して audit というキーワードを追加 してください。

拒否ルールは、許可ルールと混在させて使用することもできます。これにより、 幅の広い許可ルールを設定しておいて、その中から部分的に許可されないファイル だけを除外するような使い方ができます。拒否ルールは所有者ルールとも混在させ、 自分自身が所有するファイルに対して、アクセスを拒否させることができます。 たとえば下記の例では、ユーザのディレクトリにあるすべてのファイルに対して 読み書きアクセスを許可するが、 .ssh/ 以下にあるファイルに対しては例外的に アクセスを拒否するルールです:

deny /home/*/.ssh/** w,
/home/*/** rw,

拒否ルールを多用すると、プロファイルの動作を理解するのが難しくなってしまう ことから、お勧めできません。ただし、拒否ルールを賢く使用することで、 プロファイルを単純化することができます。そのため、ツール類では特定のファイル に対する拒否ルールのみを生成し、グロブを利用した拒否ルールは作成しないように なっています。グロブを利用して拒否ルールを記述したい場合は、手作業でプロファイル を編集し、設定してください。これは、拒否ルールについてはツール側で一切処理 されず、そのままにされるためです。

20.8. 実行モード

実行モードは、名前付きプロファイル遷移とも呼ばれ、下記のモードが含まれます:

px

独立プロファイル実行モード

cx

独立ローカルプロファイル実行モード

ux

無制限実行モード

ix

継承実行モード

m

mmap(2) での PROT_EXEC の許可

20.8.1. 独立プロファイル実行モード (px)

このモードは AppArmor の領域遷移の際、実行中のリソースに対して独立した セキュリティプロファイルを必要とします。プロファイルが定義されていない 場合は、アクセスが拒否されます。

[Warning]独立プロファイル実行モードの使用について

pxLD_PRELOAD のような環境変数を 取り除く処理は行ないません。そのため、呼び出し側の領域は呼び出された 領域からの影響を大きく受けることになります。

なお、 Ux, ux, Px, ix とはそれぞれ互換性がありません。

20.8.2. 独立ローカルプロファイル実行モード (cx)

px のようにグローバルのプロファイルセットを検索する 代わりに、 cx では現在のプロファイルが属するローカル プロファイルのみを検索対象とします。このプロファイル遷移は、ヘルパー アプリケーション向けに代替プロファイルを設定するのに使用することができます。

[Note]独立ローカルプロファイル実行モード (cx) の制限について

現時点では cx の遷移はトップレベルのプロファイルに限定されていて、ハットや 子プロファイル内で使用することはできません。この制限は将来取り除かれる予定 です。

Ux, ux, Px, px, Cx, ix とは それぞれ互換性がありません。

20.8.3. 無制限実行モード (ux)

プログラムに対して、 AppArmor プロファイルを全く適用せずにリソースを 実行できるようにします。このモードは、制限を受けているプログラムが コンピュータの再起動など、特権操作を必要となる場合に便利な機能です。 他の実行ファイル内で特権付きのセクションを用意して、そこに対して無制限の 実行権利を与えると、すべての制限付きプロセスに対して設定されていた、 必須の制限を迂回することができるようになります。制限内容について、 詳しくは apparmor(7) のマニュアルページを お読みください。

[Warning]無制限実行モード (ux) の使用について

ux は特別な理由がある場合にのみ利用してください。 これにより、子プロセスが AppArmor の保護無しで動作することになってしまいます。 また、 uxLD_PRELOAD のような環境 変数を取り除く処理も行ないません。そのため、呼び出し側の領域は呼び出された 領域からの影響を大きく受けることになります。さらに、このモードは無制限 での実行をどうしても必要とする状況で、 LD_PRELOAD の環境 変数を使用しなければならない場合に限って使用してください。このモードを 使用したプロファイルは、ほとんどセキュリティが担保されないため、ご自身の 責任範囲のもとでご利用ください。

このモードは、 Ux, px, Px, ix とそれぞれ互換性がありません。

20.8.4. クリーン実行モード

クリーン実行モードは指定した名前のプログラムを px, cx, ux の各モードで実行できるように するためのものですが、 AppArmor が Linux カーネルの機能である unsafe_exec ルーチンを呼び出す仕組みになっていて、 setuid プログラムを実行するときのように環境変数を取り除く処理を行ないます。 クリーン実行モードはそれぞれ大文字 (Px, Cx, Ux) で表わします。 setuid, setgid での環境変数の取り除きについて、詳しくは ld.so(8) の マニュアルページをお読みください。

20.8.5. 継承実行モード (ix)

ix モードは、プロファイルが用意されているプログラムが 特定の名前のプログラムを実行する際、 execve(2) による 通常の AppArmor 領域遷移を阻害するためのものです。通常の領域遷移の代わりに、 実行されたリソースは現在のプロファイルを継承します。

このモードは、制限付きのプログラムが他の制限付きプログラムを呼び出す際、 呼び出し先のプロファイルの許可を得たり、現在のプロファイルの許可を失ったり することなく実行する必要がある場合に、有用なモードです。 ix での実行は特権を変更することはないので、環境変数を取り除く機能は用意されて いません。

それぞれ cx, ux, px との互換性がありません。また、 m の機能を包含します。

20.8.6. 実行ファイルのマッピング許可 (m)

このモードは、 mmap(2)PROT_EXEC フラグを介してファイルをメモリ内にマッピングできるようにします。このフラグは 対象のページに対して実行許可を与えるものです。この機能は、いくつかの アーキテクチャで実行不可能なデータページを提供する際に使用されている もので、不正なコードを実行しにくくするために使用します。 AppArmor では、 このモードを ld(1) での無効な -L フラグのほか、 ld.so(8) での無効な LD_PRELOAD, LD_LIBRARY_PATH 設定の効果を 制限するために使用し、正しい振る舞いをするプログラム (または実行不可能な メモリアクセス制御を強制するアーキテクチャでの全プログラム) を制限する のに使用します。

20.8.7. 名前付きプロファイル遷移

既定では、 pxcx (および左記の クリーン実行モード) のプロファイル遷移を行なう際、実行ファイルの名前で プロファイルを探します。名前付きプロファイル遷移では、遷移先のプロファイル 名を指定することができるようになります。これは、複数のバイナリで単一の プロファイルを共有する必要がある場合に便利な機能であるほか、名前以外の 方法で異なるプロファイルに遷移したほうが都合がいい場合に便利です。名前 付きプロファイル遷移は、それぞれ cx, Cx, px, Px と同時に指定することができます。なお、現時点では 1 プロファイルあたり 12 個までの名前付きプロファイル遷移までしか使用できません。

名前付きプロファイル遷移では -> を使用し、移行先の プロファイル名を指定します:

/usr/bin/foo 
{
  /bin/** px -> shared_profile,
  ...
  /usr/*bash cx -> local_profile,
  ...
  profile local_profile 
  {
    ...
  }
}
[Note]通常の遷移と名前付き遷移の違いについて

グロブとともに利用した場合、通常の遷移は 一対多 の関係を 構築することになります。つまり /bin/** px は、 プログラムが実行されている環境に依存して /bin/ping/bin/cat などの遷移を指定することになります。

名前付き遷移の場合は、 多対一 の関係を構築することに なります。つまり、その名前とは関係なく、条件に該当したすべてのプログラムが 指定したプロファイルに遷移することになります。

名前付きプロファイル遷移は、ログでは Nx というモードで 表示されます。また、遷移先のプロファイル名は name2 という項目で表示されます。

20.8.8. プロファイル遷移における継承フォールバック

pxcx の遷移には 強力な 依存関係 が存在していて、指定したプロファイルが存在しない場合は 実行が失敗します。これに対して、継承フォールバックを利用すると、現在の プロファイルが適用された状態のまま実行を続けることができるようになります (つまりプロファイルを継承することになります) 。継承フォールバックを指定 するには、それぞれ cx, Cx, px, Px に対して ix を組み合わせて指定します。これにより、それぞれ cix, Cix, pix, Pix の各モードになります。フォールバックモードは名前付きプロファイル遷移でも 使用することができます。

20.8.9. 実行モードにおける変数設定

Px, Cx, Ux のいずれかの実行モードを選択した場合、子プロセスが環境を引き継ぐ にあたり、下記の環境変数が取り除かれます。その結果、プロファイルに対して Px, Cx, Ux のいずれかの実行モードを設定すると、下記の環境変数に依存して 動作するアプリケーションやプロセスは動作しなくなります:

  • GCONV_PATH

  • GETCONF_DIR

  • HOSTALIASES

  • LD_AUDIT

  • LD_DEBUG

  • LD_DEBUG_OUTPUT

  • LD_DYNAMIC_WEAK

  • LD_LIBRARY_PATH

  • LD_ORIGIN_PATH

  • LD_PRELOAD

  • LD_PROFILE

  • LD_SHOW_AUXV

  • LD_USE_LOAD_BIAS

  • LOCALDOMAIN

  • LOCPATH

  • MALLOC_TRACE

  • NLSPATH

  • RESOLV_HOST_CONF

  • RES_OPTIONS

  • TMPDIR

  • TZDIR

20.9. リソース制限制御

AppArmor では、アプリケーションが使用するリソースについて制限を設定する機能が あります (rlimits や ulimits としても知られているものです) 。既定では AppArmor はアプリケーションの rlimits を制限することはなく、プロファイルに書かれた 制限のみを適用します。リソースの制限について、詳しくは setrlimit(2), ulimit(1), ulimit(3) の各マニュアルページをお読みください。

AppArmor ではシステムの rlimits を制御しますが、通常発生するような追加の監査 機能は提供しません。また、システムが設定した rlimit を上昇させることも できず、 AppArmor ではその時点でのアプリケーションのリソース制限を下降させる ことだけが実施可能です。

これらの値はプロセスの子供に対して継承する仕組みになっているため、子の プロセスで新しいプロファイルに遷移した場合や、子のアプリケーションが無制限の 設定になっていた場合でも、リソース制限が残ることになります。アプリケーションが 新しいプロファイルに遷移した場合は、遷移先のプロファイルでさらなるリソース 制限を設定することも可能です。

AppArmor の rlimits ルールでは、アプリケーションのハードリミットの調停を行ない、 上昇させることもできます。ただし、アプリケーションは、プロファイル内で指定されて いるものよりも、ハードリミットを上げることはできません。ハードリミットを 上げる調停は値の設定として継承されることはないので、いったんアプリケーションが 新しいプロファイルに遷移すると、プロファイル内で指定された制限まで自由に 上げることができるようになります。

AppArmor のリソース制限制御は、アプリケーションのハードリミットと等しいか、 もしくはより小さいソフトリミットに対して、影響を与えることはありません。

AppArmor のハードリミットのルールは、一般的には下記のような書式で記述します:

set rlimit 資源 <= ,

それぞれ 資源 には下記の値を指定します:

cpu

現時点ではサポートされていません

fsize, data, stack, core, rss, as, memlock, msgqueue

バイト単位で指定するか、もしくは K (キロバイト), M (メガバイト), G (ギガバイト) の接尾辞を付けた数値。たとえば下記のようになります:

rlimit data <= 100M,
fsize, nofile, locks, sigpending, nproc*, rtprio

0 以上の整数

nice

-20 から 19 までの値

* nproc のリソース制限はその他のリソース制限とは 異なる方法で処理されます。標準のプロセスリソース制限の代わりに、一時点で 特定のプロファイル下で実行している、最大のプロセス数として制限されます。 いったん制限を超過すると、実行中のプロセス数が減るまでの間、プロファイル 適用下での新規プロセス生成は失敗するようになります。

[Note]

現時点では、プロファイルに対してリソース制限ルールを追加するにあたって、 ツールを利用することはできません。リソース制限ルールを追加するには、テキスト エディタなどを利用して、手作業でプロファイルを編集する必要があります。 リソース制限ルールの書かれたプロファイルをツールで読み込ませて取り扱わせる こともできますが、リソース制限ルールは編集されることも削除されることも ありません。そのため、リソース制限ルールを含むプロファイルでも、ツールで 更新することは可能です。

20.10. 監査ルール

AppArmor では特定のルールをもとに監査を行なう機能に対応していて、特定の条件に 該当した場合、監査ログ内にメッセージを出力することができます。特定のルール で監査メッセージを有効にするには、ルールの前に audit キーワードを指定します:

audit /etc/foo/*        rw,

特定の許可に対して監査だけを行ないたい場合、ルールを 2 つに分割することが できます。下記の例では、ファイルが書き込み用に開かれた場合に監査メッセージが 生成され、読み込み用にひらされた場合には監査メッセージが生成されないルール を示しています:

audit /etc/foo/*  w,
/etc/foo/*        r,
[Note]

監査メッセージは、ファイルに対して読み込みや書き込みが発生するごとに 生成されることはありません。それぞれ読み込みや書き込み用に開いた場合に のみ生成されます。

監査の設定は、所有者条件ルールと組み合わせることもできます。この場合は、 自分自身が所有するファイルにアクセスした場合に監査が生成されることになり ます (現時点では、所有していないファイルに対して監査を生成することは できません):

audit owner /home/*/.ssh/**       rw,

openSUSE セキュリティガイド 13.1