他のバージョンの文書 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

F.38. sepgsql

sepgsqlは、SELinuxのセキュリティポリシーに基づいた、ラベルベースの強制アクセス制御(MAC; Mandatory Access Control)機能を提供するモジュールです。

警告

現在の実装にはいくつかの重要な制限事項があり、そのため、全ての操作に対して強制アクセス制御を適用するわけではありません。 詳細は 項F.38.6 をご覧ください。

F.38.1. 概要

このモジュールは、PostgreSQLが標準で提供しているものに加えて、SELinuxと統合されたアクセス制御のレイヤーを追加します。 SELinuxの視点からは、このモジュールがPostgreSQLをユーザ空間オブジェクトマネージャとして機能することを可能にします。 すなわち、DMLクエリによる個々のテーブルや関数へのアクセスは、オペレーティングシステムのセキュリティポリシーによってチェックされます。 このチェックは、PostgreSQLによる通常のSQLパーミッションチェックに対して追加的に実施されます。

SELinuxにおけるアクセス制御の意思決定は、system_u:object_r:sepgsql_table_t:s0のような書式を持ったセキュリティラベルと呼ばれる文字列を用いて行われます。 個々のアクセス制御の意思決定には、2種類のラベルが利用されます。 すなわち、ある操作を行おうとする主体(サブジェクト)のラベルと、その操作の対象となるオブジェクトのラベルです。 これらのラベルはあらゆる種類のオブジェクトに対して適用されるため、(このモジュールを用いる事で)データベースに格納されたオブジェクトに対するアクセス制御は、他の一般的なオブジェクト、例えばファイルに対するものと同一の基準に従って意思決定される事になります。 このデザインは、情報資産を格納する方法とは独立に、一元管理されたセキュリティポリシーによって情報資産を保護することを意図しています。

SECURITY LABELを用いてデータベースオブジェクトにセキュリティラベルを設定することができます。

F.38.2. インストール

このモジュールはSELinuxが有効なLinuxカーネル 2.6.28 以上で動作します。その他のプラットフォーム上では利用する事はできません。 加えて、libselinux 2.0.93以上、selinux-policy 3.9.13以上(ディストリビューションによっては、必要なルールを古いバージョンのポリシーにバックポートしているか可能性があります)が必要で、--with-selinuxオプションによって明示的に有効化しなければいけません。

sestatusコマンドを用いてSELinuxの状態を確認することができます。典型的な出力例は以下の通りです。

$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

SELinuxが無効化されている、あるいはインストールされていない場合、このモジュールのインストールの前に、SELinuxのセットアップを行わねばなりません。

このモジュールをビルドするには、PostgreSQLのconfigure コマンドに--with-selinuxオプションを追加してください。 これは、ビルド時にlibselinux-develパッケージがインストール されている事を確認します。

このモジュールを利用するには、shared_preload_libraries パラメータに sepgsql を追記する必要があります。これ以外の方法で ロードされた場合、このモジュールは機能しません。 このモジュールのロード後、各データベースに対してsepgsql.sqlを 実行し、セキュリティラベル管理のための関数のインストールや、初期セキュリティ ラベルの設定を行うべきです。

以下にsepgsql関数およびセキュリティラベルと共にデータベース クラスタを初期化する手順を示します。 インストール先に応じて、適宜パス名を読み替えるようにしてください。

$ export PGDATA=/path/to/data/directory
$ initdb
$ vi $PGDATA/postgresql.conf
  change
    #shared_preload_libraries = ''                # (change requires restart)
  to
    shared_preload_libraries = 'sepgsql'          # (change requires restart)
$ for DBNAME in template0 template1 postgres; do
    postgres --single -F -c exit_on_error=true $DBNAME \
      </usr/local/pgsql/share/contrib/sepgsql.sql >/dev/null
  done

libselinuxselinux-policyのバージョンに よっては以下のようなメッセージが出力される事があります。

/etc/selinux/targeted/contexts/sepgsql_contexts:  line 33 has invalid object type db_blobs
/etc/selinux/targeted/contexts/sepgsql_contexts:  line 36 has invalid object type db_language
/etc/selinux/targeted/contexts/sepgsql_contexts:  line 37 has invalid object type db_language
/etc/selinux/targeted/contexts/sepgsql_contexts:  line 38 has invalid object type db_language
/etc/selinux/targeted/contexts/sepgsql_contexts:  line 39 has invalid object type db_language
/etc/selinux/targeted/contexts/sepgsql_contexts:  line 40 has invalid object type db_language

