PostgreSQL のセキュリティを極める PGConf.ASIA 2018 Day 2 2018 年 12 月 12 日 SRA OSS, Inc. 日本支社佐藤友章 sato@sraoss.co.jp 1
目次 おもなセキュリティの観点 データベース接続時のセキュリティ データベース内のセキュリティ そのほかのセキュリティ 2
おもなセキュリティの観点 考慮すべきセキュリティの観点は多岐に渡る TCP 接続 接続監視 データベースサーバ クライアント認証 データベース内 データ暗号化 通信暗号化 設定ファイル pg_hba.conf 操作 テーブル 権限 ローカル接続 クライアント ユーザ 属性 RLS ポリシー クライアント 監査ログ 3
データベース接続時のセキュリティ 4
通信暗号化 SSL でクライアントとデータベースサーバ間の通信を暗号化 設定例 ssl = on 悪意のあるユーザ # SSL による暗号化を有効に データベースサーバ 盗聴 SSL 接続 サーバ秘密鍵 サーバ証明書 SSL で暗号化されているので 通信を盗聴できない SSL 接続の強制はクライアント認証で設定 サーバ証明書も検証するには ルート証明書をクライアントに配置して 接続時に SSL モードを指定 SSL モード SSL モード disable allow prefer require verify-ca verify-all 非 SSL 接続 説明 非 SSL 接続を試みて できなければ SSL 接続 SSL 接続を試みて できなければ非 SSL 接続 ( デフォルト ) SSL 接続 SSL 接続 / サーバ証明書を検証 SSL 接続 / サーバ証明書とホスト名の一致を検証 クライアント ルート証明書 5
クライアント認証 クライアントに対してデータベースサーバ接続時に行う認証 データベースサーバ 接続先データベース 接続ユーザ 設定ファイル pg_hba.conf クライアント ( 接続元 IP アドレス ) pg_hba.conf で最初に一致したレコードで認証を行う 接続形式 ローカル接続 (local) TCP 接続 (host) SSL 接続 (hostssl) 非 SSL 接続 (hostnossl) pg_hba.conf の書式 local データベース名ユーザ名 認証方式 host データベース名ユーザ名 IPアドレス範囲認証方式 hostssl データベース名ユーザ名 IPアドレス範囲認証方式 hostnossl データベース名ユーザ名 IPアドレス範囲認証方式 おもな認証方式 認証方式 trust/reject 無条件で許可 / 拒否 説明 scram-sha-256 SCRAM 暗号化でパスワード認証 (10 以降 ) md5 MD5 暗号化でパスワード認証 password 平文でパスワード認証 ( 非推奨 ) ident/peer cert OS とデータベースユーザ名との一致で認証 SSL クライアント証明書で認証 6
listen_addresses パラメータ クライアントからの接続を監視するサーバのアドレスを指定するパラメータ 設定例 listen_addresses = 'localhost,129.168.0.10' データベースサーバ TCP 接続 192.168.0.10 TCP 接続 192.168.1.10 クライアント クライアントではなく サーバのアドレスを指定 未指定のアドレスでは接続要求を受けつけない デフォルトは local でローカルホストのみ * ですべてのアドレスを監視 ネットワークインタフェースが複数ある場合 リモートホストからの接続を受けつける場合 クライアント ローカル接続 /var/run/postgresql/.s.pgsql.5432 不要な接続要求を防止するため 必要なアドレスのみを指定すべき クライアント 7
データベース内のセキュリティ 8
ロールの属性 ロールに対して設定する権限 / パスワード / パラメータ CREATE ROLE/ALTER ROLE で設定 パスワードの設定は 平文での送信を回避するため psql の password で行う スーパーユーザ権限 (SUPERUSER) データベース作成権限 (CREATEDB) ロール作成権限 (CREATEROLE) ログイン権限 (LOGIN) レプリケーション権限 (REPLICATION) RLS RLS 無視権限 (9.5 以降 ) (BYPASSRLS) パスワード (PASSWORD パスワード ) パラメータ (SET パラメータ名 TO 値 ) 実行例 =# CREATE ROLE alice LOGIN; -- ログイン権限をもつロールaliceを作成 =# ALTER ROLE alice CREATEDB; -- ロールaliceにデータベース作成権限を与える =# password alice -- ロールaliceのパスワードを設定 =# ALTER ROLE alice SET work_mem TO '8MB'; -- ロールaliceが接続時のwork_memパラメータを8MBに設定 9
データベースオブジェクトの権限 データベースオブジェクトに対してロールができる操作の権限 所有者のみが基本的にデフォルトですべての権限をもつ 実行例 所有者 alice テーブル accounts GRANT で権限を与え REVOKE で取り消す SELECT INSERT すべての操作 一般ユーザ bob スーパーユーザ postgres 所有者以外に操作を許可するには 権限を与える必要がある スーパーユーザは権限に関係なく すべての操作ができる => GRANT SELECT ON TABLE accounts TO bob; -- テーブルaccountsにロールbobのSELECT 権限を与える => dp accounts Schema Name Type Access privileges Column privileges Policies --------+----------+-------+---------------------+-------------------+---------- public accounts table alice=arwddxt/alice+ aliceはすべての権限 (arwddxt) をもつ bob=r/alice bobはselect 権限 (r) をもつ 権限はaliceによって与えられた 10
おもなデータベースオブジェクトの権限一覧 データベースオブジェクト 権限 操作 データベースオブジェクト 権限 操作 テーブル / 列 / ビュー / 外部テーブル (TABLE) シーケンス (SEQUENCE) SELECT(r) INSERT(a) SELECT COPY TO INSERT COPY FROM UPDATE(w) UPDATE SELECT... FOR UPDATE/SHARE DELETE(d) TRUNCATE(D) REFERENCES(x) TRIGGER(t) USAGE(U) SELECT(r) UPDATE(w) DELETE TRUNCATE 外部キー制約作成 トリガ作成 currval nextval 関数実行 currval 関数実行 nextval setval 関数実行 データベース (DATABASE) 関数 / プロシージャ (FUNCTION) スキーマ (SCHEMA) テーブル空間 (TABLESPACE) CREATE(C) CONNECT(c) TEMPORARY(T) EXECUTE(X) CREATE(C) USAGE(U) CREATE(C) データベース内にスキーマ作成 データベース接続 データベース内に一時テーブル作成 関数 プロシージャ 演算子実行 スキーマ内にオブジェクト作成 スキーマ内のオブジェクトアクセス テーブル空間内にテーブル インデックス 一時ファイル作成 データベースの CONNECT TEMPORARY 権限 関数 / プロシージャの EXECUTE 権限 手続き言語 データ型 / ドメインの USAGE 権限はデフォルトですべてのユーザに与えられる 11
デフォルトロール スーパーユーザのみができる操作の権限を部分的に与えるためのロール (9.6 以降 ) ロール 操作 pg_read_all_settings すべてのパラメータを参照できる (10 以降 ) pg_read_all_stats すべての統計情報を参照できる (10 以降 ) pg_stat_scan_tables ACCESS SHAREロックを長時間取得する統計情報関数を実行できる (10 以降 ) pg_signal_backend サーバプロセスにシグナルを送信できる pg_read_server_files データベースサーバ上のファイルを読み取りできる (11 以降 ) pg_write_server_files データベースサーバ上のファイルに書き込みできる (11 以降 ) pg_execute_server_program データベースサーバ上のプログラムを実行できる (11 以降 ) pg_monitor pg_read_all_settings + pg_read_all_stats + pg_stat_scan_tablesと同じ (10 以降 ) 実行例 =# ALTER ROLE pg_monitor TO bob; -- ロール bob にデフォルトロール pg_monitor の権限を与える =# du bob Role name Attributes Member of -----------+------------+-------------- bob {pg_monitor} 12
public スキーマ デフォルトで存在するスキーマ すべてのユーザがデータベースオブジェクトを作成できる デフォルトで検索パスに含まれる public スキーマ ユーザ定義関数 lower(varchar) pg_catalog スキーマ 組み込み関数 lower(text) 攻撃を回避するには public スキーマに対するすべてのユーザの CREATE 権限を取り消す =# REVOKE CREATE -# ON SCHEMA public FROM PUBLIC; 作成 悪意のあるユーザ 実行 スーパーユーザ postgres 組み込み関数を実行しようとして 意図せずユーザ定義関数が実行されてしまう スキーマの検索パスから public スキーマを取り除く =# SET search_path TO '$user'; データベースオブジェクトのスキーマ名を明示的に指定する =# SELECT pg_catalog.lower(email) -# FROM accounts; 13
行単位セキュリティ (RLS) テーブルに対してロールが操作できる行を制限する仕組み (9.5 以降 ) 一般ユーザ bob グループロール managers 操作 操作 manager = bob テーブルの権限に追加して設定 操作できない行を参照しようとしても 可視できないだけで エラーにならない TRUNCATE など テーブル全体への操作は対象外 実行例 RLS ポリシー テーブル accounts =# ALTER ROLE managers TO bob; -- グループロールmanagersにロールbobを追加 =# ALTER TABLE accounts -- テーブルaccountsの行単位セキュリティを有効にする -# ENABLE ROW LEVEL SECURITY; =# CREATE POLICY account_managers -- テーブルaccountsにグループロールmanagersのメンバが -# ON accounts TO managers -- 自分がマネージャになっている行のみを操作できるように -# USING (manager = current_user); -- RLSポリシーを作成 14
そのほかのセキュリティ 15
データ暗号化 データベースに格納するデータを暗号化 おもなデータ暗号化の実現方式 pgcrypto モジュール 暗号化関数を提供する付属モジュール TDE for PG pgcryptoをベースにtde 機能を提供するモジュール T 暗号化データ型 ユーザ 暗号化関数 テーブル ユーザ テーブル暗号化キー 暗号化関数 PowerGres Plus TDE 機能を追加した PostgreSQL ベースの商用製品 ecryptfs/encfs/dm-crypt + LUKS 様々な暗号化ファイルシステム ユーザ テーブル暗号化キー ファイル ユーザ テーブルファイルディスク 16
監査ログ 不正アクセスの検出のため データベースの操作を記録したログ 設定例 log_destination = 'csvlog' log_connections = on log_disconenctions = on log_statement = all 操作 データベースサーバ ログ出力 # CSV 形式でログを取得 # 接続のログを記録 # 切断のログを記録 # すべてのSQLをログに記録 テーブル CSV 形式で出力したログをテーブルにインポートすれば SQL で検索できる 監査 OS の機能と組み合わせれば ログの設定でもある程度実現できる 監査ログ専用の機能ではないため 要件によっては pgadudit モジュールの導入が必要 pgaudit を使用すれば 取得対象の SQL の詳細な種類や テーブル / 列を指定できる 操作対象の完全なテーブル名や SQL のパラメータを取得できる ユーザ ログファイル インポート スーパーユーザ 17
オープンソースとともに 18