タイガーラック クリエイティブブログ
2025
May
22

【PostgreSQL】PostgreSQL用の自己署名証明書作成とSSL認証の設定方法

今回はPostgreSQLのSSL認証による接続の設定方法と、OpenSSLによる自己署名証明書の作成方法を説明していきます。

環境

  • さくらのVPS
  • Ubuntu 24.04.1 LTS
  • PostgreSQL 16.8
  • OpenSSL 3.0.13

サーバー証明書の作成

ディレクトリの作成

su - postgres
mkdir .postgresql
cd .postgresql

証明書を作成する前に、ユーザーをpostgresに変更し、証明書を保存するためのディレクトリを作成します。

秘密鍵の作成

openssl genrsa -out server.key

openssl genrsaコマンドにより、RSA秘密鍵を作成します。-outオプションによって出力先を指定する事ができるので、今回はserver.keyというファイルに保存します。

サーバー証明書の作成

openssl req -x509 -days 365 -key server.key -out server.crt -subj "/CN=192.168.0.1"

openssl reqコマンドにより、サーバー証明書を作成します。オプションにはそれぞれ、

オプション機能
-x509自己署名証明書を作成する
-days <日数>証明書の有効期間を設定する
-key <ファイル名>証明書を作成する為に使用する鍵の指定
-out <ファイル名>作成した証明書の保存先
-subj “</サブジェクト>”サブジェクト情報の設定

といった機能があります。

今回の例では自己署名証明書を作成する為、-x509オプションを付け、-days 365で有効期間を約1年に設定し、-keyに先程作成した鍵を指定、-outオプションによりserver.crtに保存しています。
-subj “/CN=192.168.0.1”は数種類存在するサブジェクトのうち、Common Name192.168.0.1を設定しています。PostgreSQLで使用するサーバー証明書では、Common NameにPostgreSQLにアクセスする際に使用するサーバーのIPやホスト名を設定する必要があります。

また、今回の例では使用していませんが、-textオプションを付けると証明書をテキスト形式で作成することが出来ます。テキスト形式の証明書は直接開いて中身を確認することができるので、証明書の作成が正常に行えているかを確認することが出来ます。

ルート証明書の作成

cp server.crt root.crt

今回は自己署名証明書を使用しているので、ルート証明書にはサーバー証明書のコピーを使用します。

秘密鍵と証明書の権限変更

chmod 600 server.key server.crt root.crt

作成した秘密鍵と証明書をユーザーpostgresのみが編集できるように変更します。

クライアント証明書の作成

クライアント用の秘密鍵と証明書署名要求の作成

openssl req -new -nodes -out postgresql.csr -keyout postgresql.key -subj "/CN=postgres"

まずopenssl reqコマンドを使用し、クライアントが使用する秘密鍵と証明書署名要求ファイル(以降CSRと表記)を作成します。使用しているオプションは、

オプション機能
-newCSRを作成する
-nodes秘密鍵を暗号化しない
-out <ファイル名>作成したCSRの保存先
-keyout <ファイル名>作成した秘密鍵の保存先
-subj “/<サブジェクト>”サブジェクト情報の設定

となります。

-newオプションを使用するとCSRと鍵ファイルが同時に出力されるようになるので、-nodesオプションを使用して秘密鍵を暗号化しないように設定し、保存先をそれぞれ-out-keyoutで指定しています。
また、クライアント証明書ではサブジェクトのCommon NameにPostgreSQLで使用するロール名を設定する必要があります。なので-subj “/CN=postgres”により、クライアント証明書を作成するためのCSRにPostgreSQLのロールであるpostgresを設定しています。

クライアント証明書の作成

openssl x509 -req -in postgresql.csr -days 365 \
-CA server.crt -CAkey server.key -CAcreateserial -out postgresql.crt

作成したCSRを使ってクライアント証明書を作成します。
使用しているオプションは、

オプション機能
-req-inで入力するファイルを証明書からCSRに変更する
-in <ファイル名>入力する証明書(もしくはCSR)を指定
-days <日数>証明書の有効期間を設定する
-CA <ファイル名>証明書作成に使用するCA証明書の指定
-CAkey <ファイル名>証明書作成に使用するCAの鍵の指定
-CAcreateserialCAシリアル番号を自動作成し、ファイルに保存
-out <ファイル名>作成した証明書の保存先

という内容になります。

