AppArmorのまとめ

Linuxのセキュリティはとにかくややこしい。

古典的なパーミッションやACLは「DAC」という分類に入る。

rootにすら権限を与えない「MAC」という方式もある。ただ、具体的なコマンドとして提供されるわけではなく、AppArmorやSELinuxといったフレームワークで表現されることが多い。フレームワーク化したMACのことをまとめてLSMと呼ぶ

DACとMACは共存できる。そして今回はAppArmorの話。

AppArmorの運用

基本的な操作

AppArmorの有効/無効

有効/無効の状態を確認するにはaa-enableコマンドを使う

$ aa-enabled
yes ・・・有効
  • 無効化(設定を削除する)
    • aa-teardown ・・・現在のプロファイルをアンロードする
    • systemctl disable apparmor ・・・起動時にプロファイルを読み込まない
  • 有効化する
    • systemctl enable apparmor ・・・起動時にプロファイルを読み込む

動作モード

AppArmorはシステム全体に影響を及ぼすため、部分的に無制限にしたり学習モードにしたりできる。

  • unconfined(非制限)モード:何も制限しない
  • enforced(適用)モード:プロファイルで許可されていない処理を行おうとした場合は、エラー扱いにしログに残す
  • complaining(学習)モード:プロファイルで許可されていない処理を行う場合、ログに残すものの、エラー扱いにはしない

動作モードは専用のコマンドで設定する

  • 非制限モード・・・aa-uncomfined プログラムのパス
  • 適用モード・・・aa-enforce プログラムのパス
  • 学習モード・・・aa-complain プログラムのパス

動作モードを確認するにはaa-statusコマンドを使う

$ aa-status
apparmor module is loaded.
113 profiles are loaded.
xxprofiles are in <動作モード> mode

AppArmorの設定

AppArmorの設定はファイルに対する設定とプロセスに対する設定がある。

設定ファイルについて

ファイルパス

通常のプログラムに関する設定は/etc/apparmor.d/にあるが、snapのプロファイルは/var/lib/snapd/apparmor/profiles/にある

/etc/apparmor.d/の中にはいくつかのフォルダがあり、disableフォルダの下にあるプロファイルは読み込まないなどの制御ができる

apparmor.d
├disable ・・・この下のプロファイルは起動時に読み込まれない
├force-complain ・・・この下のシンボリックリンクはcomplainingモードで動作する

設定ファイルの有効化

通常は起動時にプロファイルを読み込むが、設定を変更した場合は特定のプロファイルだけ読み込むことができる。

$ sudo apparmor_parser -r プロファイル

設定ファイルの作り方

aa-genprof

設定ファイルを作る最も簡単なやり方。

「aa-genprof 起動プロセス」を実行すると対話的にプロファイルを作成してくれる方法。一般にはこちらが楽。

complainingで雛形を作る

通常はcomplaining(学習モード)で動作させて、その結果を雛形にしながら設定ファイルを作成する方法。修正はこちらが楽。

作成手順

$ sudo aa-genprof firefox
(対話形式で設定)

$ プロファイルが作成されるので編集する

設定ファイルの書き方

