餡子付゛録゛

ソフトウェア開発ツールの便利な使い方を紹介。

AppArmorの説明用の実行ファイルと設定

バッファーオーバーラン攻撃でDNSのbindがcore*1を吐いて落ちていたのだが、権限昇格攻撃でサーバー全体が乗っ取られた後であった…と言う前世紀の思い出を聞いた人は多いと思いますが、最近のLinuxには脆弱なサーバーが攻撃されても被害を限定する仕組みLSMがあります。

LSMによる強制アクセス制御 (MAC) をbindに設定していたら、bindがbindユーザーで実行されているときはもちろん、rootユーザーに権限昇格した後でも、ディスクの読み書きやネットワーク制限が有効なので、適切に設定されていれば、サーバー全体を乗っ取るのは困難になります。LSMはSELinuxがその代表的な実装ですが、Ubuntu LinuxはAppArmorが採用されています。試しに設定してみましょう。

日本語の紹介記事は多い*2ので、細かい説明は割愛と言うか、コマンドを並べていきます。

Ubuntu 24は標準ではAppArmorの設定ツールが含まれていないので、追加します。

sudo apt install apparmor-utils

二つの実行ファイルのソースファイルを用意しました。ダウンロードしてコンパイルします。

cd /var/tmp
mkdir AAexample
cd AAexample
wget https://wh.anlyznews.com/src/learn-apparmor.tgz
tar zxvf learn-apparmor.tgz
make

rnw.exeとcrnw.exeができます。rnw.exeは、与えた1番目の引数のファイルの中身を、2番目の引数のファイルにコピーします。crnw.exeは、与えた引数をつけて、rnw.exeを呼び出します。

echo "AppArmor" > a.txt
./rnw.exe a.txt b.txt
./crnw.exe b.txt c.txt

外形的には同じように動きますね。AppArmorの設定を変えてみましょう。

# 今回用意したプロファイルをコピー
sudo cp profiles/var.tmp.AAexample /etc/apparmor.d/
# Daemonにプロファイルを読み込ませる
sudo apparmor_parser -r /etc/apparmor.d/var.tmp.AAexample

sudo service apparmor reloadとしても良いのですが、既存のプロファイルをすべて読み直す必要はないので、apparmor_parserを使いました。

コピーしたファイルvar.tmp.AAexampleの中身は、以下のようになっています。

abi <abi/3.0>,

include <tunables/global>

/var/tmp/AAexample/rnw.exe {
  include <abstractions/base>

  /var/tmp/AAexample/rnw.exe mr,
  /var/tmp/AAexample/*.txt rw,

}

/var/tmp/AAexample/crnw.exe {
  include <abstractions/base>

  /var/tmp/AAexample/crnw.exe mr,
  /etc/ld.so.cache r,
  /var/tmp/AAexample/rnw.exe mrix,
  /usr/bin/dash mrix,
  /var/tmp/AAexample/ r,
  /var/tmp/AAexample/a.txt r,
  /var/tmp/AAexample/b.txt rw,

}

rnw.exeに*.txtへの読み書き権限を与えている一方、crnw.exeにはa.txtの読み込み、b.txtへの読み書きの権限しか与えていません。

なお、aa-genprofと言うツールが用意されており、引数でプログラムを指定して起動すると、セキュリティーログの引数のプログラムの動きから、自動でプロファイルを構成してくれます。最初、aa-genprofで空ファイルを/etc/apparmor.d/以下につくり、aa-complainで強制アクセス制御を警告は出るが規制はオフにして、プログラムを作動させてセキュリティーログをつくり、aa-enforceで規制をオンにするようなことができます。

さて、強制アクセス制御を体感してみましょう。

./rnw.exe a.txt b.txt
./crnw.exe b.txt c.txt

rnw.exeは変わらず、crnw.exeはc.txtが開けないとrnw.exeがエラーになったと思います。

./rnw.exe couldn't open the file: [2] c.txt

子プロセスの強制アクセス制御は、ドメイン遷移の設定なしでは親プロセスの設定を引き継ぎます。rnw.exeを直接呼び出した場合と、crnw.exeからrnw.exeを呼び出した場合で、挙動が変わるわけです。

また、

sudo ./crnw.exe b.txt c.txt

と、root権限で実行しても同様にエラーになります。chmodで設定する所有者による任意アクセス制御(DAC)とは独立した制御であることが分かります。

*1:プログラム異常終了時のメモリーの状態を記録するファイル

*2:「第798回 Ubuntuのセキュリティを支えるAppArmor入門 | gihyo.jp」「第799回 UbuntuでAppArmorのプロファイルを作ってみる | gihyo.jp」などを参考にしました。