これらのメッセージは無害ですので無視してください。

インストール手順が正常に終了したら、通常通り、サーバを起動することができます。

F.38.3. リグレッションテスト

SELinuxの性質上、sepgsqlのリグレッションテストを 実行するには、いくつかの追加的な設定が必要で、そのうちの幾つかはrootで 実行する必要があります。 リグレッションテストは通常のmake checkmake installcheck コマンドで実行する事はできません。必要な設定を行い、テスト用スクリプトを手動で 実行する必要があります。 このテストはPostgreSQLビルドツリーのcontrib/sepgsqlディレクトリで 実行する必要があります。しかしビルドツリーを必要とする一方、このテストは インストールされたサーバに対して実行する必要があります。 これは、make checkではなく、make installcheckに よく似ています。

最初に、項F.38.2に従ってsepgsqlを データベースにセットアップします。 使用するOS上のユーザは、認証無しでデータベース特権ユーザとして接続できる 必要があることに留意してください。

次に、リグレッションテスト用のポリシーパッケージのビルドとインストールを 行ってください。sepgsql-regtest.ppはリグレッションテストの実行に 必要な一連のルールを含む特別な目的のポリシーパッケージです。 ポリシーのソースファイルであるsepgsql-regtest.teから、SELinuxの 提供するMakefileを用いてmakeコマンドでビルドする事ができます。 この時、インストール先システムにおいて、適切なMakefileの位置を 指定する必要があります。以下の例で示されているパスは一例です。 ビルドが完了したら、semoduleを用いてこのポリシーパッケージを インストールする事ができます。このコマンドは、指定されたポリシーパッケージを リンクし、カーネル空間にロードする役割を果たします。 インストールが正常終了したら、semodule -lにより 有効なパッケージの一覧としてsepgsql-regtestが表示されるはずです。

$ cd .../contrib/sepgsql
$ make -f /usr/share/selinux/devel/Makefile
$ sudo semodule -u sepgsql-regtest.pp
$ sudo semodule -l | grep sepgsql
sepgsql-regtest 1.03

次に、sepgsql_regression_test_modeブーリアンを有効化して ください。安全のため、デフォルトではsepgsql-regtest.ppに 含まれる全てのルールが有効化されている訳ではありません。 sepgsql_regression_test_modeブーリアンはリグレッションテストを 起動するための幾つかのルールに関連付けされており、setsebool コマンドによって有効化する事ができます。

$ sudo setsebool sepgsql_regression_test_mode on
$ getsebool sepgsql_regression_test_mode
sepgsql_regression_test_mode --> on

次に、シェルがunconfined_tドメインで動作している事を確認して下さい。

idコマンドを使って現在のドメインを確認する事ができます。 以下のように、シェルプロセスがunconfined_tドメインで動作している事を確認してください。

$ id -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

利用者の動作ドメインを設定する方法について、必要であれば、 詳細は項F.38.7をご覧ください。

最後に、リグレッションテストのスクリプトを実行します。

$ ./test_sepgsql

このスクリプトは全ての設定ステップが正常に行われていることを確認し、 その後、sepgsqlモジュールに対するリグレッションテストを 実行します。

テストの実行後はsepgsql_regression_test_modeブーリアンを 無効化する事をお勧めします。

$ sudo setsebool sepgsql_regression_test_mode off

sepgsql-regtestポリシーをアンロードする際は、以下のコマンドを 実行してください。

$ sudo semodule -r sepgsql-regtest

F.38.4. GUCパラメータ

sepgsql.permissive (boolean)

このパラメータにより、オペレーティングシステムの設定に関わらず、 sepgsqlをパーミッシブモードで動作させる事ができます。 デフォルトの設定値はoffです。 postgresql.conf内、およびサーバ起動時のコマンドラインでのみ、 このパラメータを設定する事ができます。

このパラメータがonの場合、たとえオペレーティングシステムがエンフォーシングモードで動作していたとしても、SE-PostgreSQLはパーミッシブモードで動作します。 このパラメータは主としてテストの目的に有用です。

