PostgreSQL接続のSSL/TLS設定による保護:完全ガイド
今日の相互接続されたデジタル環境において、転送中のデータの保護は何よりも重要です。強力なオープンソースのリレーショナルデータベースであるPostgreSQLは、SSL/TLSを使用して接続を暗号化するための堅牢なメカニズムを提供します。本ガイドでは、PostgreSQLサーバーとクライアントの両方を設定してSSL/TLS暗号化を強制し、信頼できないネットワーク上での盗聴や中間者攻撃から機密情報を保護するための包括的な手順を説明します。これらのセキュリティ対策の導入は、データの整合性を維持し、厳格なセキュリティ標準への準拠を保証し、ユーザーからの信頼を築くために不可欠です。
本記事では、SSL証明書の生成または取得から、PostgreSQLの設定での利用、そして最後にセキュアな接続のためのクライアント設定まで、必要な手順を網羅します。効果的にこれらのセキュリティ強化を実施するために、必要な設定パラメーターの詳細と実用的な例を探ります。
PostgreSQLにおけるSSL/TLSの理解
SSL/TLS(Secure Sockets Layer/Transport Layer Security)は、コンピューターネットワーク経由での通信セキュリティを提供するために設計された暗号化プロトコルです。PostgreSQLに適用される場合、データベースサーバーとそのクライアント間で交換されるデータを暗号化します。これにより、認証情報、財務データ、個人情報などの機密情報が不正な第三者によって傍受され、読み取られるのを防ぎます。
PostgreSQLはSSL/TLSに関して主に2つのモードをサポートしています。
ssl=on: SSL接続を許可しますが、必須とはしません。クライアントはSSL接続または非SSL接続のいずれかを使用して接続できます。ssl=prefer: SSL接続の確立を試みますが、失敗した場合は非SSL接続にフォールバックします。ssl=require: SSL接続を要求します。SSL接続を確立できない場合、クライアント接続は拒否されます。
ssl=requireを強制することが、転送中のデータを保護するための最も安全なオプションです。
SSL/TLS設定の前提条件
PostgreSQLのSSL/TLS設定を開始する前に、以下のものが揃っていることを確認してください。
- OpenSSLのインストール: OpenSSLツールキットは、SSL証明書の生成と管理に不可欠です。通常、LinuxおよびmacOSシステムにはプリインストールされています。Windowsの場合は、別途ダウンロードしてインストールする必要があるかもしれません。
- PostgreSQL設定ファイルへのアクセス:
postgresql.confおよびpg_hba.confファイルを変更するには、管理者権限が必要です。 - 認証局(CA)に関する理解: テスト用に自己署名証明書を作成することも可能ですが、本番環境では信頼できる認証局(CA)または社内エンタープライズCAによって署名された証明書を使用することが理想的です。
サーバー側のSSL/TLS設定
サーバー側の設定には、SSLの有効化、SSL証明書とキーの場所の指定、およびクライアント認証の設定が含まれます。
1. SSL証明書とキーの生成または取得
PostgreSQLサーバー用のSSL証明書を取得するには、主に2つの方法があります。
- 自己署名証明書(テスト/開発用): これらはOpenSSLを使用して作成され、外部クライアントからはデフォルトで信頼されません。初期設定および内部テストに役立ちます。
- 認証局(CA)からの証明書(本番用): 信頼できる公開CA(例:Let's Encrypt、DigiCert)または社内エンタープライズCAから証明書を取得します。これにより、クライアントがサーバーの身元を確認できるようになります。
OpenSSLを使用した自己署名証明書の作成:
これは開発環境および内部環境で一般的に使用されるアプローチです。PostgreSQLサーバーまたはOpenSSLがインストールされているマシンで、以下のコマンドを実行します。
-
証明書用のディレクトリ作成: 証明書を整理しておくことは良い習慣です。
bash sudo mkdir -p /etc/postgresql/ssl sudo chown postgres:postgres /etc/postgresql/ssl cd /etc/postgresql/ssl -
サーバー秘密鍵の生成: このキーは秘密に保つ必要があります。
bash sudo openssl genrsa -des3 -out server.key 2048
パスフレーズの入力を求められます。PostgreSQLの起動時に必要になるため、このパスフレーズを覚えておいてください。 -
パスフレーズの削除(オプションだが自動再起動には推奨): 手動でのパスフレーズ入力なしで自動起動するためには、パスフレーズを削除します。このファイルへのアクセス権を持つ誰でもサーバーになりすます可能性があるため、細心の注意を払ってください。
bash sudo openssl rsa -in server.key -out server.key -
サーバー証明書署名要求(CSR)の作成: これにはサーバーに関する情報が含まれます。
bash sudo openssl req -new -key server.key -out server.csr
国名、都道府県名、市区町村名、組織名、共通名(これはサーバーのホスト名またはIPアドレスである必要があります)、およびメールアドレスなどの情報の入力を求められます。 -
自身のCAによる証明書への署名(内部使用の場合):
- ルートCAの秘密鍵と証明書の作成(まだ持っていない場合):
bash # CA秘密鍵の生成 sudo openssl genrsa -des3 -out root.key 2048 # CA証明書の作成(3650日間有効) sudo openssl req -new -x509 -days 3650 -key root.key -out root.crt - CAによるサーバーCSRへの署名: これにより、信頼されたサーバー証明書が作成されます。
bash sudo openssl x509 -req -days 365 -in server.csr -CA root.crt -CAkey root.key -set_serial 01 -out server.crt
- ルートCAの秘密鍵と証明書の作成(まだ持っていない場合):
-
パーミッションの設定: PostgreSQLユーザーがこれらのファイルを読み取れるようにします。
bash sudo chown postgres:postgres server.key server.crt root.crt sudo chmod 600 server.key sudo chmod 644 server.crt root.crt
公開/エンタープライズCAからの証明書の使用:
CAから証明書を取得する場合、通常以下のファイルを受け取ります。
server.crt: サーバーの公開証明書。server.key: サーバーの秘密鍵。root.crt(または同等のもの): CAのルート証明書(および中間証明書)。
これらのファイルを安全なディレクトリ(例:/etc/postgresql/ssl/)に配置し、PostgreSQLユーザーが読み取り権限を持つことを確認してください。
2. postgresql.confの設定
SSLを有効にし、証明書ファイルの場所を指定するために、postgresql.confファイル(通常はPostgreSQLデータディレクトリ内にあります)を編集します。
#------------------------------------------------------------------------------
# SSL
#------------------------------------------------------------------------------
ssl = on
# これらはすべてPEM形式であり、サーバーのキー/証明書が設定されていない場合は無視されます。
# デフォルトでは、ファイルはサーバーのデータディレクトリにあると想定されます。
# 代わりに、完全なパスを指定することもできます。
ssl_cert_file = '/etc/postgresql/ssl/server.crt' # (必要に応じてファイル名を変更)
ssl_key_file = '/etc/postgresql/ssl/server.key' # (必要に応じてファイル名を変更)
ssl_ca_file = '/etc/postgresql/ssl/root.crt' # (クライアント証明書検証のためオプション)
# 必要に応じて暗号スイートを指定(オプション)
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL'
# クライアント証明書の検証を有効にする(オプション)
#ssl_ca_file は信頼するCA証明書を含むファイルに設定する必要があります
#ssl_crl_file = ''
#ssl_crl_dir = ''
ssl = on: サーバーでSSLサポートを有効にします。ssl_cert_file: サーバーの公開証明書へのパス。ssl_key_file: サーバーの秘密鍵へのパス。ssl_ca_file: CA証明書へのパス(クライアント証明書を検証したい場合、またはサーバー証明書がカスタムCAによって署名されている場合)。
3. SSL強制のためのpg_hba.confの設定
pg_hba.confファイルはクライアント認証を制御します。SSL接続を強制するためにエントリを変更する必要があります。
デフォルトでは、pg_hba.confのエントリは次のようになります。
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
# IPv4 ローカル接続:
host all all 127.0.0.1/32 scram-sha-256
# IPv6 ローカル接続:
host all all ::1/128 scram-sha-256
SSLを強制するには、hostエントリをhostsslに変更します。
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
# IPv4 ローカル接続:
hostssl all all 127.0.0.1/32 scram-sha-256
# IPv6 ローカル接続:
hostssl all all ::1/128 scram-sha-256
# 外部ネットワークアクセス用の例 - SSLが必要
hostssl all all 0.0.0.0/0 scram-sha-256
hostssl all all ::/0 scram-sha-256
hostssl: このレコードタイプはSSL接続を要求します。SSLなしでの接続試行は拒否されます。hostnossl: このレコードタイプは明示的にSSL接続を禁止します。host: SSL接続と非SSL接続の両方を許可します(これがデフォルトであり、セキュリティは低くなります)。
4. PostgreSQLサーバーの再起動
postgresql.confとpg_hba.confを変更した後、変更を有効にするにはPostgreSQLサービスを再起動する必要があります。
# systemdを使用するシステム(ほとんどの最新のLinuxディストリビューション)
sudo systemctl restart postgresql
# init.dを使用するシステム
sudo service postgresql restart
クライアント側のSSL/TLS設定
クライアント側でもセキュアに接続するように設定する必要があります。これには、接続パラメーターの指定、クライアント証明書の提供(必要な場合)、およびサーバー証明書の検証が含まれます。
1. 接続文字列パラメーター
psqlまたは任意のPostgreSQLクライアントライブラリ経由で接続する場合、接続文字列内、または個別のオプションとしてSSLパラメーターを指定できます。
基本的なSSL接続(サーバー認証のみ):
psql "sslmode=require host=your_server_hostname dbname=your_db user=your_user"
sslmode: クライアントのSSL動作を制御します。disable: 非SSL接続のみを許可します。allow: 非SSLを許可しますが、サーバーがサポートしていればSSLを優先します。prefer(デフォルト): SSLを優先しますが、SSLが失敗した場合は非SSLを許可します。require: SSL接続のみを許可します。サーバーがSSLをサポートしていない場合、接続は失敗します。verify-ca: SSL接続のみを許可し、サーバー証明書が信頼できるCAによって署名されていることを検証します。sslrootcertパラメーターを設定する必要があります。verify-full: SSL接続のみを許可し、サーバー証明書を信頼できるCAに対して検証し、サーバーのホスト名が証明書の共通名(CN)またはサブジェクト代替名(SAN)と一致することを検証します。
サーバー証明書の検証(verify-caまたはverify-full):
セキュリティを強化するため、クライアントはサーバーの身元を確認する必要があります。これには、クライアントがサーバー証明書に署名したCAを信頼することが必要です。
- CA証明書の取得: サーバー証明書に署名するために使用された
root.crtファイル(または適切なCA証明書)を取得します。 sslrootcertの指定: クライアントにこのCA証明書を見つける場所を伝えます。
psql "sslmode=verify-full host=your_server_hostname dbname=your_db user=your_user sslrootcert=/path/to/your/root.crt"
2. クライアント証明書(相互認証)
さらに高いレベルのセキュリティのために、サーバーもクライアント証明書を使用してクライアントの身元を確認する相互認証を実装できます。
クライアント証明書の生成:
サーバー証明書と同様に、クライアントの秘密鍵と、サーバーが信頼するCA(多くの場合、サーバー証明書と同じCA)によって署名されたクライアント証明書が必要です。
-
クライアント秘密鍵の生成:
bash openssl genrsa -des3 -out client.key 2048 -
クライアントCSRの作成:
bash openssl req -new -key client.key -out client.csr
情報を入力し、共通名がクライアントに対して一意であることを確認します。 -
CAによるクライアントCSRへの署名:
bash sudo openssl x509 -req -days 365 -in client.csr -CA root.crt -CAkey root.key -set_serial <unique_serial> -out client.crt -
パーミッションの設定:
bash chmod 600 client.key chmod 644 client.crt
クライアント証明書認証のためのpg_hba.confの設定:
サーバー側では、pg_hba.confを設定してクライアント証明書認証を受け入れる必要があります。これはしばしばcert認証メソッドを使用します。
# TYPE DATABASE USER ADDRESS METHOD
# 特定のユーザー/DBに対してSSLとクライアント証明書認証を要求
hostssl all your_user your_client_ip/32 cert map=your_cert_map
特定のクライアント証明書の詳細(SubjectやSubjectAltNameなど)をPostgreSQLユーザーにマッピングしたい場合は、証明書マップファイル(cert_mapオプション)を定義する必要があるかもしれません。詳細なcert認証および証明書マッピングの設定については、PostgreSQLの公式ドキュメントを参照してください。
証明書を使用するようにクライアントを設定する:
クライアントの接続文字列を更新し、その証明書とキーへのパスを含めます。
psql "sslmode=verify-full host=your_server_hostname dbname=your_db user=your_user \nsslrootcert=/path/to/your/root.crt sslcert=/path/to/your/client.crt sslkey=/path/to/your/client.key"
ベストプラクティスとヒント
verify-fullsslmodeを使用する: 中間者攻撃を防ぐため、クライアント側では常にverify-fullを使用するように努めてください。- 秘密鍵を保護する: 秘密鍵(
.keyファイル)には厳密なファイルパーミッション(例:chmod 600)を設定し、サーバー上ではPostgreSQLユーザーのみ、クライアント上では接続ユーザーのみが読み取れるようにします。 - 証明書の定期的な更新: 証明書には有効期限があります。接続の中断を避けるために、有効期限が切れる前に更新するプロセスを実装してください。
- 集中化された証明書管理: 大規模なデプロイメントの場合は、証明書管理システムの使用や、証明書の発行および更新の自動化を検討してください。
- ログの監視: 起動時または接続試行時に、SSL関連のエラーがないかPostgreSQLのログを確認してください。
- ドキュメント: 最新のパラメーターと、使用しているPostgreSQLバージョン固有の高度な設定オプションについては、PostgreSQLの公式ドキュメントを参照してください。
結論
PostgreSQL接続にSSL/TLSを設定することは、データベースインフラストラクチャを保護するための重要なステップです。サーバーでSSLを有効にし、pg_hba.confでssl=requireまたはhostsslを強制し、クライアントを適切なsslmode設定(理想的にはverify-full)で構成することにより、ネットワーク経由で送信されるデータのセキュリティを大幅に向上させることができます。クライアント証明書を使用した相互認証を実装することは、もう一つの堅牢なセキュリティ層を追加します。初期設定は複雑に見えるかもしれませんが、データ保護とコンプライアンスという長期的なメリットから、これはPostgreSQLのあらゆるデプロイメントにとって不可欠な実践事項となります。