セキュリティ

データベースのセキュリティ対策は、データベースが保持する情報の機密性、整合性、可用性を確保し、不正アクセスやデータ損失などのセキュリティインシデントを最小限に抑える必要があります。
データベースのセキュリティで考慮すべきは以下になります。

インテグリティ

インテグリティとは、データの整合性や信頼性を確保することです。
セキュリティの一環であり、データが予期しない状態で保持されないことを目的とします。
データベースのインテグリティでは次の方法があります。

PostgreSQLでのセキュリティ対応

PostgreSQLでのセキュリティ対応について記述します。
「pg_hba.conf」で設定することが可能で、初期設定ではローカルからの接続のみが可能になっています。
これであれば、OSにログインできない限りはアクセスできませんが、環境によってはネットワーク経由でのアクセスが必要になったりします。
その場合、ROLEにアクセス可能なデータベースなどを適正設定し、接続タイプを「hostssl」の設定をすることで、セキュアな接続になりデータ盗聴の対策にもなります。
SSL証明書なども確認できます。
以下が、「pg_hba.conf」の中身で最初(Local、host)が接続タイプになります。
次(postgres,all)がデータベースで次(user,all)がユーザになります。
その次(空白、127.0.0.1)がアクセス可能なIPアドレスで、最後が認証方式(trustは許可)です。
[pg_hba.conf]
# "local" is for Unix domain socket connections only
Local postgres user trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust

また、データベースのデータでパスワードなどは暗号化して参照させたくない運用が考えられます。
その場合、contrib/pgcryptoなどの関数を使用することで暗号化したデータを保存することができます。
PostgreSQLで考えられるセキュリティに次のことが考えられます。

1. クライアント認証
2. 通信経路暗号化
3. データ暗号化
4. ログ

【1. クライアント認証】
クライアントからPostgresに通信するときに誰もがアクセスできてしまうと不正な人物がアクセスされ情報漏えいやデータ破損などの恐れがあります。
クライアント毎に認証を設定することでその対策が行えます。
データベースクラスタ(/var/lib/pgsql/9.6/data)内のpg_hba.confがクライアント認証の設定ファイルです。
設定方法は、TYPE、DATABASE、USER、ADDRESS、METHODを区切って記載します。
各設定方法の詳細を次に記載いたします。

[TYPE]
local
→Unixドメインのソケット通信
host
→平分またはSSLでの通信
hostssl
→SSLオンリー通信
hostnossl
→平分オンリー通信

[DATABASE]
all
→全てのデータベース
sameuser
→接続ユーザと同じ名前のデータベース
samerole
→接続ロールと同じ名前のデータベース
replication
→レプリケーション専用
データベース名
→指定したデータベース

[USER]
all
→全てのユーザ
ロール名またはグループ名
→指定したロールまたはグループ名(+またはカンマで区切って複数設定可能)

[ADDRESS]
IPv4またはIPv6アドレス
→接続元のIPアドレスを指定します。(prefix長での範囲指定可能)
[METHOD]
trust
→無条件で許可
reject
→無条件で拒否
md5
→パスワード認証(md5ハッシュで比較)
password
→パスワード認証(平文)
cert
→SSL証明書にて認証
認証方式
→idnent,ldap、radius、sspi、gss、pam、peerなどの外部認証

192.168.0.0/24の全てのネットワークからSSLのみ接続を許可する場合は次の様に記載します。
ssl all all 192.168.0.0/24 trust

【2. 通信経路暗号化】
クライアントからPostgresにはTCPで通信しますが、標準の設定では通信は平文のためデータが傍受されてしまうと情報漏えいが発生いたします。
PostgreSQLにはSSLを利用して暗号化した通信を行うことで対策になります。
※SSLで通信する場合、クライアント・サーバのOSに事前にOpenSSLが必要になります。
インストール跡もPostgresの設定で、SSLのサポートを有効にする必要があります。
また、SSLを利用する場合、SSL証明証が必要になります。
SSL証明書は次のファイルに保存します。

サーバ証明書
データベースクラスタ(/var/lib/pgsql/9.6/data)/server.crt
サーバ秘密鍵
データベースクラスタ(/var/lib/pgsql/9.6/data)/server.key

SSL証明書を利用する場合、Postgresの設定ファイルを次のように修正します。

[postgresql.conf]
⇒ssl = on
[pg_hba.conf]
hostssl all all 0.0.0.0/0 md5

証明書の作成方法は以下になります。

1. データベースクラスタに移動
# cd /var/lib/pgsql/9.6/data

2.OpenSSLでRSAの秘密鍵を作成
# openssl genrsa 2048 > server.key
※2048はビット数

3.OpenSSLでCSRを作成
# openssl req -new -key server.key > server.csr

4.OpenSSLで証明書を作成
# openssl x509 -days 36500 -req -signkey server.key < server.csr > server.crt
※36500は有効期限(この場合100年)

5.作成したファイルの所有権・グループを変更
# chown postgres:postgres server.*

6.server.keyのアクセス権限変更
# chmod 600 server.key

[3. データ暗号化]
データベース内のデータを暗号化するにはcontribモジュールの1つであるpgcryptoを利用することで対応可能です。
詳細はこちらでご確認ください。
※conntribモジュールがインストールされている前提で記載いたします。
次のコマンドを実行します。(DB名は利用者のデータベース名)
#psql -f /usr/pgsql-9.6/share/extension/pgcrypto--1.3.sql [DB名]

postgres=# CREATE EXTENSION pgcrypto;

postgres=# select digest('test','MD5')
postgres-# ;
digest
------------------------------------
\x098f6bcd4621d373cade4e832627b4f6

ハッシュ関数一覧を次に記載します。

digest(data text, type text) returns bytea
digest(data bytea, type text) returns bytea
hmac(data text, key text, type text) returns bytea
hmac(data bytea, key text, type text) returns bytea
crypt(password text, salt text) returns text
gen_salt(type text [, iter_count integer ]) returns text
pgp_sym_encrypt(data text, psw text [, options text ]) returns bytea
pgp_sym_encrypt_bytea(data bytea, psw text [, options text ]) returns bytea
pgp_sym_decrypt(msg bytea, psw text [, options text ]) returns text
pgp_sym_decrypt_bytea(msg bytea, psw text [, options text ]) returns bytea
pgp_pub_encrypt(data text, key bytea [, options text ]) returns bytea
pgp_pub_encrypt_bytea(data bytea, key bytea [, options text ]) returns bytea
pgp_pub_decrypt(msg bytea, key bytea [, psw text [, options text ]]) returns text
pgp_pub_decrypt_bytea(msg bytea, key bytea [, psw text [, options text ]]) returns bytea

データの暗号化とは違うのですが、「データチェックサム」をPostgreSQLで利用可能です。
利用するとPostgreSQLのデータブロックで破損した場合、検出します。
データベースクラスタ作成時のコマンドであるinitdbにオプションを付けるとデータチェックサムが有効になります。
チェックサムはデータベースクラスタ全体ではなく、データをブロックに書き出す時に行います。
オプションは「-k」または、「--data-checksums」です。
※後から設定を変更することはできないので注意が必要です。
※データベースクラスタ全体を行いたい場合、OS側で行う必要があります。
※pg_controldataで確認することができます。