PostgreSQLは標準でSSL接続をサポートし、クライアント/サーバの通信がさらに安全になるよう暗号化します。 そのためにはOpenSSLがクライアントとサーバシステムの両方にインストールされ、構築時にPostgreSQLにおけるそのサポートが有効になっている必要があります(第16章を参照してください)。
SSLサポートを有効にしてコンパイルされた場合、PostgreSQLサーバは、postgresql.conf
においてsslパラメータをon
にすることで、SSLサポートを有効にして起動することができます。
サーバは同じTCPポートで通常の接続とSSL接続の両方を待ち受け、クライアントとの接続にSSLを使用するかどうかを調停します。
デフォルトでは、これはクライアント側の選択肢です。
一部またはすべての接続でSSLの使用を必要とさせるためのサーバ側の設定方法に関しては20.1を参照してください。
SSLモードで起動するには、サーバ証明書と秘密鍵を含むファイルが存在していなければなりません。
デフォルトでは、これらのファイルはserver.crt
およびserver.key
という名前で、それぞれがサーバのデータディレクトリに存在していることが想定されていますが、設定パラメータのssl_cert_fileとssl_key_fileによって他の名前、他の場所を指定することもできます。
Unixシステムでは、server.key
の権限は所有者以外からのアクセスを許可してはなりません。
これはchmod 0600 server.key
というコマンドで実現できます。
あるいは、このファイルの所有者をrootにして、グループに読み取りアクセス権を与える(つまり、パーミッションを0640
にする)ということもできます。
この設定は、証明書と鍵ファイルがオペレーティングシステムによって管理されるインストレーションのためのものです。
PostgreSQLサーバを実行するユーザは、証明書と鍵ファイルにアクセス権のあるグループのメンバーにする必要があります。
データディレクトリがグループアクセスを許可している場合、証明書ファイルは上記のセキュリティ上の要求を満たすためにデータディレクトリ外に置く必要があるかも知れません。 一般に、グループアクセスは権限を持たないユーザがデータベースをバックアップできるように有効化されます。 この場合、バックアップソフトウェアは証明書を読むことができず、おそらくエラーとなるでしょう。
秘密鍵がパスフレーズで保護されている場合、サーバはパスフレーズの入力を促し、入力されるまでは起動しません。 パスフレーズを使用すると、サーバを再起動せずにサーバのSSL設定を変更する機能はデフォルトで無効になりますが、ssl_passphrase_command_supports_reloadを参照してください。 さらに、パスフレーズで保護された秘密鍵は、Windowsではまったく使用できません。
server.crt
の最初の証明書は、サーバ証明書になり、秘密鍵とマッチしなければなりません。
「中間」認証局の証明書をファイルに追加することもできます。
これにより、ルートと中間証明書がv3_ca
拡張により作成されていることが前提になりますが、中間証明書をクライアントに保存する必要が無くなります。
(これにより、CA
の証明書の基本制約がtrue
に設定されます。)
これは、中間証明書の有効期限の扱いをより簡単にします。
server.crt
にルート証明書を追加する必要はありません。
代わりに、クライアントはサーバ証明書のチェーンのルート証明書を持っていなければなりません。
PostgreSQLはシステム全体のOpenSSL設定ファイルを読み込みます。
デフォルトでは、このファイルはopenssl.cnf
という名前で、openssl version -d
が報告するディレクトリに設置されます。
このデフォルトはOPENSSL_CONF
環境変数を設定することによって希望の名前に置き換えることができます。
OpenSSLは様々な強度を持つ、多様な暗号と認証アルゴリズムをサポートしています。
暗号のリストはOpenSSLの設定ファイルで指定できますが、使用するデータベースサーバ用にpostgresql.conf
のssl_ciphersで指定することができます。
NULL-SHA
あるいはNULL-MD5
暗号を使って暗号化のオーバーヘッドがない認証を行うことができます。
しかし、中間者がクライアントとサーバの間のコミュニケーションを読んで転送することができます。
また、認証のオーバーヘッドに比べると暗号化のオーバーヘッドは最小限です。
これらの理由から、NULL暗号はお勧めできません。
信頼できる証明書をクライアントに要求するには、信頼するルート認証局(CA)の証明書をデータディレクトリ内のファイルに置き、postgresql.conf
のssl_ca_fileパラメータを設定し、認証オプションclientcert=verify-ca
またはclientcert=verify-full
をpg_hba.conf
の適切なhostssl
行に追加します。
そうすると、SSL接続の開始時にクライアントへ証明書が要求されます。
(クライアント上での証明書の設定方法については33.18を参照してください。)
clientcert=verify-ca
指定付きのhostssl
エントリでは、サーバは、クライアントの証明書が信頼する認証局のいずれかにより署名されていることを検証します。
clientcert=verify-full
が指定されていると、サーバは証明書チェーンを検証するだけでなく、ユーザ名あるいはユーザ名のマッピングが提供された証明書のcn
(Common Name)に一致しているかどうかも検証します。
cert
認証メソッドが使われている場合は認証チェーンの検証は常に行われることに注意してください。
(20.12参照。)
既存のルート証明書に連鎖する中間証明書は、クライアントに保存することを避けたい場合にssl_ca_fileに含めることができます(ルート証明書と中間証明書がv3_ca
拡張で作成されている場合)。
ssl_crl_fileパラメータが設定されている場合、証明書失効リスト(CRL)項目も検査されます。
認証オプションclientcert
はすべての認証方式について利用可能ですが、pg_hba.conf
のhostssl
として指定された行でのみ有効です。
clientcert
が指定されていない、またはno-verify
と設定されている場合でも、認証局のリストが設定されていれば、サーバはその認証局に対してクライアント証明書の検証を行いますが、クライアント証明書を提示することを要求しません。
ユーザに対してログイン中に証明書を提供するように強制する二つのアプローチがあります。
最初のアプローチはpg_hba.conf
のhostssl
にcert
認証メソッドを使うことです。
そうすることによりSSL接続によるセキュリティが提供されるとともに、証明書自身が認証に使われます。
詳細は20.12をご覧ください。
(cert
認証メソッドを使う際には明示的にclientcert
オプションを指定する必要はありません。)
この場合証明書が提供するcn
(Common Name)がユーザ名あるいは適用可能なマッピングに対して検証されます。
二番目のアプローチは、clientcert
認証オプションにverify-ca
あるいはverify-full
を設定することによってhostssl
エントリの認証メソッドにクライアント証明書の検証を組み合わせることです。
前者のオプションは証明書が有効であることだけを強制し、後者は更に証明書のcn
(Common Name)がユーザ名あるいは適用可能なマッピングと一致することを強制します。
表 18.2にて、サーバにおけるSSLの設定に関連するファイルをまとめます。 (表示されているファイル名はデフォルトまたは一般的な名前です。異なる名前を個別に設定することもできます。)
表18.2 SSLサーバファイルの使用方法
ファイル | 内容 | 影響 |
---|---|---|
ssl_cert_file ($PGDATA/server.crt ) | サーバ証明書 | サーバの身元を示すためにクライアントに送信します |
ssl_key_file ($PGDATA/server.key ) | サーバの秘密鍵 | サーバ証明書が所有者によって送られたことを証明します。証明書所有者が信頼できることを意味しません。 |
ssl_ca_file | 信頼できる認証局 | 信頼する認証局により署名されたクライアント証明書か検査します。 |
ssl_crl_file | 認証局により失効された証明書 | クライアント証明書はこの一覧にあってはいけません。 |
サーバは、サーバ起動時及びサーバ設定がリロードされるたびに、これらのファイルを読み取ります。 Windowsシステム上では新しいクライアント接続のために新しいバックエンドプロセスが生成されるたびに再読み込みされます。
サーバ起動時にこれらのファイルのエラーが検出された場合、サーバは起動を拒否します。 ただし、設定のリロード中にエラーが検出された場合、ファイルは無視され、古いSSL設定が引き続き使用されます。 Windowsシステム上ではバックエンドの開始時にこれらのファイルのエラーが検出された場合、そのバックエンドはSSL接続を確立出来ません。 これらのすべてのケースでは、エラー状態がサーバログに記録されます。
365日有効なサーバ用の自己署名証明書を簡単に作るためには下記のOpenSSLコマンドを実行してください(dbhost.yourdomain.com
をサーバのホスト名に置き換えてください)。
openssl req -new -x509 -days 365 -nodes -text -out server.crt \
-keyout server.key -subj "/CN=dbhost.yourdomain.com
"
続けて以下も実行します。
chmod og-rwx server.key
サーバの秘密鍵および証明書を作成するための詳しい方法についてはOpenSSLの文書を参照してください。
テストには自己署名証明書を使用できますが、運用時は認証局(CA)(通常は事業全体のCA)により署名された証明書を使用する必要があります。
クライアントが身元を検証できるサーバ証明書を作成するには、まず最初に証明書署名要求(CSR) と公開/秘密鍵を作成します。
openssl req -new -nodes -text -out root.csr \
-keyout root.key -subj "/CN=root.yourdomain.com
"
chmod og-rwx root.key
その後、鍵を使用して署名要求に署名しルート証明書を作成します(Linux上のデフォルトのOpenSSL設定ファイルの場所を使用)。
openssl x509 -req -in root.csr -text -days 3650 \ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ -signkey root.key -out root.crt
最後に、新しいルート証明書によって署名されるサーバ証明書を作成します。
openssl req -new -nodes -text -out server.csr \
-keyout server.key -subj "/CN=dbhost.yourdomain.com
"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
-CA root.crt -CAkey root.key -CAcreateserial \
-out server.crt
server.crt
とserver.key
をサーバに格納し、root.crt
をクライアントに格納します。
クライアントはサーバのリーフ証明書が信頼されたルート証明書によって署名されたことを確認できます。
root.key
は将来の証明書の作成に使用するために、オフラインで保存する必要があります。
中間証明書が含まれる信頼の連鎖を作成することも可能です。
# root openssl req -new -nodes -text -out root.csr \ -keyout root.key -subj "/CN=root.yourdomain.com
" chmod og-rwx root.key openssl x509 -req -in root.csr -text -days 3650 \ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ -signkey root.key -out root.crt # intermediate openssl req -new -nodes -text -out intermediate.csr \ -keyout intermediate.key -subj "/CN=intermediate.yourdomain.com
" chmod og-rwx intermediate.key openssl x509 -req -in intermediate.csr -text -days 1825 \ -extfile /etc/ssl/openssl.cnf -extensions v3_ca \ -CA root.crt -CAkey root.key -CAcreateserial \ -out intermediate.crt # leaf openssl req -new -nodes -text -out server.csr \ -keyout server.key -subj "/CN=dbhost.yourdomain.com
" chmod og-rwx server.key openssl x509 -req -in server.csr -text -days 365 \ -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \ -out server.crt
server.crt
とintermediate.crt
は証明書ファイルに束ねて連結し、サーバに格納する必要があります。
server.key
もまたサーバに格納される必要があります。
サーバのリーフ証明書が信頼されたルート証明書にリンクされた一連の証明書によって署名されていることをクライアントが確認できるように、root.crt
をクライアントに格納する必要があります。
root.key
とintermediate.key
は将来の証明書を作成に使用するためにオフラインで格納する必要があります。