sepgsql.debug_audit (boolean)

このパラメータにより、セキュリティポリシーの設定とは無関係に監査ログを出力する事が可能になります。 デフォルト値はoff(セキュリティポリシーの設定に従う)です。

SELinuxのセキュリティポリシーには、特定のアクセスを監査ログに記録するか否かを制御するルールも存在します。 デフォルトでは、ポリシーに違反したアクセスを記録し、それ以外はログに記録されません。

システムのポリシーとは無関係に、このパラメータは全ての監査ログの出力を強制します。

F.38.5. 機能

F.38.5.1. 制御されるオブジェクトの種類

SELinuxのセキュリティモデルでは、全てのアクセス制御 ルールは動作主体(サブジェクト; 典型的にはデータベースクライアント)と 対象オブジェクト間の関係として記述し、これらはセキュリティラベルによって 識別されます。 ラベル付けされていないオブジェクトに対するアクセスが発生した場合、 そのオブジェクトはあたかもunlabeled_tタイプが割り当てられて いるかのように振舞います。

現在のsepgsqlでは、スキーマ、テーブル、カラム、シーケンス、ビューおよび関数に対するラベル付けがサポートされています。 sepgsqlの利用時には、これらのデータベースオブジェクトに対して、その生成時に自動的にセキュリティラベルが割り当てられます。 このラベルはデフォルトセキュリティラベルと呼ばれ、作成者のラベルと親関係にあたるオブジェクトのラベルに基づいて、システムのセキュリティポリシーが決定します。

新しいデータベースオブジェクトのラベルは、タイプ遷移と呼ばれる異なったラベルを設定するための特別なルールがセキュリティポリシーに設定されている場合を除き、親関係にあるオブジェクトのラベルを引き継ぎます。 スキーマの親オブジェクトはデータベースであり、テーブル、シーケンス、ビュー、および関数はその属するスキーマが、カラムはその属するテーブルが親オブジェクトという事になります。

F.38.5.2. DMLパーミッション

テーブルに対しては、構文の種類に応じてdb_table:selectdb_table:insertdb_table:updateあるいはdb_table:delete権限が全ての被参照テーブルに対してチェックされます。 加えて、WHERE句やRETURNING句で参照されるカラム、又はUPDATEの際のデータ元として利用されるカラムの属するテーブルに対してdb_table:select権限もチェックされます。

UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;

この場合、t1.aWHERE句の中で参照されているため、利用者はdb_table:update権限に加えて、db_table:select権限を有していなければいけません。 さらに、参照されているカラムに対しては列レベルのパーミッションがチェックされます。

カラムに対しては、SELECT構文で読み出されるカラムに対してだけでなく、他のDML構文で参照されるカラムに対してもdb_column:select権限がチェックされます。

言うまでもなく、UPDATE構文やINSERT構文によって更新されるカラムに対しては、db_column:update権限、もしくはdb_column:insert権限がチェックされます。

UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;

この場合、更新されるt1.xに対してdb_column:update権限が、更新と同時に参照されるt1.yに対してはdb_column:{select update}権限が、そして、WHERE句で参照されるだけのt1.zにはdb_column:select権限がチェックされます。 また、テーブルレベルではdb_table:{select update}権限がチェックされます。

SELECT構文を用いてシーケンスを参照する場合、db_sequence:get_valueがチェックされます。 しかし、現在のところlastval()など関連する関数の実行時にはパーミッションチェックを行わない事に留意してください。

ビューに対してはdb_view:expand権限がチェックされ、次いで、ビューから展開されたオブジェクトに対するパーミッションが個別にチェックされます。

関数に対してdb_procedure:{execute}権限が定義されていますが、現バージョンではチェックされません。

クライアントは全ての被参照テーブル・カラムに対して参照の権限を有している必要があります。それらがビューに由来し、展開されたものであっても同様です。これにより、テーブルの内容がどのような方法によって参照されるかに関係なく、一貫したアクセス制御ルールを適用する事ができます。

データベーススーパーユーザに対して、標準のデータベース権限システムはDMLを用いたシステムカタログの更新と、TOASTテーブルの参照および更新を許していますが、sepgsqlが有効なとき、これらの操作は禁止されます。

