Amazon RDS PostgreSQLにpsqlからSSL接続する

3行まとめ

  • psql はデフォルトでSSL接続する
  • SSL接続を強制するにはパラメータグループの rds.force_ssl パラメータを変更する
  • ルート証明書を取得すれば、RDSのSSL証明書を検証できる

Amazon Aurora MySQL 向け SSL 接続方法

次の過去記事を参照ください。

【Amazon Aurora】SSLによる通信の暗号化

検証環境

Client

  • Amazon Linux 2
  • psql で PostgreSQL に接続

Database

  • RDS : Aurora PostgreSQL 9.6
  • RDS : PostgreSQL 10.4-R1

事前準備:psqlのインストール

Amazon Linux 2にPostgreSQL クライアント(psql)をインストールします。

psql のバージョンが RDS より古くても OK な場合

psql の基本機能だけを利用する場合、psql のバージョンの古さは問題にはなりません。

Amazon Linux 2 の yum で標準提供されている psql をインストールします。

$ sudo yum install -y postgresql
...
Installed:
  postgresql.x86_64 0:9.2.24-1.amzn2.0.1

Dependency Installed:
  postgresql-libs.x86_64 0:9.2.24-1.amzn2.0.1

Complete!
$ psql -V
psql (PostgreSQL) 9.2.2

インストールされるバージョンは 9.2.2 と少し古めです。

psql と RDS のバージョンを一致させたい場合

amazon-linux-extras 経由で RDS のバージョンに対応する psql をインストールします。

現時点では

  • 9.6 系
  • 10 系

が提供されています。

試しに 10 系をインストールします。

$ amazon-linux-extras
  0  ansible2                 available    [ =2.4.2  =2.4.6 ]
  1  emacs                    available    [ =25.3 ]
  2  httpd_modules            available    [ =1.0 ]
  3  memcached1.5             available    [ =1.5.1 ]
  4  nginx1.12                available    [ =1.12.2 ]
  5  postgresql9.6            available    [ =9.6.6  =9.6.8 ]
  6  postgresql10             available    [ =10 ]
  8  redis4.0                 available    [ =4.0.5  =4.0.10 ]
  9  R3.4                     available    [ =3.4.3 ]
 10  rust1                    available    \
        [ =1.22.1  =1.26.0  =1.26.1  =1.27.2 ]
 11  vim                      available    [ =8.0 ]
 12  golang1.9                available    [ =1.9.2 ]
 13  ruby2.4                  available    [ =2.4.2  =2.4.4 ]
 14  nano                     available    [ =2.9.1 ]
 15  php7.2                   available    \
        [ =7.2.0  =7.2.4  =7.2.5  =7.2.8 ]
 16  php7.1                   available    [ =7.1.22 ]
 17  lamp-mariadb10.2-php7.2  available    \
        [ =10.2.10_7.2.0  =10.2.10_7.2.4  =10.2.10_7.2.5
          =10.2.10_7.2.8 ]
 18  libreoffice              available    [ =5.0.6.2_15  =5.3.6.1 ]
 19  gimp                     available    [ =2.8.22 ]
 20  docker=latest            enabled      \
        [ =17.12.1  =18.03.1  =18.06.1 ]
 21  mate-desktop1.x          available    [ =1.19.0  =1.20.0 ]
 22  GraphicsMagick1.3        available    [ =1.3.29 ]
 23  tomcat8.5                available    [ =8.5.31  =8.5.32 ]
 24  epel                     available    [ =7.11 ]
 25  testing                  available    [ =1.0 ]
 26  ecs                      available    [ =stable ]
$ amazon-linux-extras info  postgresql10
postgresql10 recommends postgresql                 # yum install postgresql
$ sudo amazon-linux-extras install postgresql10
...

$ psql -V
psql (PostgreSQL) 10.4

psql で SSL 接続

psql はデフォルトで SSL 接続を試します。

SSL は、PostgreSQL 用のすべての AWS リージョンでサポートされています。インスタンスが作成されるとき、Amazon RDS で PostgreSQL DB インスタンスの SSL 証明書が作成されます。

そのため、psql 接続時に、特別なオプションを渡さなければ、SSL で接続します。

$ psql -h  $HOST "dbname=dbname user=username"
Password:
psql (10.4)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
dbname=>

デフォルトで SSL 接続を試す仕様は、環境変数 PGSSLMODE で変更可能です。

非SSLで接続してみます

$ PGSSLMODE=disable \
  psql -h  $HOST "dbname=dbname user=username"
Password:
psql (10.4)
Type "help" for help.

先程と異なり SSL connection ... のメッセージが表示されていません。

SSL 接続を強制する

SSL 接続を強制するには RDS の rds.force_ssl パラメータをデフォルトの 0(off) から 1(on) に変更します。

このパラメータの設定は非 Aurora と Aurora でパラメータグループが異なります。

  • Amazon RDS for PostgreSQL の場合は Parameter groups
  • Amazon Aurora PostgreSQL の場合は DB cluster parameter group

変更を反映するためには DB インスタンスを再起動する必要があります。

SSL 接続を強制後、非 SSL 接続を試みると、エラーになります。

$ PGSSLMODE=disable \
  psql -h $HOST "dbname=dbname user=username"
psql: FATAL:  no pg_hba.conf entry for host "XX.XX.XX.XX", user "username", database "dbname", SSL off

SSL 証明書を検証する

なりすましを防止するために、ルート証明書を取得して、RDS エンドポイント用の SSL 証明書を検証する事ができます。

SSL 証明書を検証するには psql コマンドに sslmode=verify-full オプションを追加し、ルート証明書を指定します。

ルート証明書の管理

ルート証明書は次の URL から取得します。

psql からルート証明書を参照するには次の方法があります。

  • 証明書を psql デフォルトのパス($HOME/.postgresql/root.crt)にインストール
  • 環境変数で証明書のパスを指定($ PGSSLROOTCERT=/path/to/rds-combined-ca-bundle.pem psql ...)
  • psql の引数で証明書のパスを指定(sslrootcert=/path/to/root.crt)

SSL 証明書を検証して接続

バンドルのルート証明書をダウンロードし、psql の引数で証明書のパスを指定して SSL 証明書を検証する場合、以下のようになります。

$ wget https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
$ psql -h $HOST \
  "dbname=dbname user=username sslrootcert=rds-combined-ca-bundle.pem sslmode=verify-full"
Password:
psql (10.4, server 9.6.8)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
dbname=>

sslinfo エクステンションによるSSL接続状況の確認

PostgreSQL の sslinfo エクステンションを利用すると、SSL 接続状況を確認できます。

このエクステンションは

  • Amazon RDS for PostgreSQL
  • Amazon Aurora PostgreSQL

の両方で利用可能です。

# エクステンションを有効化
dbname=> create extension sslinfo;
CREATE EXTENSION

# SSL 接続ステータスを調べる。リザルトは boolean
dbname=> select ssl_is_used();
 ssl_is_used
-------------
 t
(1 row)

# SSL 暗号を調べる
dbname=> select ssl_cipher();
         ssl_cipher
-----------------------------
 ECDHE-RSA-AES256-GCM-SHA384
(1 row)

関連情報