MENU

AppArmorプロファイルでサービスを段階保護する|complain→enforceの移行と拒否ログ解釈手順

サービスの脆弱性を突かれたとき、カーネルレベルで動作を制限するMAC(強制アクセス制御)が最後の防衛線になります。AppArmorはUbuntu・Debian・openSUSE系で標準採用されており、systemdとの統合も進んだことで導入の敷居は大きく下がりました。一方で「プロファイルを有効にしたらサービスが起動しなくなった」という声は今も絶えません。その多くは、complainモードで十分に動作を観察しないままenforceに切り替えたことが原因です。本記事では、complainモードを使ってプロファイルを育て、enforceモードへ安全に移行する手順を、拒否ログの解釈も含めて一通り解説します。

目次

AppArmorが提供する「段階的な権限制限」という考え方

AppArmorはファイルパス・ネットワーク・ケーパビリティ・シグナルといったリソースへのアクセスを、プロセス単位のプロファイルで制御します。SELinuxがラベルベースで複雑な設定を要求するのに対し、AppArmorはパスベースで記述が平易な点が特徴です。

プロファイルには大きく2つの動作モードがあります。complainモードはアクセスを拒否せず、ポリシー違反をログに記録するだけです。enforceモードはポリシー違反を実際に拒否し、必要に応じてプロセスを停止させます。段階的な保護とは、まずcomplainモードでサービスの実際のアクセスパターンを把握し、プロファイルを調整してからenforceに切り替えるという運用フローを指します。

多くのディストリビューションには、NginxやMySQLなどよく使われるデーモン向けのプリセットプロファイルが用意されています。ただし、独自ビルドのバイナリや非標準パスへのログ出力など、環境固有の設定には必ず手を加える必要があります。プリセットをそのままenforceで動かすのは危険で、complainモードで観察してから適用するのが原則です。

complainモードでプロファイルを育てる

初期プロファイルの生成と読み込み

AppArmor関連のツールは apparmor-utils パッケージに含まれています。インストールされていない場合は先に導入します。

sudo apt install apparmor-utils

既存のバイナリから雛形プロファイルを生成するには aa-genprof を使います。引数にはバイナリの絶対パスを指定します。

sudo aa-genprof /usr/sbin/nginx

コマンドを実行するとインタラクティブなプロンプトが起動します。別のターミナルでサービスを実際に動かし、代表的な操作(起動・リクエスト受信・設定リロードなど)を一通り実施します。操作が終わったらプロンプト側で「S(Scan)」を入力すると、その間に記録されたログをもとにルール候補が提示されます。各ルールに「Allow」「Deny」「Glob」などの選択肢が表示されるので、意図に沿って選択していきます。

生成されたプロファイルは /etc/apparmor.d/ 以下に保存されます。初期状態はcomplainモードになっているため、サービスへの影響なくログ収集を続けられます。プロファイルを明示的にcomplainモードで読み込むには次のコマンドを使います。

sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

現在のプロファイル一覧と各モードは aa-status で確認できます。

sudo aa-status

aa-logprofによる拒否ログの解釈

complainモードで一定期間動作させたあと、aa-logprof を使ってログを解析します。このコマンドはシステムログからAppArmor関連のイベントを読み取り、未定義のアクセスをルール候補として対話的に提示します。

sudo aa-logprof

journaldを使う環境では aa-logprof がジャーナルを直接参照できないことがあります。その場合はパイプ経由で渡します。

sudo journalctl -k --since "1 hour ago" | sudo aa-logprof -f /dev/stdin