F.38.5.3. DDLパーミッション

SECURITY LABELコマンドの実行時、ラベル付けされるオブジェクトの古いラベルに対してsetattr権限とrelabelfrom権限が、入力された新しいラベルに対してrelabelto権限がチェックされます。

複数のラベルプロバイダがインストールされており、利用者がSELinuxの管理下にないセキュリティラベルを設定しようとした場合、setattr権限だけがチェックされるべきです。しかし実装上の制約により、現在はこれをチェックしていません。

F.38.5.4. トラステッド プロシジャ

トラステッド・プロシジャはSECURITY DEFINER関数やSet-UIDコマンドに似て います。通常、機密データに対する高度にコントロールされたアクセス手段を 提供する目的で、SELinuxは利用者のものとは異なる セキュリティラベルで信頼済みのコードを実行するための機能を持っています。 関数がトラステッド・プロシジャとして振舞うかどうかは、関数のセキュリティ ラベルおよびオペレーティングシステムのセキュリティポリシーに従って 決まります。 例えば:

postgres=# CREATE TABLE customer (
               cid     int primary key,
               cname   text,
               credit  text
           );
CREATE TABLE
postgres=# SECURITY LABEL ON COLUMN customer.credit
               IS 'system_u:object_r:sepgsql_secret_table_t:s0';
SECURITY LABEL
postgres=# CREATE FUNCTION show_credit(int) RETURNS text
             AS 'SELECT regexp_replace(credit, ''-[0-9]+$'', ''-xxxx'', ''g'')
                        FROM customer WHERE cid = $1'
           LANGUAGE sql;
CREATE FUNCTION
postgres=# SECURITY LABEL ON FUNCTION show_credit(int)
               IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0';
SECURITY LABEL

これらの操作は管理権限を持つ利用者で行ってください。

postgres=# SELECT * FROM customer;
ERROR:  SELinux: security policy violation
postgres=# SELECT cid, cname, show_credit(cid) FROM customer;
 cid | cname  |     show_credit
-----+--------+---------------------
   1 | taro   | 1111-2222-3333-xxxx
   2 | hanako | 5555-6666-7777-xxxx
(2 rows)

この場合、一般の利用者はcustomer.creditを直接参照することはできませんが、トラステッド・プロシジャであるshow_creditを用いる事で、一部の桁がマスクされた顧客のクレジットカード番号をプリントする事が可能になります。

F.38.5.5. その他

ロードされたモジュールは、セキュリティポリシーの適用を容易にバイパスできるため、LOADコマンドの実行は全面的に禁止されています。

F.38.6. 制限事項

ユーザ空間アクセスベクタ・キャッシュ

まだsepgsqlはユーザ空間アクセスベクタ・キャッシュをサポートしていません。この機能はパフォーマンスを改善するでしょう。

Data Definition Language (DDL) パーミッション

実装上の制約により、DDLパーミッションはチェックされていません。

Data Control Language (DCL) パーミッション

実装上の制約により、DCLパーミッションはチェックされていません。

Row-level access control

PostgreSQLは行レベルアクセス制御をサポートしていません。 したがって、sepgsqlも同様です。

隠れチャネル

たとえ利用者が参照を許可されていないオブジェクトであっても、sepgsqlはその存在を隠すことを意図していません。 例えば、我々があるオブジェクトの内容を参照する事ができなくても、主キーの競合や外部キー違反、その他の方法によって不可視なオブジェクトが存在する事を推測できます。 "最高機密"テーブルの存在を隠すことは不可能であり、その内容を秘匿することだけを意図しています。

F.38.7. 外部リソース

SE-PostgreSQL Introduction

このwikiページでは、概要、セキュリティ・デザイン、アーキテクチャ、管理、および将来の機能について紹介しています。

Fedora SELinux User Guide

このドキュメントはSELinuxシステム管理に対する広範な知識を提供しています。 主としてFedoraを対象としていますが、それに限ったものではありません。

Fedora SELinux FAQ

このドキュメントはSELinuxに関するよくある質問と回答(FAQ)です。 主としてFedoraを対象としていますが、それに限ったものではありません。

F.38.8. 著者

KaiGai Kohei