4.4. PostgreSQL サーバーにおける TLS 暗号化の設定
デフォルトでは、PostgreSQL は暗号化されていない接続を使用します。よりセキュアな接続のために、PostgreSQL サーバーで Transport Layer Security (TLS) サポートを有効にし、暗号化された接続を確立するようにクライアントを設定できます。
前提条件
- PostgreSQL サーバーがインストールされている
- データベースクラスターが初期化されている
- サーバーが RHEL 9.2 以降を実行し、FIPS モードが有効になっている場合、クライアントが Extended Master Secret (EMS) 拡張機能をサポートしているか、TLS 1.3 を使用している必要があります。EMS を使用しない TLS 1.2 接続は失敗します。詳細は、ナレッジベースの記事 TLS extension "Extended Master Secret" enforced を参照してください。
手順
OpenSSL ライブラリーをインストールします。
# dnf install openssl
TLS 証明書とキーを生成します。
# openssl req -new -x509 -days 365 -nodes -text -out server.crt \ -keyout server.key -subj "/CN=dbhost.yourdomain.com"
dbhost.yourdomain.com を データベースのホストとドメイン名に置き換えます。
署名済み証明書と秘密鍵をデータベースサーバー上の必要なロケーションにコピーします。
# cp server.{key,crt} /var/lib/pgsql/data/.
署名付き証明書と秘密鍵の所有者とグループの所有権を
postgres
ユーザーに変更します。# chown postgres:postgres /var/lib/pgsql/data/server.{key,crt}
所有者だけが読み取れるように、秘密鍵の権限を制限します。
# chmod 0400 /var/lib/pgsql/data/server.key
/var/lib/pgsql/data/postgresql.conf
ファイルの次の行を変更して、パスワードハッシュアルゴリズムをscram-sha-256
に設定します。#password_encryption = md5 # md5 or scram-sha-256
更新後は次のようになります。
password_encryption = scram-sha-256
/var/lib/pgsql/data/postgresql.conf
ファイルの次の行を変更して、SSL/TLS を使用するように PostgreSQL を設定します。#ssl = off
更新後は次のようになります。
ssl=on
/var/lib/pgsql/data/pg_hba.conf
ファイルの IPv4 ローカル接続で次の行を変更して、TLS を使用するクライアントからの接続のみを受け入れるように、すべてのデータベースへのアクセスを制限します。host all all 127.0.0.1/32 ident
更新後は次のようになります。
hostssl all all 127.0.0.1/32 scram-sha-256
または、次の行を新たに追加して、単一のデータベースとユーザーのアクセスを制限できます。
hostssl mydatabase mydbuser 127.0.0.1/32 scram-sha-256
mydatabase をデータベース名に、mydbuser をユーザー名に置き換えます。
postgresql
サービスを再起動して、変更を有効にします。# systemctl restart postgresql.service
検証
接続が暗号化されていることを手動で確認するには、以下を行います。
mydbuser ユーザーとして PostgreSQL データベースに接続し、ホスト名とデータベース名を指定します。
$ psql -U mydbuser -h 127.0.0.1 -d mydatabase Password for user mydbuser:
mydatabase をデータベース名に、mydbuser をユーザー名に置き換えます。
現在のデータベース接続に関する情報を取得します。
mydbuser=> \conninfo You are connected to database "mydatabase" as user "mydbuser" on host "127.0.0.1" at port "5432". SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
PostgreSQL への接続が暗号化されているかどうかを検証する簡単なアプリケーションを作成できます。この例は、
libpq-devel
パッケージで提供されるlibpq
クライアントライブラリーを使用する C で記述されたアプリケーションを示しています。#include <stdio.h> #include <stdlib.h> #include <libpq-fe.h> int main(int argc, char* argv[]) { //Create connection PGconn* connection = PQconnectdb("hostaddr=127.0.0.1 password=mypassword port=5432 dbname=mydatabase user=mydbuser"); if (PQstatus(connection) ==CONNECTION_BAD) { printf("Connection error\n"); PQfinish(connection); return -1; //Execution of the program will stop here } printf("Connection ok\n"); //Verify TLS if (PQsslInUse(connection)){ printf("TLS in use\n"); printf("%s\n", PQsslAttribute(connection,"protocol")); } //End connection PQfinish(connection); printf("Disconnected\n"); return 0; }
mypassword をパスワードに、mydatabase をデータベース名に、myduser をユーザー名に置き換えます。
注記-lpq
オプションを使用して、コンパイルのためにpq
ライブラリーをロードする必要があります。たとえば、GCC コンパイラーを使用してアプリケーションをコンパイルするには、次のようにします。$ gcc source_file.c -lpq -o myapplication
この source_file.c には上記のサンプルコードが含まれており、myapplication はセキュアな PostgreSQL 接続を検証するためのアプリケーションの名前です。
例4.4 TLS 暗号化を使用した PostgreSQL データベースの初期化、作成、接続
この例では、PostgreSQL データベースの初期化方法、データベースユーザーとデータベースの作成方法、セキュアな接続を使用したデータベースへの接続方法を示します。
PosgreSQL サーバーをインストールします。
# dnf install postgresql-server
データベースクラスターを初期化します。
# postgresql-setup --initdb * Initializing database in '/var/lib/pgsql/data' * Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log
OpenSSL ライブラリーをインストールします。
# dnf install openssl
TLS 証明書とキーを生成します。
# openssl req -new -x509 -days 365 -nodes -text -out server.crt \ -keyout server.key -subj "/CN=dbhost.yourdomain.com"
dbhost.yourdomain.com を データベースのホストとドメイン名に置き換えます。
署名済み証明書と秘密鍵をデータベースサーバー上の必要なロケーションにコピーします。
# cp server.{key,crt} /var/lib/pgsql/data/.
署名付き証明書と秘密鍵の所有者とグループの所有権を
postgres
ユーザーに変更します。# chown postgres:postgres /var/lib/pgsql/data/server.{key,crt}
所有者だけが読み取れるように、秘密鍵の権限を制限します。
# chmod 0400 /var/lib/pgsql/data/server.key
パスワードハッシュアルゴリズムを
scram-sha-256
に設定します。/var/lib/pgsql/data/postgresql.conf
ファイルで、次の行を変更します。#password_encryption = md5 # md5 or scram-sha-256
更新後は次のようになります。
password_encryption = scram-sha-256
SSL/TLS を使用するように PostgreSQL を設定します。
/var/lib/pgsql/data/postgresql.conf
ファイルで、次の行を変更します。#ssl = off
更新後は次のようになります。
ssl=on
postgresql
サービスを開始します。# systemctl start postgresql.service
postgres
という名前のシステムユーザーとしてログインします。# su - postgres
postgres
ユーザーとして PostgreSQL インタラクティブターミナルを起動します。$ psql -U postgres psql (13.7) Type "help" for help. postgres=#
mydbuser
という名前のユーザーを作成し、mydbuser
のパスワードを設定します。postgres=# CREATE USER mydbuser WITH PASSWORD 'mypasswd'; CREATE ROLE postgres=#
mydatabase
という名前のデータベースを作成します。postgres=# CREATE DATABASE mydatabase; CREATE DATABASE postgres=#
すべての権限を
mydbuser
ユーザーに付与します。postgres=# GRANT ALL PRIVILEGES ON DATABASE mydatabase TO mydbuser; GRANT postgres=#
インタラクティブターミナルからログアウトします。
postgres=# \q
postgres
ユーザーセッションからログアウトします。$ logout
/var/lib/pgsql/data/pg_hba.conf
ファイルの IPv4 ローカル接続で次の行を変更して、TLS を使用するクライアントからの接続のみを受け入れるように、すべてのデータベースへのアクセスを制限します。host all all 127.0.0.1/32 ident
更新後は次のようになります。
hostssl all all 127.0.0.1/32 scram-sha-256
postgresql
サービスを再起動して、変更を有効にします。# systemctl restart postgresql.service
mydbuser
ユーザーとして PostgreSQL データベースに接続し、ホスト名とデータベース名を指定します。$ psql -U mydbuser -h 127.0.0.1 -d mydatabase Password for user mydbuser: psql (13.7) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off) Type "help" for help. mydatabase=>