サーバー証明書等の作成にopenssl req -x509というコマンドを使用していましたが、openssl x509 -reqとは別体系のコマンドとなり、使用できるオプションに差異があります。
通常、openssl x509コマンドでは-inオプションで入力する証明書を指定しますが、-reqオプションを付けることでCSRを使用する事ができます。
クライアント証明書の作成にはサーバーの証明書と秘密鍵を使用する必要があるため、-CAにサーバーの証明書、-CAkeyにサーバーの秘密鍵を指定します。そして、-CreateserialでCAシリアル番号を自動作成します。自動生成されたシリアル番号は<CAファイル名>.srlとして保存されます。CAシリアル番号は手動で入力する事もできますが、証明書毎に違う番号が振られていないといけないため自動で割り振るようにしたほうが無難です。

作成した証明書の確認

ls -la ~/.postgresql

-rw-rw-r--  1 postgres postgres  989 May 21 00:00 postgresql.crt
-rw-rw-r--  1 postgres postgres  891 May 21 00:00 postgresql.csr
-rw-------  1 postgres postgres 1704 May 21 00:00 postgresql.key
-rw-------  1 postgres postgres 1115 May 21 00:00 root.crt
-rw-------  1 postgres postgres 1115 May 21 00:00 server.crt
-rw-------  1 postgres postgres 1704 May 21 00:00 server.key
-rw-rw-r--  1 postgres postgres   41 May 21 00:00 server.srl

サーバー証明書とクライアント証明書の作成を終えた時点で、7つのファイルが作成されているはずです。

クライアントがPostgreSQLに接続する際は、postgresql.keypostgresql.crtとサーバー証明書の項で作成したroot.crtを使用します。

PostgreSQLのSSL認証設定

postgresql.confの編集

vi /etc/postgresql/16/main/postgresql.conf
# - SSL -

ssl = on
ssl_ca_file = '/var/lib/postgresql/.postgresql/root.crt'
ssl_cert_file = '/var/lib/postgresql/.postgresql/server.crt'
ssl_key_file = '/var/lib/postgresql/.postgresql/server.key'

postgresql.conf内のSSL設定を有効化します。# – SSL –の項にあるsslonに変更し、ssl_ca_fileにルート証明書、ssl_cert_fileにサーバー証明書、ssl_key_fileにサーバーの秘密鍵を指定します。

pg_hba.confの編集

vi /etc/postgresql/16/main/pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD
hostssl all             all             192.168.0.1/32          cert
#もしくは
hostssl all             all             192.168.0.1/32          scram-sha-256 clientcert=verify-full

pg_hba.conf内にSSL接続用の設定を追加します。
接続設定のTYPEの項にhostsslを記入、DATABASEUSERADDRESSには通常通りの接続設定を記入します。
METHODにはcert<別タイプのMETHOD> clientcert=verify-fullと記入します。certと記入した場合はSSL証明書のみでの接続可能になり、<別タイプのMETHOD> clientcert=verify-fullと記入した場合はパスワード等に加えて証明書が要求されるようになります。

PostgreSQLの再起動

systemctl restart postgresql

設定を反映するために再起動します。

SSL接続テスト

psql -h 192.168.0.1 -U postgres
psql (16.8 (Ubuntu 16.8-1.pgdg24.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=#

サーバー証明書に設定されたホストに対し、クライアント証明書に設定されたロールで接続するとSSLの認証に成功します。
psqlコマンドによる接続の場合、~/.postgresql内にpostgresql.keypostgresql.crtroot.crtの3つが入っている場合、psqlコマンド時に自動で読み込まれ、SSL接続されることを確認出来ます。
別のクライアントから接続する場合も、postgresql.keypostgresql.crtroot.crtの3つをコピーして使用することでSSL接続する事ができます。
実際にSSL設定を使用する際はサーバー用の証明書とクライアント用の証明書は別のディレクトリに分けて保存したほうが良いでしょう。

PostgreSQLをSSL認証に対応させるにあたり、PostgreSQLの設定よりもOpenSSLによる証明書の作り方に難儀することのほうが多いかと思います。OpenSSLによる証明書の作り方は一つではないので、openssl <サブコマンド> -helpで表示されるコマンドオプションの一覧も確認しながら、作りたい証明書を作成してみてください。

このカテゴリの最新記事

関連記事

SHOP LIST

タイガーラック株式会社

〒577-0056
大阪府東大阪市長堂1-3-14 TOKUYASU Bld.