N予備校 【2020年度】プログラミング入門 Webアプリ
[第4章24節 【サービス開発9】セキュリティ対策と公開]
Herokuの設定で詰まったので解決した手順を記載。
Database / GitHubのOAuthなどの設定を終えてHerokuのアプリを起動し、ログインをしようとすると下記のエラーが発生
2021-02-21T03:05:26.710859+00:00 app[web.1]: Unhandled rejection SequelizeConnectionError: no pg_hba.conf entry for host "XX.XXX.XXX.XXX", user "xxxxxxxxxx", database "xxxxxxxxxxxx", SSL off
2021-02-21T03:05:26.710870+00:00 app[web.1]: at connection.connect.err (/app/node_modules/sequelize/lib/dialects/postgres/connection-manager.js:182:24)
2021-02-21T03:05:26.710870+00:00 app[web.1]: at Connection.connectingErrorHandler (/app/node_modules/pg/lib/client.js:194:14)
2021-02-21T03:05:26.710871+00:00 app[web.1]: at Connection.emit (events.js:198:13)
2021-02-21T03:05:26.710872+00:00 app[web.1]: at Socket.<anonymous> (/app/node_modules/pg/lib/connection.js:134:12)
2021-02-21T03:05:26.710872+00:00 app[web.1]: at Socket.emit (events.js:198:13)
2021-02-21T03:05:26.710872+00:00 app[web.1]: at addChunk (_stream_readable.js:288:12)
2021-02-21T03:05:26.710873+00:00 app[web.1]: at readableAddChunk (_stream_readable.js:269:11)
2021-02-21T03:05:26.710874+00:00 app[web.1]: at Socket.Readable.push (_stream_readable.js:224:10)
2021-02-21T03:05:26.710874+00:00 app[web.1]: at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
2021-02-21T03:05:56.475031+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=GET path="/auth/github/callback?code=025f7e4e57093209889a" host=limitless-lowlands-54630.herokuapp.com request_id=31dc51eb-fd89-48fb-9155-a08b997709de fwd="153.207.171.208" dyno=web.1 connect=1ms service=30001ms status=503 bytes=0 protocol=https
・アプリからDB接続ができない (pg_hba.confの設定が足りない?)
・GitHubの認証がタイムアウトする (一つ前のDB接続エラー起因かはこの時点では不明)
エラーメッセージと pg_hba.conf、Herokuでぐぐってみたところ、解決方法としてHerokuの環境変数でDB接続をSSL化するか、node-jsのソース側でこのエラー制御を無視することができるようでした。
環境変数の追加が簡単そうだったので、方法1で対処しました。
##【方法1】
参考にした記事
https://qiita.com/hiro93n/items/fe015ce9517f139edbeb
Herokuに環境変数を設定する
heroku config:set PGSSLMODE=require
環境変数を更新したらHerokuが再起動して接続できるようになり、GitHub認証のタイムアウトエラーも解消しました。
2021-02-21T03:14:46.096182+00:00 app[api]: Release v11 created by user xxxxxxxxxx
2021-02-21T03:14:46.096182+00:00 app[api]: Set PGSSLMODE config vars by user xxxxxxxxxx
2021-02-21T03:14:46.573285+00:00 heroku[web.1]: Restarting
2021-02-21T03:14:46.590224+00:00 heroku[web.1]: State changed from up to starting
2021-02-21T03:14:48.006684+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2021-02-21T03:14:48.223861+00:00 heroku[web.1]: Process exited with status 143
2021-02-21T03:14:50.316993+00:00 heroku[web.1]: Starting process with command `npm start`
Warningの中に、node-jsが理由を説明しているログがありました。
2021-02-21T03:14:53.846841+00:00 app[web.1]: (node:21) DeprecationWarning:
Implicit disabling of certificate verification is deprecated and will be removed in pg 8.
Specify `rejectUnauthorized: true` to require a valid CA or `rejectUnauthorized: false`
to explicitly opt out of MITM protection.
暗黙的な証明書検証の無効化は非推奨となっていますので、pg 8で削除されます。rejectUnauthorized: true で証明書の検証をしているものをrejectUnauthorized: falseと指定することで、明示的に中間者攻撃防御を解除してください。
##【方法2】
Herokuの公式ドキュメント[Heroku Posgres]
https://devcenter.heroku.com/articles/heroku-postgresql#connecting-in-node-js
先ほどの理由からPosgreのDB接続用のインスタンスを生成するときに、ssl証明書検証の設定をfalseに明示的に設定する。
const client = new Client({
connectionString: process.env.DATABASE_URL,
ssl: {
rejectUnauthorized: false
}
});
今回は方法1で接続できましたが、方法2も公式ドキュメントの情報なので問題なく解決できそうです。
もし4章の最後の節で詰まってる方がいましたらご参考まで。