monoの開発ブログ

もっと気軽にLinux Security Modulesを作りたい

前回の記事では、一応Linux Security Modules(LSM)を作ることができたわけですが、ちょっと遊んでみたいだけなにのカーネルを置き換えるのは若干(というかかなり)大げさですし、何より再構築に絶望的なほど時間が掛かるという問題があります。

そこで、今回はカーネルに変更を加えることなくLoadable Kernel Module(LKM)の仕組みを利用してLSM相当の機能を実現してみます。といっても、LSMのAPIはLKMからは利用できないようになっているため、正規の方法では実現できません。この壁を突破するのが、AKARIです。

AKARIは、TOMOYO Linuxとほぼ同等の強制アクセス制御をLKMとして実装したものです。カーネルにパッチを当てたりコードを組み込んだりする必要がないため、気軽に導入できるという特徴があります。先述のとおりLSM相当の機能をLKMとして利用することは正規の方法では不可能ですが、AKARIでは、LSMがフックしたいイベントのコールバック関数を指定するのに用いられるsecurity_operations構造体のメンバを上書きすることで、LKM側の関数でイベントを捕捉して独自の処理を追加できるようにしています。これによって冒頭で述べたカーネルに手を加えなければならない、再構築に時間がかかるという問題が解消されるほか、通常のLSMでは不可能な複数のセキュリティモジュールの共存を実現することができるようになります。

良い点ばかりを挙げましたが、もちろん問題もあります。それは、この手法が正規のものではないということです。今はいくつかの環境で動作していますが、動作しない環境があるかもしれないですし、今動いていたとしても将来的にサポートされるかどうかは分かりません。

とはいえ、気軽にLSM(相当の働きをするもの)を作ってみたいという今回の目的に合致しているのは確かですし、将来のことを気にしなければならないほどのものを作るわけではないので、とりあえずAKARIベースで進めてみようと思います。

インストール

AKARIのコードをベースにしてフックに最低限必要な部分だけを抜き出したサンプルを用意してみました。 このサンプルではinode_mkdirイベントをフックしてディレクトリが作成される時にログを生成するようにしています。

動作確認はUbuntu 11.04 (2.6.38-8)で行いました。

なお、AKARIのライセンスがGPLv2であるため、この記事中のコードもすべてGPLv2です。他の記事とは扱いが異なるので注意してください。

version=`uname -r`
sudo apt-get install linux-headers-$version
cd /usr/src/linux-headers-$version
sudo git clone https://github.com/mono0x/loadable-security-module.git foobar
sudo make SUBDIRS=$PWD/foobar modules
sudo make SUBDIRS=$PWD/foobar modules_install
sudo depmod $version

lsm.cがプログラム本体です。割と長いですが、ほとんどはAKARI由来のフックを掛けるために必要な処理で、フックしたイベントに対して実際に処理を行なっているのはccs_inode_mkdir関数のみです。基本的には、イベントを処理する関数を作成してccs_update_security_ops関数に1行追記すればイベントをフックすることができます。

今回作成したccs_inode_mkdir関数はディレクトリが作成される時に呼び出され、printk関数でログを出力した後オリジナルのinode_mkdir関数を呼び出しています。

処理の詳細を追いたいという方はccs_find_security_ops関数あたりを読み進めてみてください。

なお、このサンプルを作るにあたってAKARIのアクセス制御を実現している部分のコードを削る作業を行ったのですが、 ここに載せているコードではそれらを削っており、自分の環境で動くことしか確認していません。真面目にセキュリティモジュールを作ろうとしている方は直接AKARIのコードを参照してください。

動作確認

modprobeでfoobarモジュールを組み込み、その状態で適当にディレクトリを作成すると、/var/log/syslogにログが書き込まれます。

sudo modprobe foobar
tail -f /var/log/syslog

問題点

AKARIにはOS起動時に自動的にモジュールを組み込む機能があるのですが、適当に真似してみてもうまくいかなかったので今回は紹介できませんでした。

おわりに

AKARIの手法を用いることで、Linuxのセキュリティ周りをいじることに対するハードルはかなり低くなり、気軽にLSMを書いて実行できるようになりました。みなさんもいろいろなLSMを作って遊んでみてください!