AppArmorの使い方を習得するため、簡単なファイルアクセス制御を試してみた。
■ 検証環境
・Ubuntu 12.04LTS (参考資料 Ubuntu documentation : AppArmor)
■ まず、プロファイルのスケルトンを作成する
# aa-genprof /home/user/workspace/test
Writing updated profile for /home/user/workspace/test.
Setting /home/user/workspace/test to complain mode.
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:
http://wiki.apparmor.net/index.php/Profiles
Please start the application to be profiled in
another window and exercise its functionality now.
Once completed, select the "Scan" button 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.
Profiling: /home/user/workspace/test
[(S)can system log for AppArmor events] / (F)inish
← F キーを押す
Setting /home/user/workspace/test to enforce mode.
Reloaded AppArmor profiles in enforce mode.
Please consider contributing your new profile! See
the following wiki page for more information:
http://wiki.apparmor.net/index.php/Profiles
Finished generating profile for /home/user/workspace/test.
/etc/apparmor.d/ ディレクトリにプロファイルの骨格が作成される
# Last Modified: Mon Dec 3 22:23:45 2012
#include <tunables/global>
/home/user/workspace/test {
#include <abstractions/base>
/home/user/workspace/test mr,
}
■ テスト用プログラムを作成し、コンパイル
#include <stdio.h>
#include <stdlib.h>
void main(void){
FILE *fp;
printf("File write test ...\n");
fp = fopen("test.dat", "w");
if(fp == NULL){
printf("file open error\n");
exit(0);
}
fprintf(fp, "test\n");
fclose(fp);
printf("write success\n");
}
このプログラムをコンパイルし、test という実行ファイルを作成
$ gcc test.c -o test
■ AppArmorでテストプログラム用プロファイルを有効化する
# aa-enforce /home/user/workspace/test
Setting /home/user/workspace/test to enforce mode.
# invoke-rc.d apparmor reload
* Reloading AppArmor profiles
Skipping profile in /etc/apparmor.d/disable: usr.bin.firefox
Skipping profile in /etc/apparmor.d/disable: usr.sbin.rsyslogd
[ OK ]
■ テスト用プログラムを実行し、AppArmorで追加すべきルールを見つけ出す
テスト用プログラムを実行し、syslogを観察すると…
# cat /var/log/syslog | grep test
Dec 3 22:43:42 s5350-ubuntu-1204 kernel: [ 6672.074597] type=1400 audit(1354542222.088:696): apparmor="DENIED" operation="open" parent=3138 profile="/home/user/workspace/test" name="/home/user/workspace/test.dat" pid=6954 comm="test" requested_mask="wc" denied_mask="wc" fsuid=1001 ouid=1001
AppArmorで拒否されたファイルアクセスを発見した
■ AppArmorのプロファイルに、ファイル書きこみルールを追加する
# Last Modified: Mon Dec 3 22:23:45 2012
#include <tunables/global>
/home/user/workspace/test {
#include <abstractions/base>
/home/user/workspace/test mr,
/home/user/workspace/test.dat rw,
}
AppArmorのプロファイルを再読みこみさせれば、テスト用プログラムは問題なく動くようになる
ファイルアクセスの許可書式は
短い形式 | 長い形式 | 許可内容の説明 |
---|---|---|
r | read | ファイルの読み込み許可 |
w | write | ファイルの書き込み許可 |
a | append | ファイルの新規作成と追記許可(O_APPENDでfopenする場合) |
create | ファイルの作成許可 | |
delete | ファイルの削除許可 | |
rename | ファイルの名称変更許可 | |
l | link | ファイルへのリンク作成許可 |
k | lock | ファイルのロック許可 |
x | exec | ファイルの実行許可 |
※writeを指定すれば、create, delete, rename, chmod, chownなどの許可も同時に与えられる。
■ Perlスクリプトの場合
#!/usr/bin/perl
use strict;
use warnings;
print "File write test\n";
open(FH, "> test.dat") or die("file open error\n");
print(FH "test\n") or die("file write error\n");
close(FH);
print "write success\n";
このスクリプトファイル自体に実行許可を与えた場合に、AppArmorで制御が出来るようになる。perl test.pl
のように呼び出した場合は/usr/bin/perlが制御対象で、test.plはperlというプログラムから呼び出される一つのデータファイルに過ぎない。
/usr/bin/perl のプロファイルを作成して、適切に継承関係設定すれば何とかなるのかもしれないが…
$ chmod + test.pl
$ ./test.pl
Apparmorのプロファイルは次のようになる
# Last Modified: Mon Dec 3 20:24:46 2012
#include <tunables/global>
/home/user/workspace/test.pl {
#include <abstractions/base>
#include <abstractions/perl>
/home/user/workspace/test.pl r,
/home/user/workspace/test.dat w,
}
■ 参考資料
・AppArmor (2.3.1) Quick Start
・AppArmor Core Policy Reference