第2回 データベース強制アクセス制御をカスタマイズする


海外 浩平
日本SELinuxユーザ会
2007/9/4


 Trusted Procedureの設定

 SQL関数に付与することのできる定義済みタイプのうち、最もクセのある働きをするのは「sepgsql_trusted_proc_t」タイプです。このタイプを持つSQL関数の実行はドメイン遷移を発生させ、SQL関数の実行中に限り管理ドメインと同じ権限でデータベースオブジェクトを参照することができます。

 このような関数は、高い権限で実行させても無害であるということが管理者によってチェック済みであると考えられるため、信頼済みのSQL関数、すなわちTrusted Procedureと呼ばれます。

 先ほどのcustomerテーブルを使って、Trusted Procedureの実行例を試してみましょう。

 クレジットカード番号を格納したcreditカラムの内容を直接読み出されることは避けなければいけません。しかし、オンラインで決済を行う顧客が、どのクレジットカードで決済するのかを提示する必要があり、一部を伏せ字にした文字列を返却するものとします。

 上記の処理を行うSQL関数を、次のように定義します。

CREATE OR REPLACE FUNCTION notice_credit(integer) RETURNS text
    LANGUAGE SQL CONTEXT = 'system_u:object_r:sepgsql_trusted_proc_t'
    AS 'SELECT substring(credit,1,4) || ''-xxxx-xxxx-xxxx''
    FROM customer WHERE id = $1';

 「CONTEXT = '...'」の拡張構文によって、「sepgsql_trusted_proc_t」タイプを持ったSQL関数として作成されます。

 そして、本来はccreditカラムにアクセスできない一般ドメインからTrusted Procedure呼び出しを通じてcreditカラムにアクセスすることが可能になります。

postgres=> SELECT id, name, notice_ccredit(id) FROM customer;
   id  |   name     |      notice_ccredit
----+--------+---------------------
  10  |   kaigai     |  1234-xxxx-xxxx-xxxx
  11  |   ymj       |  1111-xxxx-xxxx-xxxx
  12  |   tak        |  5555-xxxx-xxxx-xxxx
(3 rows)

 このように、機密情報にアクセスする限定的な方法を提供する場合にTrusted Procedureは威力を発揮します。

 条件変数booleanによるポリシーのカスタマイズ

 SELinuxは、セキュリティポリシーの一部をbooleanと呼ばれる条件変数の値に応じて動的に有効化/無効化するための機能を持っています。

 booleanはon、またはoffの2つの状態を持っています。例えば、boolean Xの値がonである場合に「vat_t」タイプのファイルに対して書き込み可能だが、offであれば書き込みを禁止する、という使い方が可能です。

 定義済みbooleanの一覧は、getseboolコマンドを利用して参照することができます。

[kaigai@masu ~]$ /usr/sbin/getsebool -a
allow_console_login --> off
allow_cvs_read_shadow --> off
          :
   (以下略)

 SE-PostgreSQLの標準セキュリティポリシーでも、以下の表のように5つの定義済みbooleanを提供しています。

boolean名
定義済みの動作
初期値
sepgsql_enable_unconfined 管理ドメインの操作に制約をつけない(すべて許可)
on
sepgsql_enable_users_ddl 一般ドメインのDDL系SQL構文の実行を許可
on
sepgsql_enable_auditallow 「アクセス許可ログ」の出力を有効化
off
sepgsql_enable_auditdeny 「アクセス拒否ログ」の出力を有効化
on
sepgsql_enable_audittuple 行に対する「アクセス許可/拒否ログ」の出力を有効化
off
表3 SE-PostgreSQLの定義済み条件変数

 このうち、「sepgsql_enable_users_ddl」と「sepgsql_enable_auditallow」を使ってポリシーのカスタマイズを試してみましょう。

 「sepgsql_enable_users_ddl」がonのとき、一般ドメインがCREATE TABLEなどのDDL系SQL構文を実行可能です。初期値はonですので、これをoffに切り替えて、一般ドメインがDDL構文を実行できなくなることを確認してみましょう。

 booleanの値を切り替えるには、setseboolコマンドを使用します。-Pオプションを付けると、設定したbooleanの値は再起動後でも有効になります。

[root@masu ~]# setsebool -P sepgsql_enable_users_ddl off

 これで、一般ドメインがDDL構文を実行することはできなくなりました。実際にCREATE TABLE構文を実行して試してみましょう。

