★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

18.9. SSLによる安全なTCP/IP接続

PostgreSQLは標準でSSL接続をサポートし、クライアント/サーバの通信がさらに安全になるよう暗号化します。 そのためにはOpenSSLがクライアントとサーバシステムの両方にインストールされ、構築時にPostgreSQLにおけるそのサポートが有効になっている必要があります(第16章を参照してください)。

18.9.1. 基本的な設定

SSLサポートを有効にしてコンパイルされた場合、PostgreSQLサーバは、postgresql.confにおいてsslパラメータをonにすることで、SSLサポートを有効にして起動することができます。 サーバは同じTCPポートで通常の接続とSSL接続の両方を待ち受け、クライアントとの接続にSSLを使用するかどうかを調停します。 デフォルトでは、これはクライアント側の選択肢です。 一部またはすべての接続でSSLの使用を必要とさせるためのサーバ側の設定方法に関しては20.1を参照してください。

SSLモードで起動するには、サーバ証明書と秘密鍵を含むファイルが存在していなければなりません。 デフォルトでは、これらのファイルはserver.crtおよびserver.keyという名前で、それぞれがサーバのデータディレクトリに存在していることが想定されていますが、設定パラメータのssl_cert_filessl_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にルート証明書を追加する必要はありません。 代わりに、クライアントはサーバ証明書のチェーンのルート証明書を持っていなければなりません。

18.9.2. OpenSSLの設定

PostgreSQLはシステム全体のOpenSSL設定ファイルを読み込みます。 デフォルトでは、このファイルはopenssl.cnfという名前で、openssl version -dが報告するディレクトリに設置されます。 このデフォルトはOPENSSL_CONF環境変数を設定することによって希望の名前に置き換えることができます。

OpenSSLは様々な強度を持つ、多様な暗号と認証アルゴリズムをサポートしています。 暗号のリストはOpenSSLの設定ファイルで指定できますが、使用するデータベースサーバ用にpostgresql.confssl_ciphersで指定することができます。

注記

NULL-SHAあるいはNULL-MD5暗号を使って暗号化のオーバーヘッドがない認証を行うことができます。 しかし、中間者がクライアントとサーバの間のコミュニケーションを読んで転送することができます。 また、認証のオーバーヘッドに比べると暗号化のオーバーヘッドは最小限です。 これらの理由から、NULL暗号はお勧めできません。

18.9.3. クライアント証明書の使用

信頼できる証明書をクライアントに要求するには、信頼するルート認証局(CA)の証明書をデータディレクトリ内のファイルに置き、postgresql.confssl_ca_fileパラメータを設定し、認証オプションclientcert=verify-caまたはclientcert=verify-fullpg_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.confhostsslとして指定された行でのみ有効です。 clientcertが指定されていない、またはno-verifyと設定されている場合でも、認証局のリストが設定されていれば、サーバはその認証局に対してクライアント証明書の検証を行いますが、クライアント証明書を提示することを要求しません。

ユーザに対してログイン中に証明書を提供するように強制する二つのアプローチがあります。

最初のアプローチはpg_hba.confhostsslcert認証メソッドを使うことです。 そうすることによりSSL接続によるセキュリティが提供されるとともに、証明書自身が認証に使われます。 詳細は20.12をご覧ください。 (cert認証メソッドを使う際には明示的にclientcertオプションを指定する必要はありません。) この場合証明書が提供するcn (Common Name)がユーザ名あるいは適用可能なマッピングに対して検証されます。

二番目のアプローチは、clientcert認証オプションにverify-caあるいはverify-fullを設定することによってhostsslエントリの認証メソッドにクライアント証明書の検証を組み合わせることです。 前者のオプションは証明書が有効であることだけを強制し、後者は更に証明書のcn (Common Name)がユーザ名あるいは適用可能なマッピングと一致することを強制します。

18.9.4. サーバにおけるSSL関連ファイルの利用

表 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接続を確立出来ません。 これらのすべてのケースでは、エラー状態がサーバログに記録されます。

18.9.5. 証明書の作成

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.crtserver.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.crtintermediate.crtは証明書ファイルに束ねて連結し、サーバに格納する必要があります。 server.keyもまたサーバに格納される必要があります。 サーバのリーフ証明書が信頼されたルート証明書にリンクされた一連の証明書によって署名されていることをクライアントが確認できるように、root.crtをクライアントに格納する必要があります。 root.keyintermediate.keyは将来の証明書を作成に使用するためにオフラインで格納する必要があります。