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 を参照してください。

手順

  1. OpenSSL ライブラリーをインストールします。

    # dnf install openssl
  2. TLS 証明書とキーを生成します。

    # openssl req -new -x509 -days 365 -nodes -text -out server.crt \
      -keyout server.key -subj "/CN=dbhost.yourdomain.com"

    dbhost.yourdomain.com を データベースのホストとドメイン名に置き換えます。

  3. 署名済み証明書と秘密鍵をデータベースサーバー上の必要なロケーションにコピーします。

    # cp server.{key,crt} /var/lib/pgsql/data/.
  4. 署名付き証明書と秘密鍵の所有者とグループの所有権を postgres ユーザーに変更します。

    # chown postgres:postgres /var/lib/pgsql/data/server.{key,crt}
  5. 所有者だけが読み取れるように、秘密鍵の権限を制限します。

    # chmod 0400 /var/lib/pgsql/data/server.key
  6. /var/lib/pgsql/data/postgresql.conf ファイルの次の行を変更して、パスワードハッシュアルゴリズムを scram-sha-256 に設定します。

    #password_encryption = md5              # md5 or scram-sha-256

    更新後は次のようになります。

    password_encryption = scram-sha-256
  7. /var/lib/pgsql/data/postgresql.conf ファイルの次の行を変更して、SSL/TLS を使用するように PostgreSQL を設定します。

    #ssl = off

    更新後は次のようになります。

    ssl=on
  8. /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 をユーザー名に置き換えます。

  9. postgresql サービスを再起動して、変更を有効にします。

    # systemctl restart postgresql.service

検証

  • 接続が暗号化されていることを手動で確認するには、以下を行います。

    1. mydbuser ユーザーとして PostgreSQL データベースに接続し、ホスト名とデータベース名を指定します。

      $ psql -U mydbuser -h 127.0.0.1 -d mydatabase
      Password for user mydbuser:

      mydatabase をデータベース名に、mydbuser をユーザー名に置き換えます。

    2. 現在のデータベース接続に関する情報を取得します。

      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 データベースの初期化方法、データベースユーザーとデータベースの作成方法、セキュアな接続を使用したデータベースへの接続方法を示します。

  1. PosgreSQL サーバーをインストールします。

    # dnf install postgresql-server
  2. データベースクラスターを初期化します。

    # postgresql-setup --initdb
    * Initializing database in '/var/lib/pgsql/data'
    * Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log
  3. OpenSSL ライブラリーをインストールします。

    # dnf install openssl
  4. TLS 証明書とキーを生成します。

    # openssl req -new -x509 -days 365 -nodes -text -out server.crt \
      -keyout server.key -subj "/CN=dbhost.yourdomain.com"

    dbhost.yourdomain.com を データベースのホストとドメイン名に置き換えます。

  5. 署名済み証明書と秘密鍵をデータベースサーバー上の必要なロケーションにコピーします。

    # cp server.{key,crt} /var/lib/pgsql/data/.
  6. 署名付き証明書と秘密鍵の所有者とグループの所有権を postgres ユーザーに変更します。

    # chown postgres:postgres /var/lib/pgsql/data/server.{key,crt}
  7. 所有者だけが読み取れるように、秘密鍵の権限を制限します。

    # chmod 0400 /var/lib/pgsql/data/server.key
  8. パスワードハッシュアルゴリズムを scram-sha-256 に設定します。/var/lib/pgsql/data/postgresql.conf ファイルで、次の行を変更します。

    #password_encryption = md5              # md5 or scram-sha-256

    更新後は次のようになります。

    password_encryption = scram-sha-256
  9. SSL/TLS を使用するように PostgreSQL を設定します。/var/lib/pgsql/data/postgresql.conf ファイルで、次の行を変更します。

    #ssl = off

    更新後は次のようになります。

    ssl=on
  10. postgresql サービスを開始します。

    # systemctl start postgresql.service
  11. postgres という名前のシステムユーザーとしてログインします。

    # su - postgres
  12. postgres ユーザーとして PostgreSQL インタラクティブターミナルを起動します。

    $ psql -U postgres
    psql (13.7)
    Type "help" for help.
    
    postgres=#
  13. mydbuser という名前のユーザーを作成し、mydbuser のパスワードを設定します。

    postgres=# CREATE USER mydbuser WITH PASSWORD 'mypasswd';
    CREATE ROLE
    postgres=#
  14. mydatabase という名前のデータベースを作成します。

    postgres=# CREATE DATABASE mydatabase;
    CREATE DATABASE
    postgres=#
  15. すべての権限を mydbuser ユーザーに付与します。

    postgres=# GRANT ALL PRIVILEGES ON DATABASE mydatabase TO mydbuser;
    GRANT
    postgres=#
  16. インタラクティブターミナルからログアウトします。

    postgres=# \q
  17. postgres ユーザーセッションからログアウトします。

    $ logout
  18. /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
  19. postgresql サービスを再起動して、変更を有効にします。

    # systemctl restart postgresql.service
  20. 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=>