June 24, 2011
Linuxのセキュリティ周りを拡張するフレームワークであるLinux Security Modules(LSM)を作ってみます。LSMはSELinuxやTOMOYO Linuxの実装に使われており、LSMを利用することでシステムのさまざまな部分をフックしてアクセス制御などの処理を実現することができるようになります。
とりあえず以下の記事にあったLSMのスケルトンを実際にUbuntuに組み込んでみたのでメモしておきます。
Writing a Skeleton Linux Security Module | recluze
必要なツールとカーネルのソースコードをインストールしておきます。
cd /usr/src
sudo apt-get install -y build-essential libncurses-dev ncurses-dev kernel-package linux-source-2.6.38
sudo tar vxf linux-source.2.6.38.tar.bz2
うちの環境(Ubuntu 11.04)ではこのままだとエラーになってしまったため、こちらを参考に対処。
sudo vi /usr/src/linux-source-2.6.38/ubuntu/omnibook/Makefile
以下のように修正。
...
# 追加
PWD = $(shell pwd)
ifeq ($(KERNELRELEASE),)
...
# 削除
# PWD = $(shell pwd)
...
LSMのスケルトンをダウンロードしてきてカーネルに組み込みます。
wget http://csrdu.org/pub/nauman/files/blabbermouth.tar.gz
tar vxf blabbermouth.tar.gz
sudo mv lsm-tut-files/blabbermouth /usr/src/linux-source-2.6.38/security
cd /usr/src/linux-source-2.6.38/security
sudo vi blabbermouth/blabbermouth.c
そのままだと大量のログを吐いて操作不能になるのとか、記述が古かったりするのを修正。
...
static int blabbermouth_file_permission(struct file *file, int mask)
{
/* printk("blabbermouth: file_permission called\n"); */
return 0;
}
...
static int __init blabbermouth_init(void) {
...
}
security_initcall(blabbermouth_init);
MakefileとKconfigに追加したLSMを含める設定を追記します。
cd /usr/src/linux-source-2.6.38/security
sudo vi Makefile
sudo vi Kconfig
...
obj-$(CONFIG_KEYS) += keys/
subdir-$(CONFIG_SECURITY_SELINUX) += selinux
subdir-$(CONFIG_SECURITY_SMACK) += smack
subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
subdir-$(CONFIG_SECURITY_YAMA) += yama
# 追加
subdir-$(CONFIG_SECURITY_BLABBERMOUTH) += blabbermouth
...
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
obj-$(CONFIG_AUDIT) += lsm_audit.o
obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
obj-$(CONFIG_SECURITY_YAMA) += yama/built-in.o
# 追加
obj-$(CONFIG_SECURITY_BLABBERMOUTH) += blabbermouth/built-in.o
...
source security/selinux/Kconfig
source security/smack/Kconfig
source security/tomoyo/Kconfig
source security/apparmor/Kconfig
source security/yama/Kconfig
source security/blabbermouth/Kconfig
...
現在利用しているカーネルの設定をもとにLSMを組み込んだカーネルを構築します。make oldconfigを実行すると追加したLSMを有効にするかどうか聞かれるので、yを選択して有効にしてください。
cd /usr/src/linux-source-2.6.38
sudo cp /boot/config-2.6.38-8-generic .config
sudo make oldconfig
sudo make-kpkg --initrd --revision=20110625 kernel_image
cd ..
sudo dpkg -i linux-image-2.6.38.2_20110625_amd64.deb
GRUBの設定を変更して作成したLSMが利用されるようにします。
sudo vi /etc/default/grub
sudo update-grub
以下のように記述。
GRUB_CMDLINE_LINUX="security=blabbermouth"
再起動するとLSMが組み込まれたカーネルで起動します。printk関数で出力したログは/var/log/dmesgに保存されるので、blabbermouth:で始まるログがあることを確認してください。
less /var/log/dmesg
とりあえずLSMを組み込んだカーネルを起動させることには成功したのですが、分からない点がいろいろと。
LSMの初期化を行うblabbermouthinit内でprintk関数を呼び出してもログが残ってくれません。ログレベルをKERNEMERGなどとすると画面上には表示されるので、実行されてはいるみたいですし、他のLSMの出力するログは出力されてるみたいなのですが……。
ドキュメントや他のLSMのソースを眺めていると、どうも初期化時にsecuritymoduleenable関数を呼び出さなければならないようなのですが、今回参考にしたサンプルではそれが行われていませんでした。試しにsecuritymoduleenable関数を呼び出すように書き換えてみたのですが、動作しなくなってしまいました。securitymoduleenable関数のコードを見た感じだと、動作しないほうが正しいような気すらしてしまうのですが、どうなっているんでしょうかね。
LSMを1行いじっただけで30分近く待たされてしまうのはちょっと耐えられません。何かがおかしい気がします。
AKARIを使えばカーネルの再構築をすることなくLSMを実装することができると聞いたので、試してみたいなぁと思っています。