追記:ITproさんに取り上げて頂きました
http://itpro.nikkeibp.co.jp/article/NEWS/20070305/263930/
======================================================
Security Enhanced PostgreSQL 8.2.3-1.0 alpha release
======================================================
Security Enhanced PostgreSQL (SE-PostgreSQL) は、PostgreSQLの拡張機能で、SELinuxと連携して一元的なセキュリティポリシに基づく細粒度の強制アクセス制御を提供します。このようなSE-PostgreSQLの特徴は、RDBMSをOSと一体化した情報フロー制御の枠組みに組み込むことを可能にし、情報資産を漏えいや改ざんといった脅威から保護します。
細粒度のアクセス制御
SE-PostgreSQLは行レベル/列レベルのアクセス制御を可能にします。
PostgreSQL-ACLは表よりも小さな単位のDBオブジェクトにアクセス制御を提供しないため、SE-PostgreSQLの利用によって、データベース管理者はより柔軟できめ細かいアクセス制御を施すことが可能です。
強制アクセス制御
SE-PostgreSQLの提供するアクセス制御は、特権ユーザを含む全てのDBクライアントから発行された全てのSQLクエリに対して例外なく適用されます。即ち、SE-PostgreSQLはユーザ空間リファレンスモニタとして機能します。
SELinuxとの相互作用
SE-PostgreSQLの提供するアクセス制御は、SELinuxのセキュリティポリシーに基づいて意思決定が行われます。また、DBクライアントの権限は、接続元プロセスのセキュリティコンテキストによって決定されます。
(※) 本バージョンのSE-PostgreSQLは、正式なリリースに先立って、オープンソースコミュニティからの要望やバグのレポート等のフィードバックを得るためのものです。従って、未だコードに対する十分な検証が行われていないことに留意の上、ご利用ください。
(※) 本ソフトウェアは、IPA 未踏ソフトウェア創造事業(2006年/下期)の支援を受けて開発が進められています。
[インストール]
SE-PostgreSQLは、SELinuxセットアップ済みの Fedora Core 6 環境にインストールすることができます。
以下のURLからRPMパッケージを取得してください
http://code.google.com/p/sepgsql/downloads/list selinux-policy-2.4.6-40.sepgsql.noarch.rpm selinux-policy-targeted-2.4.6-40.sepgsql.noarch.rpm sepostgresql-8.2.3-0.206a.i386.rpm
最初に、selinux-policy と selinux-policy-targeted パッケージをインストールし、続いて sepostgresql パッケージをインストールします。
sepostgresql パッケージのインストール時に、SE-PostgreSQL用の標準セキュリティポリシーがインストールされます。
また、フロントエンドとして psql コマンドを利用する場合には postgresql及び postgresql-libs パッケージのインストールが別途必要です。
データベースクラスタを初期化するため、以下のコマンドを実行してください。
# /etc/init.d/sepostgresql initdb
/var/lib/sepgsql/data 以下にデータベースクラスタが作成されます。
続いて、SE-PostgreSQL サーバを起動します。(標準の) postgresqlサーバが停止していることを確認し、以下のコマンドを実行してください。
# /etc/init.d/sepostgresql start
データベースクラスタを初期化するのは sepgsql ユーザです。suコマンドで sepgsql ユーザになり、createdbコマンドでデータベースを作成したり、createuserコマンドでデータベースロールを作成することができます。
[例] # su - sepgsql $ createuser kaigai Shall the new role be a superuser? (y/n) y CREATE ROLE $ createdb kaigaidb CREATE DATABASE $
[サンプルSQL/構築用]
CREATE TABLE drink (
did integer primary key,
dname text,
dprice integer,
dsoft bool,
dstock integer
);
ALTER TABLE drink ALTER dstock
context = 'user_u:object_r:sepgsql_secret_table_t';
INSERT INTO drink VALUES (1, 'juice', 110, true, 35);
INSERT INTO drink VALUES (2, 'coke', 110, true, 20);
INSERT INTO drink VALUES (3, 'milk', 130, true, 5);
INSERT INTO drink VALUES (4, 'water', 100, true, 10);
INSERT INTO drink VALUES (5, 'beer', 240, false, 15);
INSERT INTO drink VALUES (6, 'wine', 380, false, 0);
UPDATE drink SET security_context =
'user_u:object_r:sepgsql_table_t:SystemHigh'
where dsoft = false;
create or replace function drink_stock_exist (integer)
returns bool
language 'sql'
as 'select dstock > 0 from drink where did = $1';
ALTER FUNCTION drink_stock_exist(integer)
context = 'user_u:object_r:sepgsql_trusted_proc_t';[サンプルSQL/実行例]
$ id -Z
root:system_r:unconfined_t:SystemLow-SystemHigh
$ psql -q
kaigai=# select sepgsql_getcon();
sepgsql_getcon
-------------------------------------------------
root:system_r:unconfined_t:SystemLow-SystemHigh
(1 row)
kaigai=# select * from drink;
did | dname | dprice | dsoft | dstock
-----+-------+--------+-------+--------
1 | juice | 110 | t | 35
2 | coke | 110 | t | 20
3 | milk | 130 | t | 5
4 | water | 100 | t | 10
5 | beer | 240 | f | 15
6 | wine | 380 | f | 0
(6 rows)
## 各タプルのセキュリティコンテキストは、システム列 security_context に
## 格納されています。
kaigai=# select security_context,* from drink;
security_context | did | dname | dprice | dsoft | dstock
---------------------------------+-----+-------+--------+-------+--------
user_u:object_r:sepgsql_table_t | 1 | juice | 110 | t | 35
user_u:object_r:sepgsql_table_t | 2 | coke | 110 | t | 20
user_u:object_r:sepgsql_table_t | 3 | milk | 130 | t | 5
user_u:object_r:sepgsql_table_t | 4 | water | 100 | t | 10
user_u:object_r:sepgsql_table_t | 5 | beer | 240 | f | 15
user_u:object_r:sepgsql_table_t | 6 | wine | 380 | f | 0
(6 rows)
kaigai=#
## 権限を落として実行してみます。
## SystemHigh の2つのタプルが結果セットから除外されました
$ runcon -l s0 -- bash
$ id -Z
root:system_r:unconfined_t
$ psql -q
kaigai=# select sepgsql_getcon();
sepgsql_getcon
----------------------------
root:system_r:unconfined_t
(1 row)
kaigai=# select * from drink;
NOTICE: SELinux: denied { select }
scontext=root:system_r:unconfined_t
tcontext=user_u:object_r:sepgsql_table_t:SystemHigh
tclass=tuple
NOTICE: SELinux: denied { select }
scontext=root:system_r:unconfined_t
tcontext=user_u:object_r:sepgsql_table_t:SystemHigh
tclass=tuple
did | dname | dprice | dsoft | dstock
-----+-------+--------+-------+--------
1 | juice | 110 | t | 35
2 | coke | 110 | t | 20
3 | milk | 130 | t | 5
4 | water | 100 | t | 10
(4 rows)
kaigai=#
$ exit
## sepgsql_secret_table_t にアクセスできないドメインから接続します。
$ runcon -t initrc_t -- bash
$ id -Z
root:system_r:initrc_t:SystemLow-SystemHigh
$ psql -q
kaigai=# select * from drink;
ERROR: SELinux: denied { select }
scontext=root:system_r:initrc_t:SystemLow-SystemHigh
tcontext=user_u:object_r:sepgsql_secret_table_t
tclass=column name=dstock
## sepgsql_secret_table_t タイプの dstock 列へのアクセスを行おうとして
## アクセスが拒否されました。
## しかし、Trusted Procedure を利用することによって、信頼された手続きに
## 基づいてのみ dstock 列へのアクセスを許可しています。
kaigai=# select did, dname, dprice, drink_stock_exist(did) from drink;
did | dname | dprice | drink_stock_exist
-----+-------+--------+-------------------
1 | juice | 110 | t
2 | coke | 110 | t
3 | milk | 130 | t
4 | water | 100 | t
5 | beer | 240 | t
6 | wine | 380 | f
(6 rows)
kaigai=#[ヒント]
・ SE-PostgreSQL と PostgreSQL には、データベースのフォーマットに互換性はありません。誤って PostgreSQL のデータベースを破壊しないよう注意してください。
・ アクセス拒否ログ/アクセス許可ログは、SELinuxのboolean(条件変数)を用いて制御することができます。sesetboolコマンドで以下のbooleanを設定してください。
sepgsql_enable_auditallow
sepgsql_enable_auditdeny
sepgsql_enable_audittuple
・テスト用に initrc_t を権限の弱いドメインとして定義しています。initrc_tドメインからは DDL 文が使えない他、sepgsql_secret_table_t のテーブル/カラム/タプルにアクセスできません。
・strict-policy向けのセキュリティポリシーは開発中です。α版をご利用の場合、targeted-policyを利用する必要があります。