システム権限
• 注意すべき権限
– rolsuperはすべての権限管理より優先する権限
–rolcreateroleは任意の権限(super除く)を持ったロールを作成可能
– rolcanloginはログイン可能な権限
データベースは rolcreatedb で作れても、EXTENSIONのインストールは
rolsuper が必要だったりするが・・・
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 13
‐‐ データベースの作成・削除が可能な admin_r ロールを作成
CREATE ROLE admin_r NOSUPERUSER CREATEDB NOCREATEROLE INHERIT
NOLOGIN NOREPLICATION;
‐‐ データベースやロールの作成などが⼀切できない webapp_r ロールを作成
CREATE ROLE webapp_r NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT
NOLOGIN NOREPLICATION
‐‐ ユーザ snaga を作成して admin_r ロールに割り当てる
CREATE ROLE snaga LOGIN INHERIT IN ROLE admin_r;
‐‐ ユーザ webapp を作成して webapp_r ロールに割り当てる
CREATE ROLE webapp LOGIN INHERIT IN ROLE webapp_r;
14.
システム権限の獲得
• 所属しているロールのシステム権限を得るにはSET ROLEを使う
–接続直後には、他のロールのシステム権限は持っていない。
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 14
postgres=> select
rolname,rolsuper,rolcreatedb from pg_roles;
rolname | rolsuper | rolcreatedb
‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐
postgres | t | t
webapp | f | f
webapp_r | f | f
snaga | f | f
admin_r | f | t
(5 rows)
postgres=> select current_user;
current_user
‐‐‐‐‐‐‐‐‐‐‐‐‐‐
snaga
(1 row)
postgres=> create database testdb;
ERROR: permission denied to create
database
postgres=>
postgres=> set role admin_r;
SET
postgres=> select current_user;
current_user
‐‐‐‐‐‐‐‐‐‐‐‐‐‐
admin_r
(1 row)
postgres=> create database testdb;
CREATE DATABASE
postgres=>
権限を持っていないユーザー snaga が、
admin_rに昇格してデータベースを作成。
→ 必要な時だけ権限を獲得する
15.
ロールとアクセス制御の設定例
• ロールの設定
– postgresロール以外はロール操作権限なし。
–(管理者含む)⼀般のロールとpostgresロールは分離。SET ROLEも不可。
• pg_hba.confの設定
– ローカル(Unix domain socket)からの接続はすべてMD5認証。
– リモート(TCP/IP)からの postgres ユーザの接続はすべて拒否。
– リモート(127.0.0.1 or 10.0.2.0/24)からの他のユーザの接続はすべてMD5認証。
• 結果、ロールの操作はpostgresユーザでローカルから直接接続した場合のみ。
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 15
postgres=> ¥du
List of roles
Role name | Attributes | Member of
‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐
admin_r | Create DB, Cannot login | {}
postgres | Superuser, Create role, Create DB, Replication | {}
snaga | No inheritance | {admin_r}
webapp | No inheritance | {webapp_r}
webapp_r | No inheritance, Cannot login | {}
local all all md5
host all postgres 0.0.0.0/0 reject
host all all 127.0.0.1/32 md5
host all all 10.0.2.0/24 md5
テーブルにおける権限設定
• テーブルとビューの権限の分離
• ⾏レベルの権限制御
–ビューによる制御
– RLSによる制御
• 列レベルセキュリティ
– ビューによる制御
– GRANT TABLE COLUMN
• トリガーによる更新の制御
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 24
25.
テーブルとビューの権限の分離
• テーブルとビューには別々に権限を付与できる
– 単⼀のテーブルでもユーザによって権限を制御可能
Copyright2015 Uptime Technologies, LLC. All rights reserved. 25
testdb=> CREATE TABLE t1 AS SELECT rolname,rolsuper,rolcreaterole,rolcreatedb
FROM pg_roles;
SELECT 5
testdb=> CREATE VIEW v1 AS SELECT * FROM t1;
CREATE VIEW
testdb=> grant select on v1 to webapp_r;
GRANT
testdb=> ¥dp t1
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
‐‐‐‐‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
public | t1 | table | |
(1 row)
testdb=> ¥dp v1
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
‐‐‐‐‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
public | v1 | view | snaga=arwdDxt/snaga+|
| | | webapp_r=r/snaga |
(1 row)
26.
テーブルとビューの権限の分離
• ビューは参照可能だが、テーブルは参照不可
Copyright 2015Uptime Technologies, LLC. All rights reserved. 26
You are now connected to database "testdb" as user "webapp".
testdb=> select * from t1;
ERROR: permission denied for relation t1
testdb=> select * from v1;
rolname | rolsuper | rolcreaterole | rolcreatedb
‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐
postgres | t | t | t
webapp | f | f | f
webapp_r | f | f | f
snaga | f | f | f
admin_r | f | f | t
(5 rows)
testdb=>
27.
ビューによる⾏レベルの制御
• どのような⾏を⾒せるかをビューの条件で制御する
• 例えば、実効ロールと⼀致する⾏だけ⾒せたい場合
Copyright2015 Uptime Technologies, LLC. All rights reserved. 27
postgres=> CREATE VIEW pg_all_roles AS SELECT * FROM pg_roles WHERE rolname =
current_user;
CREATE VIEW
ostgres=> SELECT rolname,rolsuper,rolcreaterole,rolcreatedb FROM pg_all_roles;
rolname | rolsuper | rolcreaterole | rolcreatedb
‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐
snaga | f | f | f
(1 row)
postgres=> SET ROLE admin_r;
SET
postgres=> SELECT rolname,rolsuper,rolcreaterole,rolcreatedb FROM pg_all_roles;
rolname | rolsuper | rolcreaterole | rolcreatedb
‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐
admin_r | f | f | t
(1 row)
28.
⾏レベルセキュリティ(RLS)
• ⾏レベルセキュリティ(Row LevelSecurity; RLS)
– テーブルに含まれるどの⾏が返却されるべきか、という、アク
セスポリシーの定義を可能にする
– デフォルトでは無効化されている
– CREATE POLICY, ALTER POLICY, DROP POLICY
• 制約
– PostgreSQL 9.5からの機能
– 現時点では、システムカタログには適⽤できない
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 28
29.
実⾏例
• CREATE POLICYroles_table_policy1 ON roles_table
FOR ALL USING (rolname = current_user);
ユーザ名でフィルタするように
ポリシーを定義
ビューによる列レベルの制御
• 参照させたくない列を除いた、または別のデータにマス
クしたビューを定義する
– 例:システムビューのpg_roles (pg_authidを使ったビュー)
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 31
testdb=> ¥d+ pg_roles;
Column | Type | Modifiers | Storage | Description
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐
rolname | name | | plain |
(...snip...)
rolconnlimit | integer | | plain |
rolpassword | text | | extended |
rolvaliduntil | timestamp with time zone | | plain |
(...snip...)
View definition:
SELECT pg_authid.rolname,
(...snip...)
pg_authid.rolconnlimit,
'********'::text AS rolpassword,
pg_authid.rolvaliduntil,
(...snip...)
FROM pg_authid
LEFT JOIN pg_db_role_setting s ON pg_authid.oid = s.setrole AND s.setdatabase =
0::oid;
32.
列レベルセキュリティ
• テーブルの特定のカラムだけ権限を設定する
– GRANT... ON <table> (<column>, ...) TO ...
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 32
postgres=> ¥c postgres snaga
Password for user snaga:
You are now connected to database
"postgres" as user "snaga".
postgres=> CREATE TABLE t1 AS SELECT * FROM
pg_database;
SELECT 4
postgres=> GRANT SELECT (datname) ON t1 TO
webapp_r;
GRANT
postgres=> ¥c postgres webapp
Password for user webapp:
You are now connected to database
"postgres" as user "webapp".
postgres=> SELECT datname FROM t1;
datname
‐‐‐‐‐‐‐‐‐‐‐
template1
template0
postgres
testdb
(4 rows)
postgres=> SELECT * FROM t1;
ERROR: permission denied for relation t1
postgres=> ¥d t1
Table "public.t1"
Column | Type | Modifiers
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐
datname | name |
datdba | oid |
encoding | integer |
datcollate | name |
datctype | name |
datistemplate | boolean |
datallowconn | boolean |
datconnlimit | integer |
datlastsysoid | oid |
datfrozenxid | xid |
datminmxid | xid |
dattablespace | oid |
datacl | aclitem[] |
postgres=>
実⾏例(1/2)
• テーブルの作成とデータ挿⼊
– すべての監査ログイベントを出⼒するように設定
–クライアント側にもログを表⽰するように設定して実⾏
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 42
testdb=# set client_min_messages to log;
SET
testdb=# create table k1 (uid integer primary key, uname text );
LOG: AUDIT,2015‐11‐27 11:46:56.526683+09,testdb,snaga,snaga,DEFINITION,CREATE
TABLE,TABLE,public.k1,create table k1 (uid integer primary key, uname text );
LOG: AUDIT,2015‐11‐27 11:46:56.546729+09,testdb,snaga,snaga,DEFINITION,CREATE
INDEX,INDEX,public.k1_pkey,create table k1 (uid integer primary key, uname text );
CREATE TABLE
testdb=# insert into k1 values (1, 'Park Gyu‐ri'),(2, 'Nicole Jung'),(3, 'Goo Ha‐
ra'),(4, 'Han Seung‐yeon'),(5, 'Kang Ji‐young');
LOG: AUDIT,2015‐11‐27
11:47:01.647673+09,testdb,snaga,snaga,WRITE,INSERT,TABLE,public.k1,insert into k1
values (1, 'Park Gyu‐ri'),(2, 'Nicole Jung'),(3, 'Goo Ha‐ra'),(4, 'Han Seung‐
yeon'),(5, 'Kang Ji‐young');
INSERT 0 5
testdb=#
43.
実⾏例(2/2)
• データの参照と権限の付与
Copyright 2015Uptime Technologies, LLC. All rights reserved. 43
testdb=# select * from k1;
LOG: AUDIT,2015‐11‐27 11:47:07.221334+09,testdb,snaga,snaga,READ,SELECT,TABLE,pub
lic.k1,select * from k1;
uid | uname
‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
1 | Park Gyu‐ri
2 | Nicole Jung
3 | Goo Ha‐ra
4 | Han Seung‐yeon
5 | Kang Ji‐young
(5 rows)
testdb=# grant select on k1 to public;
LOG: AUDIT,2015‐11‐27 11:47:11.328344+09,testdb,snaga,snaga,PRIVILEGE,GRANT,,,gra
nt select on k1 to public;
GRANT
testdb=#
44.
ログの収集と監査の実施
• 「コンプライアンス上、ログを残します」という要件は多いが…
– 本当に「監査」していますか?
–例えば、以下のようなエラーメッセージ
• FATAL: role "foo" does not exist
• FATAL: password authentication failed for user "postgres"
• FATAL: permission denied for database "postgres"
• ERROR: permission denied for relation orders
• セキュリティインシデントをすぐに検知できますか?
– 検知をしないと回復はできない
– 「実は半年前からデータを抜かれてました」(←よくある話)
• セキュリティコントロールの4機能
– 「抑⽌/予防/検知/回復」
– ⽇本の企業は「検知」と「回復」が弱い傾向(PwC 林⽒)
Copyright 2015 Uptime Technologies, LLC. All rights reserved. 44