最終回 オリジナルセキュリティモジュールを拡張する
Linuxカーネルには、バージョン2.6から「Linux Security Module」(LSM)というセキュリティフレームワークが導入されています。この連載ではLSMの仕組みを紹介するとともに、これを活用してオリジナルのセキュリティモジュールを作り上げていきます(編集部)
村上 純一
株式会社フォティーンフォティ技術研究所
研究開発部 αUnit シニア・リサーチエンジニア
2008/6/12
第2回「オリジナルセキュリティモジュールの作成」では、 セキュリティモジュールを実装するためのフレームワーク「LSM」を用いて、ネットワーク接続を利用してアクセス制御を行う「Root Connect LSM Module」(以降、Root Connect)を作成しました。ネットワーク上のサーバへの接続を利用してアクセス制御を行い、指定したサーバにアクセス可能な場合にのみroot権限でのコマンド実行を許可するというものです。
今回は、LSMのほかの機能を利用してRoot Connectの機能を拡張していきます。なお、本稿で機能拡張を行ったRoot Connectのソースコードは、こちらからダウンロードできます。
関連記事: | |
Linux Kernel Watch 2006年5月版 「LSM不要論」に揺れるSELinux&AppArmor http://www.atmarkit.co.jp/flinux/rensai/watch2006/watch05b.html |
|
Linux Kernel Watch番外編:セキュリティをやってるやつらは狂っている?! http://www.atmarkit.co.jp/fsecurity/special/103kernelwatch/kernelwatch01.html |
securityfsを活用しよう
securityfsは、カーネル2.6.14で追加されたRAMベースのファイルシステムです。LSMを用いると、securityfsを利用し、ユーザー空間から自身のメモリへアクセスするためのインターフェイスを、ファイルシステム上に作成することができます。ユーザー空間からは、procfsのように、通常のファイルアクセスを介してセキュリティモジュールのメモリにアクセスすることができます。
securityfsは、カーネルソース中のsecurity/inode.cに実装されており、以下の3つのAPIによる非常にシンプルな設計になっています。
struct dentry *securityfs_create_file(const char *name, mode_t mode, |
インターフェイスの実装
では、実際にRoot Connectをベースにして、securityfsを利用した設定情報の取得用インターフェイスを実装してみましょう。
まず、セキュリティモジュールの初期化を行うrootconn_init関数、終了処理を行うrootconn_exit関数のそれぞれで、securityfsの登録および解除の処理を行う必要があります。それぞれの変更点をリスト1に示します。
|
|
リスト1 root_conn.cの変更箇所(1) ※変更箇所は黄色で表記 |
rootconn_init関数の37行目でrootconnfs_register関数を呼び出しています。rootconnfs_register関数は、始めにsecurityfs_create_dir関数を呼び出して、「rootconn」という名前のディレクトリエントリを作成します。
次に、securityfs_create_file関数に作成したディレクトリエントリを引数として渡すことで、ディレクトリ内に「server」という名前のファイルを作成します。
securityfs_create_file関数の第5引数に指定されているrootconn_file_opsは、ユーザー空間からこのファイルにアクセスした際に呼び出されるコールバック関数の関数ポインタ群を含む、file_operations構造体のポインタです。rootconn_file_ops変数の定義をリスト2に示します。
一方のrootconn_exit関数では、関数の先頭でrootconnfs_unregister関数を呼び出しています。rootconnfs_unregister関数は、securityfs_unregister関数をrootconnfs_register関数で作成した「rootconn」ディレクトリ、「server」ファイルそれぞれを引数に呼び出し、削除します。
|
|
リスト2 rootconn_file_ops変数の定義 |
rootconn_files_opsは、readメンバーのみ、read_server_config関数のアドレスで初期化しています。この関数ポインタ(readメンバー)は、名前のとおりユーザー空間のプロセスがreadシステムコールを発行した際に呼び出されます。read_server_config関数をリスト3に示します。
|
|
リスト3 read_server_config関数 |
read_server_config関数は、ファイルオブジェクトのポインタ、ユーザー空間のバッファのポインタ、バッファ長、オフセットが引数として渡されます。今回は、Root Connectをロードした際に指定したサーバのIPアドレス、ポート番号をプロセスに返すため、scnprintf関数を呼び出して、コロン区切りの文字列をローカルバッファに生成しています。
次に、simple_read_from_buffer関数を呼び出して生成した文字列を、ユーザー空間のバッファにコピーします。simple_read_from_buffer関数は、カーネルソース中のfs/libfs.cに実装されており、copy_to_user関数を呼び出すことで、引数に指定されたカーネル空間のメモリ領域の内容をユーザー空間のメモリ領域にコピーします。単純にmemcpy関数を利用していないのは、ユーザー空間のメモリ領域は、スワップアウトを考慮する必要があるからです。
動作確認を行う際は、前回同様、ソースコード(root_conn.c)をsecurity/以下に配置し、カーネルソースのルートディレクトリから以下のコマンドを実行します。ビルド環境、手順の詳細については、前々回、前回を参照ください。
% make security/root_conn.ko |
前回同様、TCP接続が可能な適当なサーバのIPアドレス、ポート番号を引数に指定して、Root Connectをカーネルにロードします。
% sudo modprobe root_conn addr=192.168.1.10 port=1111 |
securityfsは、デフォルトではマウントされないため、以下のコマンドを実行してマウントします。
% sudo mount -t securityfs securityfs /sys/kernel/security |
この状態で、/sys/kernel/security配下にrootconnディレクトリ、またその配下に「server」ファイルが生成されていることが確認できます。「server」ファイルの内容を表示すると、ロード時に指定したパラメータを確認することができます。
% cat /sys/kernel/security/rootconn/server |
第2回へ |
1/2 |
|
||||
|
Linux Squareフォーラム Linux/システム学習関連記事 |
連載:Windowsユーザーに教えるLinuxの常識(全12回) Windowsのセオリーが通用しないLinux。Linux初心者向けに、LinuxというOSの考え方/常識をゼロから伝授! |
|
連載:LFSで作って学ぶLinuxの仕組み(全4回) 管理者(root)は、何をしなければならないのか? 管理に際して検討すべきことは? 管理のための技術とは? など、駆け出し管理者のための考え方や方法論を検討する |
|
連載:Linux管理者への道(全8回) 「Linux From Scratch」というシンプルなLinuxをインストール&環境構築する作業を通して、LinuxがOSとして機能するための仕組みや設定を見直そう |
|
Linux Squareフォーラム全記事インデックス |
|
- 【 pidof 】コマンド――コマンド名からプロセスIDを探す (2017/7/27)
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、コマンド名からプロセスIDを探す「pidof」コマンドです。 - Linuxの「ジョブコントロール」をマスターしよう (2017/7/21)
今回は、コマンドライン環境でのジョブコントロールを試してみましょう。X環境を持たないサーバ管理やリモート接続時に役立つ操作です - 【 pidstat 】コマンド――プロセスのリソース使用量を表示する (2017/7/21)
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、プロセスごとのCPUの使用率やI/Oデバイスの使用状況を表示する「pidstat」コマンドです。 - 【 iostat 】コマンド――I/Oデバイスの使用状況を表示する (2017/7/20)
本連載は、Linuxのコマンドについて、基本書式からオプション、具体的な実行例までを紹介していきます。今回は、I/Oデバイスの使用状況を表示する「iostat」コマンドです。
|
|