postgres=> CREATE TABLE tbl_1 (
postgres(> x integer,
postgres(> y text
postgres(> );
ERROR: Transaction aborted due to SELinux access denied.

 このように、セキュリティポリシーに違反するということで、CREATE TABLE構文の実行は禁止されます。

 同様に、一般ドメインからはテーブルを作成するSELECT……INTO構文や、そのほかのCREATE/ALTER/DROPなどのSQL構文も実行できなくなります。

 「sepgsql_enable_auditallow」は、監査ログの出力を制御するためのbooleanの1つで、これがonのとき「アクセス許可ログ」の出力が有効化されます。初期状態では「アクセス拒否ログ」のみが出力されますが、「アクセス許可ログ」を参照することでSE-PostgreSQLがどのようなアクセス制御を行っているのかを確認することができます。

[root@masu ~]# setsebool -P sepgsql_enable_auditallow on

 では、単純なSQL構文を実行して試してみましょう。

kaigai=# SELECT * FROM drink;
NOTICE: SELinux: granted { select } scontext=system_u:system_r:unconfined_t tcontext=user_u:object_r:sepgsql_table_t tclass=db_table name=drink
NOTICE: SELinux: granted { select } scontext=system_u:system_r:unconfined_t tcontext=user_u:object_r:sepgsql_table_t tclass=db_column name=drink.id
NOTICE: SELinux: granted { select } scontext=system_u:system_r:unconfined_t tcontext=user_u:object_r:sepgsql_table_t tclass=db_column name=drink.name
NOTICE: SELinux: granted { select } scontext=system_u:system_r:unconfined_t tcontext=user_u:object_r:sepgsql_table_t tclass=db_column name=drink.price
   id  |    name    |   price
----+--------+-------
   1   |   water    |   100
   2   |   coke     |   120
   3   |   juice     |   120
   4   |   coffee   |   180
   5   |   beer      |   260
   6   |   wine      |   420
(6 rows)

 このように、drinkテーブルに対するselect権限、id、name、priceの各カラムに対するselect権限が評価され、それらのチェックをクリアしてSQLが実行されていることが分かります。

 実際には、6つの行それぞれに対してもアクセス制御が行われていますが、行レベルのアクセス許可/拒否ログを有効にするためには「sepgsql_enable_audittuple」のbooleanをonにする必要があります。これは、巨大なテーブルをスキャンした場合に監査ログによってディスクが埋まってしまうことを避けるための措置です。


 今回の記事では、タイプの変更やbooleanの切り替えによるSE-PostgreSQLのカスタマイズ方法を紹介しました。次回は、SE-PostgreSQLがどのようにアクセス制御を行っているのかという、アーキテクチャの話を中心に紹介したいと思います。

参考情報:ログイン時のドメインを変更する

 Fedora 7のデフォルトでは、sshなどでログインした場合のシェルプロセスはunconfined_tドメインで動作します。

 このドメインは「あらゆる操作を許可」された非常に強い権限を持っており、これはSE-PostgreSQLにおいても同様です。

 以下の設定を加えることにより、ユーザーがログインしたときのドメインをuser_tという制約された権限のものに切り替えることが可能です。

[root@masu ~]# echo "system_r:sshd_t:s0 user_r:user_t:s0" \
                       > /etc/selinux/targeted/contexts/users/user_u

 この設定により、一般ユーザーがssh経由でログインした場合のドメインを定義しています。

 特定のユーザーだけは引き続きunconfined_tドメインで動作させたい場合は、semanageコマンドを用いて、当該ユーザーとSELinuxユーザーsystem_uを関連付けてください。

 上で設定したuser_uは、「このような関連付けが定義されていないすべてのユーザー」という意味になります。

[root@masu ~]# semanage login -a -s system_u kaigai

 なお、user_tドメインからSE-PostgreSQLに接続するには、最初に一度だけ以下のコマンドの実行が必要です。

[root@masu ~]# setsebool -P allow_user_postgresql_connect on

3/3
 

Index
データベース強制アクセス制御をカスタマイズする
  Page1
OSとデータベースのアクセス制御ポリシーを一元化する
最も詳細なアクセス制御を実現するType Enforcement
「誰が」「何に」「何をする」――TEのアクセス制御方式
ドメイン遷移とは
SE-PostgreSQLとクライアントのドメイン
  Page2
SE-PostgreSQLでTEを使ってみる
テーブル/カラムに対するアクセス制御
SQL関数に対するアクセス制御
Page3
Trusted Procedureの設定
条件変数booleanによるポリシーのカスタマイズ


Profile
海外 浩平(かいがい こうへい)

日本SELinuxユーザ会

某社でLinuxカーネルの開発・サポートを行うかたわら、SELinux並列実行性能の改善や、組み込み向けファイルシステムのSELinux対応などを行っている。

現在は本業に加えて、IPA未踏ソフトウェア創造事業の支援を受けて、SE-PostgreSQL開発という二足のわらじを履いている日々。

「アンチ事なかれ主義」がモットー、好きな言葉は「前代未聞」。

SE-PostgreSQLによるセキュアDB構築 連載インデックス


Security&Trust フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Security & Trust 記事ランキング

本日 月間