[pgsql-jp: 38111] [ANN] SE-PostgreSQL 8.2.3-1.0 alpha release

KaiGai Kohei kaigai @ kaigai.gr.jp
2007年 3月 5日 (月) 20:55:51 JST


PostgreSQL-JP各位

海外@SELinuxです。PostgreSQL関係のネタを宣伝させてください。

現在、開発を進めている SE-PostgreSQL ですが、以下の通りα版をリリース
しました。
このバージョンの目的は、OSSコミュニティからのフィードバックを得るため
のもので、開発者は、皆さんからの全てのコメント/リクエスト/レポートを
歓迎します。

======================================================================
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を利用する必要があります。
-- 
KaiGai Kohei <kaigai @ kaigai.gr.jp>



pgsql-jp メーリングリストの案内