無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

F.33. sepgsql

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

警告

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

F.33.1. 概要

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

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

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

F.33.2. インストール

このモジュールは SELinux が有効な Linux カーネル 2.6.28 以上で動作します。その他のプラットフォーム上では利用する事はできません。 加えて、 libselinux 2.1.10以上、 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 パッケージがインストールされている事を確認します。

このモジュールを利用するには、 postgresql.conf 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

libselinux selinux-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.33.3. リグレッションテスト

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

最初に、 項F.33.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.07

次に、 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 -Z
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

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

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

$ ./test_sepgsql

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

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

$ sudo setsebool sepgsql_regression_test_mode off

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

$ sudo semodule -r sepgsql-regtest

F.33.4. GUCパラメータ

sepgsql.permissive ( boolean )

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

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

sepgsql.debug_audit ( boolean )

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

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

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

F.33.5. 機能

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

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

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

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

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

テーブルに対しては、構文の種類に応じて db_table:select db_table:insert db_table:update あるいは db_table:delete 権限が全ての被参照テーブルに対してチェックされます。 加えて、 WHERE 句や RETURNING 句で参照されるカラム、又は 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} 権限が、そして参照されるだけの t1.z には db_column:select 権限がチェックされます。 また、テーブルレベルでは db_table:{select update} 権限がチェックされます。

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

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

利用者がクエリの一部として、あるいは近道インターフェースを用いた呼び出しによって 関数を実行しようとするとき、 db_procedure:{execute} 権限がチェックされ ます。 関数がトラステッドプロシジャである場合、関数がトラステッドプロシジャのエントリー ポイントとして振る舞う事ができるかどうかを検査するために db_procedure:{entrypoint} 権限がチェックされます。

あらゆるスキーマオブジェクトにアクセスするためには、それらを含むスキーマに対する db_schema:search 権限が必要です。 あるスキーマオブジェクトがスキーマ修飾無しに参照された場合、この権限を与えられていないスキーマは探索されません(あたかも利用者がスキーマに対する USAGE 権限を有していないかのように振る舞います)。 明示的なスキーマ修飾があり、このスキーマに対して利用者が要求された権限を有していない場合、エラーが発生します。

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

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

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

オブジェクトの作成、変更、削除やセキュリティラベルの変更など、 SELinux は各オブジェクトに共通の操作を制御するためのパーミッションを何個か定義しています。 また、特定のスキーマに対する名前の追加や削除など、いくつかのオブジェクトにはそれ固有の操作を制御するための特別なパーミッションも定義されています。

新しいデータベースオブジェクトの作成には create 権限が必要です。 SELinux は利用者のセキュリティラベルと新しいオブジェクトに付与される事になるセキュリティラベルの対に基づいて、この権限を許可、あるいは拒否します。 いくつかの場合では、追加的な権限チェックが行われます。

  • CREATE DATABASE は、複製元またはテンプレートのデータベース に対する getattr 権限を要求します。

  • スキーマオブジェクトの作成は、それを含むスキーマに対して add_name 権限を要求します。

  • テーブルの作成は同時に、それがあたかも独立したオブジェクトであるかのように、 個々のテーブル列を作成する権限を要求します。

  • LEAKPROOF 属性を持った関数の作成は install 権限を要求します。(これはまた、既存の関数に LEAKPROOF 属性を設定する時にも要求されます)

DROP 構文の実行時、削除されるオブジェクトに対して drop 権限がチェックされます。 CASCADE により間接的に削除されるオブジェクトに対してもチェックは行われます。 特定のスキーマに含まれるオブジェクト(テーブル、ビュー、シーケンスや関数)の削除に際しては、スキーマに対する remove_name 権限も併せてチェックされます。

ALTER 構文の実行時、テーブルに対するインデックスやトリガなど別オブジェクトに従属するもの(これらは代わりに親オブジェクトに対する権限がチェックされる)を除き、 setattr がチェックされます。 いくつかの場合では、追加的な権限チェックが行われます。

  • オブジェクトを新しいスキーマに移動させるには、古いスキーマに対して remove_name 権限が、新しいスキーマに対して add_name 権限が必要です。

  • 関数に対する LEAKPROOF 属性の設定は install 権限を要求します。

  • SECURITY LABEL コマンドの実行時、ラベル付けされるオブジェクトの古いラベルに対して setattr 権限と relabelfrom 権限が、入力された新しいラベルに対して relabelto 権限がチェックされます。 (複数のラベルプロバイダがインストールされており、利用者が SELinux の管理下にないラベルを設定しようとした場合、 setattr 権限だけがチェックされるべきです。しかし実装上の制約により、現在はこれをチェックしていません)

