🐦

RDSのPostgre15からSSL通信がデフォルトでONになって接続エラーが発生した件

2023/06/06に公開

RDSのPostgreのバージョンを13.3→15.2に上げてみたところ、TypeScript&TypeORMで構築しているアプリケーションで以下のエラーが発生し、DB接続に失敗する現象が発生したのでその原因と対策を記載します。

UnhandledPromiseRejectionWarning: error: no pg_hba.conf entry for host "x.x.x.x", user "xxxx", database "xxxx", no encryption

原因

上記のエラーは、no encryptionの部分が示している通り、SSL接続が有効になっていないことが原因のようです。
ただ、RDSのPostgre13を使っていた時には発生しなかったエラーのため、なぜ15にあげたらエラーが発生するのか最初はいまいちわかりませんでした。

これについて、RDSがデフォルトで設定するパラメータグループを確認したところ、rds.force_sslというSSL接続を強制する設定が、Postgre14までは0であったのに対し、Postgre15からは1に変更されていました!

↓これ

ちなみに、AuroraのDBを作った時にデフォルトで設定されるパラメータグループを確認すると、こちらは0でした。なんで。。

ということで、対策をいくつか考えていきます。

対策案①:RDSのパラメータグループを変更する

まず思いつくのが、RDSのパラメータグループを変更する、ですね。
rds.force_sslを0にすれば解決します。
が、ちょっとこれだとおもしろくないですし、セキュリティ的に弱い方に倒してしまうことになるので、別の方法を考えます。

対策案②:アプリのSSL接続設定を有効にする(セキュリティ弱め)

続いて考えるのが、アプリからDBにSSL接続するにはどうしたらよいか、です。
今回のアプリはTypeScript&TypeORMで構築しているため、「TypeORM SSL」で検索すると、以下のstack overflowのやりとりが引っかかります。

https://stackoverflow.com/questions/56660312/cannot-connect-an-ssl-secured-database-to-typeorm

この中の2つ目の回答に出てくる通り、ormconfigに以下の設定を加えることで、SSL接続の設定が可能になります。

orconfig.js
  "ssl": true,
  "extra": {
    "ssl": {
      "rejectUnauthorized": false
    }
  }

ただ、"rejectUnauthorized": falseという設定が少し気になります。
この項目について少し調べてみると、PostgreSQLサーバーの証明書の検証を無効にする設定のようです。
ローカル環境であれば問題ないですし、今回はVPCの中で通信するだけなので、正直これでも問題ないと思いますが、ちゃんと証明書の検証をやるにはどうしたら良いのかが気になり、その方法を考えます。

対策案③:アプリのSSL接続設定を有効にする(セキュリティ強め)

調べた結果、というか、先ほどのstack overflowのリンク先に、サーバ証明書の検証まで行う方法の記載がありました。
ormconfig.jsに以下の設定を加えればOKです。

orconfig.js
  ssl: {
    ca: fs.readFileSync("./certs/global-bundle.pem").toString(),
  },

CAの証明書は、AWSの以下ページにあったのでこれを使用します。
「すべての AWS リージョン の証明書バンドル」というセクションにある、global-bundle.pemをダウンロードしました。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html

これで、TypeORMを使っているアプリから、SSLでDBに接続することができました!
今回はTypeORMを例にして説明しましたが、他のORMのツールでもきっと似たような設定があると思われます。

おまけ:ローカルではSSL接続しないための設定

上記の設定で、本番環境は問題ないのですが、ローカルで立ち上げているdockerなどのDBに接続しようとすると以下のエラーが発生します。

(node:86777) UnhandledPromiseRejectionWarning: Error: The server does not support SSL connections

なので、ormconfig.jsを以下のように記載し、ローカルではSSL接続をしないように設定します(本番環境では環境変数のIS_LOCALをfalseでセットします)。

orconfig.js
module.exports =
  process.env.IS_LOCAL === "false"
    ? {
        ...defaultConfig,
        ssl: {
          ca: fs.readFileSync("./certs/global-bundle.pem").toString(), // RDSのPostgre15のデフォルト設定でsslが強制されている
        },
      }
    : defaultConfig;
NCDCエンジニアブログ

Discussion