外部リソースから Private または Shield の Heroku Postgres データベースに接続する
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2023年05月31日(水)
Table of Contents
Mutual TLS を使用して、外部リソースと、Private Space または Shield Private Space で実行されている Heroku Postgres データベースの間に、安全で相互に認証されたチャネルを作成します。外部リソースには、プライベートデータセンターまたはパブリッククラウドで実行されている任意の mTLS 対応アプリケーションまたはシステムを含めることができます。この機能を使用するには、データベースに接続する外部 IP も許可リストに登録する必要があります。
概要
この機能を利用できるのは、Private および Shield の Postgres データベースに限定されます。
Heroku では、認証局 (CA) を Private Space および Shield Private Space にプロビジョニングして、Postgres データベースサーバー用およびクライアント用の証明書を生成します。その後、Postgres クライアントの設定のために、サーバー証明書チェーン、クライアント証明書チェーン、およびクライアント秘密鍵が公開されます。必要な場合、追加のクライアント証明書をプロビジョニングできます。
このプロセスは、大きく分けて 3 つの手順で構成されます。
- Mutual TLS を設定し、外部 IP を許可リストに登録する
- クライアント側の証明書を設定する
- 外部リソースからデータベースに接続する
Heroku の前提条件
Mutual TLS を設定するには、以下の Heroku リソースが必要です。
- Private Space または Shield Private Space
- Private または Shield の Heroku Postgres データベースがアタッチされた Space で実行されている Heroku アプリ
Mutual TLS の設定と IP の許可リスト登録
手順 1: Mutual TLS CLI プラグインをインストールする
$ heroku plugins:install mtls
手順 2: Mutual TLS を有効化する
次のようにして、データベースで Mutual TLS を有効化します。
$ heroku data:mtls:create DATABASE_NAME --app APP_NAME
DATABASE_NAME
は Postgres データベースの名前、APP_NAME
はアプリケーションの名前です。
次に示すのは、コマンドとそれに伴う出力の例です。
$ heroku data:mtls:create postgresql-sushi-12345 --app sushi
addon: postgresql-sushi-12345
app: sushi
status: Provisioning
Enabling MTLS on postgresql-sushi-12345... done
通常、Mutual TLS の有効化には 5 ~ 10 分かかります。heroku data:mtls DATABASE_NAME --app APP_NAME
で進捗状況を追跡できます。
手順 3: 外部 IP を許可リストに登録する
許可リストに登録できるのは Postgres データベースあたり 60 個の IP ブロックというハード制限があります。Mutual TLS を有効化したら、次の Heroku CLI コマンドを使用して、Postgres データベースにアクセスする IP ブロックを許可リストに登録します (以下の置き換える値に注意すること)。
$ heroku data:mtls:ip-rules:create DATABASE_NAME --app APP_NAME \
--cidr CIDR_BLOCK \
--description DESCRIPTION
DATABASE_NAME
は、Postgres データベースの名前に置き換えます (例: postgresql-sushi-12345
)。APP_NAME
は、アプリの名前に置き換えます (例: sushi
)。CIDR_BLOCK
は、許可リストに登録する CIDR ブロックに置き換えます。個々の IP アドレスはx.x.x.x/32
のように表され、x は 0 ~ 255 の任意の数値です。DESCRIPTION
は、許可リストに登録するこの CIDR ブロックのわかりやすい説明に置き換えます (例: "Office IP"
)。
次に示すのは、コマンドとそれに伴う出力の例です。
$ heroku data:mtls:ip-rules:create postgresql-sushi-12345 --app sushi \
--cidr "1.2.3.4/32" \
--description "My Office IP"
Creating IP Rule for database postgresql-sushi-12345... done
cidr: 1.2.3.4/32
created_at: 2019-07-17 00:05:52 +0000
description: My Office IP
id: 38c466b6-dcfb-4869-b5ac-40420b786fb4
status: Authorizing
updated_at: 2019-07-17 00:05:52 +0000
通常、外部 IP を許可リストに登録するには数分かかります。次のコマンドで進捗状況を追跡できます。
$ heroku data:mtls:ip-rules:get DATABASE_NAME --id IP_RULE_ID --app APP_NAME
ここで、DATABASE_NAME
と APP_NAME
は上記の説明のとおりであり、IP_RULE_ID
は create コマンドの出力にある id
です (たとえば、上記で許可リストに登録された IP の id は 38c466b6-dcfb-4869-b5ac-40420b786fb4
)。
次に示すのは、コマンドとそれに伴う出力の例です。
$ heroku data:mtls:ip-rules:get postgresql-sushi-12345 --id "38c466b6-dcfb-4869-b5ac-40420b786fb4" --app sushi
cidr: 1.2.3.4/32
created_at: 2019-07-17 00:05:52 +0000
description: My Office IP
id: 38c466b6-dcfb-4869-b5ac-40420b786fb4
status: Authorized
updated_at: 2019-07-17 00:05:52 +0000
heroku data:mtls:ip-rules DATABASE_NAME --app APP_NAME
を使用すると、このデータベースの許可リストに登録されているすべての IP アドレスを表示できます。
クライアント側の証明書を設定する
手順 1: クライアント側の証明書をダウンロードする
次のようにして、Postgres データベース用のすべてのクライアント側証明書を表示します。
$ heroku data:mtls:certificates DATABASE_NAME --app APP_NAME
DATABASE_NAME
と APP_NAME
は、以前の定義と同じです。次に示すのは、コマンドとそれに伴う出力の例です。
$ heroku data:mtls:certificates postgresql-sushi-12345 --app sushi
id Created At Status
61acf66f-e505-452c-a517-e727689fb54f 2019-07-16 23:39:26 +0000 ready
次の Heroku CLI コマンドを使用して、Postgres データベースにアクセスするクライアントを設定するために必要な証明書をダウンロードします (後で説明する値の置き換えに注意してください)。
$ heroku data:mtls:certificates:download DATABASE_NAME \
--id CERTIFICATE_ID \
--prefix PREFIX \
--dir DIRECTORY \
--app APP_NAME
DATABASE_NAME
は、Postgres データベースの名前に置き換えます (例: postgresql-sushi-12345
)。APP_NAME
は、アプリの名前に置き換えます (例: sushi
)。CERTIFICATE_ID
は、ダウンロードする証明書のid
に置き換えます (たとえば、前出の例における証明書のid
は61acf66f-e505-452c-a517-e727689fb54f
です)。PREFIX
は、ダウンロードしたファイルの名前の前に付ける接頭辞に置き換えます (例: demo_
)。DIRECTORY
は、ファイルをダウンロードするディレクトリに置き換えます (例: ./folder
)。デフォルトは$HOME/.postgresql
です。
次に示すのは、コマンドとそれに伴う出力の例です。
$ heroku data:mtls:certificates:download postgresql-sushi-12345 \
--id "61acf66f-e505-452c-a517-e727689fb54f" \
--prefix "demo_" \
--dir "./folder" \
--app sushi
Downloading certificates for database postgresql-sushi-12345... done
your certs are now located in ./folder
folder
ディレクトリを開くと、次の 3 つのファイルがあります。
- demo_postgresql.crt (チェーン付きのクライアント証明書)
- demo_postgresql.key (クライアントの秘密鍵)
- demo_root.crt (サーバー証明書チェーン)
手順 2: 環境変数を設定する
次の Heroku CLI コマンドを使用して、必要な環境変数を設定します (後で説明する値の置き換えに注意してください)。
$ export DATABASE_URL=`heroku config:get DATABASE_URL -a APP_NAME`
$ export PGSSLCERT=DIRECTORY/PREFIXpostgresql.crt
$ export PGSSLKEY=DIRECTORY/PREFIXpostgresql.key
$ export PGSSLROOTCERT=DIRECTORY/PREFIXroot.crt
DATABASE_URL
は、Postgres データベースの URL に置き換えます (例: postgresql-sushi-12345
)。APP_NAME
は、アプリの名前に置き換えます (例: sushi
)。DIRECTORY
は、前の手順でファイルをダウンロードしたディレクトリに置き換えます。PREFIX
は、前の手順でダウンロードしたファイルの名前の前に付ける接頭辞に置き換えます。
秘密鍵の適切なアクセス許可を設定します。前の手順でダウンロードした鍵の場合、次のようにしてアクセス許可を設定できます。
$ chmod 0600 ./folder/demo_postgresql.key
PGSSLCERT、PGSSLKEY、および PGSSLROOTCERT の各環境設定は、接頭辞を設定せずにデフォルトディレクトリにファイルをダウンロードした場合、設定する必要はありません。
開発環境で接頭辞を省略することはお勧めしません。なぜなら、証明書がすべてのデータベースに送信される原因となり、通常の Heroku CLI の操作の妨げとなる可能性があるためです。
クライアント証明書の更新
クライアント証明書の有効期限は、作成日の 13 か月後です。有効期限の 75 日前に、以下のことが行われます。
- 新しいクライアント証明書が作成されます
- 現在の証明書の期限切れが近いというメールが送信されますメールの内容には、新しい証明書についての詳細と、証明書の使用を開始する方法が含まれています。
新しい証明書が作成されたら、現在の証明書が期限切れになって機能しなくなる前に使用を開始することをお勧めします。
外部リソースからデータベースに接続する
ここで、次のようにしてデータベースに接続できます。
$ psql "${DATABASE_URL}?sslmode=verify-ca"
psql (11.1, server 11.4 (Ubuntu 11.4-1.pgdg16.04+1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
abcdefghij1234=>
mTLS 経由で接続するための外部アプリケーションの設定
ご使用のデータベースに mTLS 経由で接続するよう他のアプリケーションを設定する場合は、そのアプリケーションのドキュメントを参照して、特別な要件がないか確認することをお勧めします。
たとえば、JDBC PostgreSQL コネクターを使用するアプリケーションでは、sslcert
、sslkey
、sslroot
、および sslmode
のパラメーターを含む接続文字列が必要で、さらにキーが PKCS-12 または PKCS-8 DER 形式のいずれかで提供される必要があります。
data:mtls:certificates:download
コマンドによって提供されるキーは PEM 形式で、これはこの openssl
コマンドを使用して DER 形式に変換できます (ダウンロードされたキーファイルが格納されているディレクトリから実行します)。
$ openssl pkcs8 -topk8 -inform PEM -in postgresql.key -outform DER -out postgresql.pk8 -nocrypt
上記の通り、新しいキーファイルで適切なアクセス許可を設定する必要があります。
$ chmod 0600 postgresql.pk8
JDBC 接続 URL の構築の詳細は、公式の PostgreSQL ドキュメントを参照してください。
この機能の使用に関して問題または気になる点がある場合は、サポートチケットを開いてください。
mTLS CLI プラグイン
mTLS CLI プラグインについての完全なドキュメントを参照してください。