Linux の権限は「このファイルを誰が読んでよいか」に答えます。AppArmor が答えるのは別の問いです。「このプログラムはそもそも何をしてよいのか」。違いは侵入のときに現れます。web shell は Web サーバーのユーザーとして動き、その権限をすべて受け継ぎます——つまりシステムの半分以上への読み取りです。AppArmor のプロファイルはプロセスを仕事に必要なものの一覧に制限し、/etc/shadow を読もうとしたり /bin/bash を起動しようとしたりすれば、ユーザーの権限にかかわらず拒否で終わります。

すでに何が有効か

sudo aa-status

出力は三つの問いに答えます。いくつのプロファイルが読み込まれているか、そのうち enforce と complain のモードはいくつか、そしてプロファイル無しで動いているプロセスはどれか。典型的な Ubuntu では数十のプロファイルがありますが、そのほぼすべてが mantcpdump といった補助的なプログラムのものです。主要なサービス——nginx、Apache、PHP-FPM——はたいてい制限されたものの一覧にありません。

区別しておくべき三つのモード:

  • enforce——ルールが適用され、余計なものはすべて拒否されます;
  • complain——違反はジャーナルに記録されるだけで、何も遮断されません。調整用のモードです;
  • unconfined——プロファイルが無く、プログラムは制限なしで動きます。

aa-status の出力で最も役に立つのは最後の部分です。ネットワークで待ち受けていて何にも制限されていないプロセス。そこから始めるべき一覧です。

ツール

sudo apt install apparmor-utils

このパッケージが無いと、aa-complainaa-enforceaa-logprof の各コマンドはシステムに存在しません。AppArmor 自体は動いていてもです。

サービスを止めずにプロファイルを有効にする方法

順序が根本です。いきなり enforce に切り替えたプロファイルは、高い確率でサービスに必要な何かを拒み、サービスは動かなくなります——たいていは即座にではなく、ファイルのアップロードやメール送信といった珍しい操作で起こります。

正しい順序:

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

そのモードで一週間の作業。珍しい場面もすべて含めてください。バックアップの取得、更新、大きなファイルのアップロード。それから溜まったものを見ていきます。

sudo aa-logprof

このコマンドは記録された違反を順にたどり、それぞれについて許可するかどうかを尋ねます。ここでは注意が要ります。本当にサービスの仕事に属するものだけを許可し、目に入るもの全部ではありません——さもないと何でも許すプロファイルが出来上がり、意味が失われます。

そのうえで初めて:

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

拒否はどこで見るか

すべての違反はカーネルのジャーナルへ入ります。

sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log

二つ目のファイルは auditd が入っていれば存在します——そしてそれがあると記録は目に見えて詳しくなります。拒否の記録はプロファイル名、要求された操作、アクセスされたパスを示します。プロファイルを直すべきか、それとも発火したことを喜ぶべきかを判断するにはそれで十分です。

覚えておく価値のある症状が一つあります。サービスが妙な振る舞いをする——設定が読めない、ディレクトリに書けない、ソケットが開けない——のに、そのサービス自身のログには権限が明らかに正しいのに「permission denied」のエラーが出ている。これはほぼ必ず AppArmor であり、最初にやるべきはカーネルのジャーナルを見ることです。

理論ではなく実務的な対策

PHP-FPM や nginx のプロファイルは、具体的な形で元が取れます。プロセスが制限されていれば、サイトに入り込んだ web shell はシステムファイルを読むことも、シェルを起動することも、許可されたディレクトリの外へ何かを書くこともできません。乗っ取られたサイトはマシン全体へのアクセスに化けることなく、乗っ取られたサイトのままです——そして被害の大半はまさにその移行にあります。

導入の妥当な順序は、まずインターネットに向いているもののプロファイル(Web サーバー、PHP-FPM)、次にデータベース、そして必要に応じて。すべてを一度に有効にする必要はありませんし、万能の出来合いセットもありません。プロファイルはあなたのファイルがどこにあるかに依存します。

定期的に何を確認するか

プロファイルは思っているより頻繁に unconfined へ戻ります。パッケージの更新がプロファイルのファイルを差し替えることがあり、手作業の障害調査はサービスを complain に置き去りにし、新しいサービスはそもそもプロファイル無しでやって来ます。役に立つ数字は二つ。enforce にあるプロファイルの数と、ネットワークに向いていて unconfined のままのプロセスの数です。そのどちらの変化も知る価値があります。一つのページにまとめるとどう見えるかは下のデモで。