提示されるルール候補に対しては、以下の点を意識して判断します。

  • そのアクセスがサービスの正常動作に必要か(不要であれば拒否ルールを追加する)
  • グロブパターンが広すぎないか(/tmp/** のような広範な許可は避ける)
  • ネットワークアクセスの許可先が意図したエンドポイントか

enforceモードへの移行手順

complainモードで十分なログ収集と調整が完了したら、enforceモードへの移行を行います。移行前に、直近のcomplainログにまだ未対応のアクセスが残っていないかを確認します。サービス名でフィルタリングすると見落としが減ります。

grep 'apparmor="ALLOWED"' /var/log/syslog | grep nginx

問題がなければenforceモードへ切り替えます。

sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx

切り替えと同時にサービスを再起動し、ログを監視します。

sudo systemctl restart nginx
sudo journalctl -f -k | grep apparmor

apparmor="DENIED" のエントリが現れた場合は、そのアクセスが実際に拒否されています。enforceモードでの拒否はサービスの動作に直接影響するため、迅速な対応が必要です。プロファイルファイルを編集して修正したあとは、次のコマンドでカーネルへ再読み込みさせます。

sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.nginx

拒否ログの詳細解釈と誤検知への対処

enforceモードでの拒否ログは、以下のような形式でカーネルログに記録されます。

audit: type=1400 audit(1234567890.123:456): apparmor="DENIED" operation="open" profile="/usr/sbin/nginx" name="/var/log/nginx/custom.log" pid=12345 comm="nginx" requested_mask="wc" denied_mask="wc" fsuid=33 ouid=0

各フィールドの意味を押さえておくと、対処が速くなります。

  • operation:拒否されたシステムコールの種類(open、connect、signal など)
  • profile:適用されているプロファイルのパス
  • name:アクセスしようとしたリソース(ファイルパスやネットワークアドレスなど)
  • requested_mask:プロセスが要求したアクセス権限(r=読み取り、w=書き込み、c=作成、x=実行)
  • denied_mask:実際に拒否された権限

誤検知への対処は、プロファイルファイルを直接編集してルールを追加します。例えば /var/log/nginx/custom.log への書き込みが拒否されている場合は、プロファイルの該当ブロックに次のような行を追加します。

/var/log/nginx/custom.log rw,

ただし、安易なグロブ許可はプロファイルの保護効果を著しく下げます。/var/log/nginx/*.log rw, 程度の範囲に抑え、/var/log/** rw, のような広すぎるパターンは避けるべきです。ネットワーク接続の拒否については、network tcp, のようなプロトコル単位での許可から始め、必要に応じて接続先を絞っていくアプローチが安全です。

ロールバックと緊急時の対応

enforceモードへの移行後にサービスが正常に動作しなくなった場合、まず一時的にcomplainモードへ戻します。

sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
sudo systemctl restart nginx

より緊急性が高く、特定のプロファイルだけを完全に無効化する必要がある場合は aa-disable を使います。

sudo aa-disable /etc/apparmor.d/usr.sbin.nginx

aa-disable を実行するとプロファイルが /etc/apparmor.d/disable/ にシンボリックリンクされ、再起動後も無効状態が維持されます。再有効化するには aa-enforce または aa-complain を再度実行します。AppArmor全体を停止させるオプションもありますが、システム全体の保護が解除されるため、本当に手詰まりのときの最終手段として位置づけておくのが無難です。

プロファイルをバージョン管理しておくことも重要です。/etc/apparmor.d/ ディレクトリをgitで管理し、変更前にコミットしておくと、差分確認や巻き戻しが容易になります。現場でのトラブル対応時間を大幅に短縮できるため、可能であれば初期段階から習慣化したい運用です。

2026年現行環境での注意点と差分

Ubuntu 24.04 LTS(Noble Numbat)以降、AppArmorはバージョン4.0系に移行しており、プロファイル言語にいくつかの変更が加わっています。特に abi/4.0 ヘッダーの記述が推奨される形式になり、古いプロファイルをそのまま利用すると警告が出ることがあります。既存のプロファイルを引き継ぐ場合は、ファイル先頭の abi 行を確認し、必要であれば更新します。

Debian 12(Bookworm)ではAppArmorがデフォルト有効になり、多くのシステムサービスにプロファイルが付属しています。とりわけ systemd-resolvedcupsavahi-daemon などにはデフォルトプロファイルが当たっているため、カスタム設定を行うとこれらのサービスとの競合が発生するケースがあります。

SnapやFlatpakで配布されるアプリケーションは、AppArmorとは独立したサンドボックス機構を持つことが多く、/etc/apparmor.d/ で管理するプロファイルとは別に動作します。Snapのプロファイルは /var/lib/snapd/apparmor/profiles/ に格納されており、直接編集するのではなく、Snapのインターフェース機能を通じてアクセス権を調整するのが正しいアプローチです。

また、aa-logprof がjournaldと連携する際の動作は、apparmor-utils のバージョンによって挙動が異なります。Ubuntu 24.04では journalctl からのパイプで比較的安定して動作しますが、一部のDebian環境では /var/log/kern.log を明示的に指定する方が確実です。ツールのバージョンを dpkg -l apparmor-utils で確認し、既知のバグがある場合はアップデートを優先します。

コンテナ環境(DockerやLXCなど)でAppArmorを活用する場合、ホスト側のプロファイルがコンテナ内のプロセスにも適用される点を理解しておく必要があります。Dockerはデフォルトで docker-default プロファイルをコンテナに適用しており、カスタムプロファイルを使うには --security-opt apparmor=プロファイル名 オプションで明示的に指定します。コンテナオーケストレーション環境では、この設定をコンテナ定義ファイルに含めることで一貫した保護が実現できます。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

PR・広告

新しいLinuxの教科書 第2版(Amazon)

コマンド操作から基本運用までを手を動かして学べる定番書。記事で触れた技術の土台固めに。

Amazonで見る

※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次