【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 Nameに192.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と表記)を作成します。使用しているオプションは、
オプション | 機能 |
---|---|
-new | CSRを作成する |
-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の鍵の指定 |
-CAcreateserial | CAシリアル番号を自動作成し、ファイルに保存 |
-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.key、postgresql.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 –の項にあるsslをonに変更し、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を記入、DATABASEとUSERとADDRESSには通常通りの接続設定を記入します。
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.keyとpostgresql.crtとroot.crtの3つが入っている場合、psqlコマンド時に自動で読み込まれ、SSL接続されることを確認出来ます。
別のクライアントから接続する場合も、postgresql.keyとpostgresql.crtとroot.crtの3つをコピーして使用することでSSL接続する事ができます。
実際にSSL設定を使用する際はサーバー用の証明書とクライアント用の証明書は別のディレクトリに分けて保存したほうが良いでしょう。
PostgreSQLをSSL認証に対応させるにあたり、PostgreSQLの設定よりもOpenSSLによる証明書の作り方に難儀することのほうが多いかと思います。OpenSSLによる証明書の作り方は一つではないので、openssl <サブコマンド> -helpで表示されるコマンドオプションの一覧も確認しながら、作りたい証明書を作成してみてください。
このカテゴリの最新記事
2024.09.19
2024.08.22
2023.11.28
2024.12.13