F.33.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.33.5.5. 動的ドメイン遷移

セキュリティポリシーによって許可されている場合、SELinuxの動的ドメイン遷移機能を用いて、利用者のラベルを新しいものに切り替える事ができます。 利用者のドメインは setcurrent 権限および、古いドメインから新しいドメインに遷移するための dyntransition 権限を有している必要があります。

利用者に自身のラベル、すなわち権限を切り替える事を可能にする動的ドメイン遷移は、システムによる自動切り替え(トラステッド・プロシージャの場合)に比べて慎重に取り扱う必要があります。 dyntransition 権限は元々のドメインよりも小さな権限セットを持つドメインに切り替える場合にのみ安全であると考えられます。例えば、

regression=# select sepgsql_getcon();
                    sepgsql_getcon
-------------------------------------------------------
 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
(1 row)

regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c4');
 sepgsql_setcon 
----------------
 t
(1 row)

regression=# SELECT sepgsql_setcon('unconfined_u:unconfined_r:unconfined_t:s0-s0:c1.c1023');
ERROR:  SELinux: security policy violation

上記の例では、広いMCSレンジ c0.c1023 から狭いMCSレンジ c1.c4 への遷移は許可されているものの、その逆は禁止されています。

動的ドメイン遷移とトラステッド・プロシジャの組み合わせは、典型的なコネクションプーラのライフサイクルに適合する興味深い利用法を提供します。 たとえコネクションプーリングソフトウェアが大半のSQLの実行を許可されていない場合でも、トラステッド・プロシジャの内側から sepgsql_setcon() 関数を用いて利用者のセキュリティラベルを切り替える事ができます。(トラステッド・プロシジャは利用者のセキュリティラベルを切り替えるための認証情報を要求すべきです) この後、現在のセッションはコネクションプーラの権限ではなく、対象となる利用者の権限で動作する事になります。 また、 sepgsql_setcon() NULL 引数を与えて(適切な権限チェックを行う)トラステッド・プロシジャから再び呼び出す事で、コネクションプーラは後でセキュリティラベルを元に戻す事ができます。 ここでのポイントは、トラステッド・プロシジャだけが実際に有効なセキュリティラベルを変更する権限を持っており、正しい認証情報が与えられた場合にのみそれを実行するという事です。 言うまでもなく、安全な操作のためには、権限のないアクセスから認証情報を保持するテーブルや関数定義などを保護しなければなりません。

F.33.5.6. その他

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

F.33.6. sepgsql関数

表F-27 に利用可能な関数を示します。

表 F-27. Sepgsql 関数

sepgsql_getcon() returns text 利用者のドメイン、つまり、現在の利用者ラベルを返却します。
sepgsql_setcon(text) returns bool セキュリティポリシーで許可されている場合、現在のセッションの利用者ドメインを新しいドメインへと切り替えます。 NULL を引数に取る事も可能で、その場合、元々の利用者ドメインへの遷移を意味します。
sepgsql_mcstrans_in(text) returns text mcstransデーモンが動作している場合、入力されたMLS/MCSレンジを修飾フォーマットから直接フォーマットに変換します。
sepgsql_mcstrans_out(text) returns text mcstransデーモンが動作している場合、入力されたMLS/MCSレンジを直接フォーマットから修飾フォーマットに変換します。
sepgsql_restorecon(text) returns bool 現在のデータベース内の全てのオブジェクトに対して初期ラベルを割り当てます。引数は NULL もしくはシステムの標準に代わる定義ファイルの名前です。

F.33.7. 制限事項

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

実装上の制約により、いくつかのDDL操作はパーミッションをチェックしません。

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

実装上の制約により、DCL操作はパーミッションをチェックしません。

Row-level access control

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

隠れチャネル

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

F.33.8. 外部リソース

SE-PostgreSQL Introduction

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

Fedora SELinux User Guide

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

Fedora SELinux FAQ

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


powered by SEO.CUG.NET