ab i <abi/バージョン>AppArmorのバージョン
include <機能>プロファイルがあるディレクトリ。
<tubables/global>と記載すると必要と思われるディレクトリをすべて読み込んでくれる
サブコマンドのパス {
include <機能>
ファイルパス 権限,
ファイルパス/* 権限,
ファイルパス/** 権限,
:
}
プログラムがファイルに対して実行できる権限を記載する。
/*はディレクトリ直下のファイル。/**は再起的にサブフォルダのファイル。

includeで指定できる機能

<tunables/global>すべてのプロファイルでロードしたほうが良いもの
<abstractions/base>一般的なLinuxコマンドならまず必要になるであろう設定
<abstractions/consoles>標準入出力を使うコマンドに必要な設定
<abstractions/opencl-pocl>OpenCLを使う際に必要な設定

権限で指定できるパーミッション

r読み込み
w書き込み
?x実行
mmmap()
lリンク
kファイルロック

設定の反映と動作確認

  • sudo apparmor_parser -r プロファイル でプロファイルを更新する。
    • もしくはrcapparmor reloadでも読み込める
  • 1つ目のターミナルで$sudo aa-genprof プロセス を実行し、他のターミナルでコマンドを実行する。
  • aa-genprofターミナルでSを入力してスキャンするとエラーが表示されるので、設定を追加していく。

もしくは学習モードにして結果を読み込ませる方法でも良い。この方法はsnapの場合はおそらくうまく機能しない。

$ aa-complain プログラムのパス
$ プログラムを実行
$ aa-logprof プログラムのパス

設定に関するもっと詳細な情報

https://manual.geeko.jp/ja/part.apparmor.html

デバッグの方法

一般的な権限不正はsyslogで確認できる

snapのfirefoxが起動に失敗した際、/var/log/syslogには以下のメッセージが出力されていた。

2025-01-17T21:20:24.403046+09:00 workpc kernel: audit: type=1400 audit(1737116424.401:213): apparmor="DENIED" operation="exec" class="file" profile="/usr/bin/snap" name="/snap/snapd/23545/usr/bin/snap" pid=4352 comm="firefox" requested_mask="x" denied_mask="x" fsuid=1000 ouid=0
apparmorの診断結果。拒否した。
operation="exec"
class="file"
profile="/usr/bin/snap"
name="/snap/snapd/23545/usr/bin/snap"
/usr/bin/snapが/snap/snapd/23545/usr/bin/snapを実行しようとした。
comm="firefox"snapで操作しようとしたコマンドはfirefox
requested_mask="x" denied_mask="x" 要求した権限はxで、拒否された権限はx
fsuid=1000 ouid=0実行しようとしたファイルのfsuid(使用しようとしたユーザー)は1000で、本来のファイルの持ち主のouidは0(root)

対面でデバッグするならaa-genprof

1つの画面でaa-genprofを開いておき、別の画面でコマンドを実行する方法。snapの様に親プロセス(snap)が子プロセス(firefox)を起動するような複雑な動作をする場合はこのやり方が望ましい。

ここではsnapでインストールされたfirefoxを起動する例を紹介する

まずスキャンを始める。プロファイルを編集するためsudoを忘れないこと。

$ sudo aa-genprof /usr/bin/snap
Updating AppArmor profiles in /etc/apparmor.d.

Before you begin, you may wish to check if a
profile already exists for the application you
wish to confine. See the following wiki page for
more information:
https://gitlab.com/apparmor/apparmor/wikis/Profiles

Profiling: /usr/bin/snap

Please start the application to be profiled in
another window and exercise its functionality now.

Once completed, select the "Scan" option below in
order to scan the system logs for AppArmor events.

For each AppArmor event, you will be given the
opportunity to choose whether the access should be
allowed or denied.

[(S)can system log for AppArmor events] / (F)inish

次にfirefoxを起動する。今回は前述のエラーを出して停止している。

この状態でSを押すとエラーログを解析してどう処理すべきか選択できるようになる。

[(S)can system log for AppArmor events] / (F)inish
Reading log entries from /var/log/syslog.

Profile: /usr/bin/snap
Execute: /snap/snapd/23545/usr/bin/snap
Severity: unknown

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish

重要度(Severity)は不明だが何らかの権限不正が起きたようです。この問題をどう扱うかを選択します

Inherit親プロセスのプロファイルを継承して子プロセスを実行する
Child親プロファイル内にある子プロセスのプロファイルを使用する
Profile子プロセスが持つプロファイルを適用する
Named既存の他のプロファイルを指定して適用する
Unconfined子は制限なしで実行されます。これにより、セキュリティ上のリスクが発生する可能性があります。
X ix On子は独自のプロファイルを持つことができますが、独自のプロファイルが存在しない場合は、親のプロファイルをフォールバックとして使用します。
Denyプログラムの起動を拒否する
Abortaa-genprofを強制終了する。これまでの記録は破棄される。
Finishaa-genprofを正常終了する。これまでの記録は保存される。

通常はInheritを選択する。するとこの設定を保存するか聞いてくるのでSで保存する。

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
Complain-mode changes:
Enforce-mode changes:

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

[1 - /usr/bin/snap]
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t

するとプロファイルを編集して再びスキャンモードに戻る。

Allow Deny Igunore といった選択肢が出る場合もあるが、基本的にはAllowを選択する。

これを目的のプログラムが起動するまで繰り返す。


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です