Express.jsアプリケーションをHTTPSサーバ化ではまった際に見直したい項目、確認方法について記載します。
普通に設定できていれば問題なく繋がるはずです。エラーが出ていた場合は何かしら設定ミスがあるはずなので一つ一つ確認していきましょう。
ポート・サービスの確認
サーバ側でポート、サービスを開放していないとブラウザから接続エラーが表示されます。
CentOS7の場合は、firewalldで設定します。
//ポートの確認 sudo firewall-cmd --list-ports --zone=public //サービスの確認 sudo firewall-cmd --list-service --zone=public //4000ポート追加 sudo firewall-cmd --zone=public --add-port=3000/tcp --permanent //httpsサービス追加 sudo firewall-cmd --zone=public --add-service=https --permanent //設定後は再起動 sudo systemctl restart firewalld
証明書のアクセス権限確認
アプリケーションを通常ユーザで実行する場合、証明書に権限を設定するのも忘れないようにしましょう。
//権限付与設定例 sudo chmod 755 /etc/letsencrypt/live sudo chmod 755 /etc/letsencrypt/live/xxxxxxxx.xyz sudo chmod 744 /etc/letsencrypt/live/xxxxxxxx.xyz/privkey.pem sudo chmod 744 /etc/letsencrypt/live/xxxxxxxx.xyz/chain.pem sudo chmod 744 /etc/letsencrypt/live/xxxxxxxx.xyz/cert.pem
上記のサーバ設定ができていれば問題なくつながります。
繋がらない場合はいづれかの設定に不備があるので、設定を確認していきます。
私はブラウザで「ERR_SSL_VERSION_OR_CIPHER_MISMATCH」が出てしばらくはまりましたので、その際の原因切り分けについて書いていきます。
証明書の確認
openssl
アクセスする端末からopensslコマンドをたたいて確認します。
問題なければ証明書情報が出力されて最後に「Verify return code: 0 (ok)」となります。
openssl s_client -connect xxxxxxxx.xyz:4000
私は「routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure」が出ていました。
参考
SSL SERVER TESTでもう少し詳細にエラーメッセージを確認することもできます。
ポートは443にする必要がありますので、node.jsアプリのlistenポートを443にしてroot権限で起動してからテストしてみてください。
httpdサービスで確認
証明書発行ミスの可能性もありますので、Apache httpdサービスで確認してみます。
Express.jsでもApache httpdでも繋がらなければ証明書が不正と考えられます。
sudo vi /etc/httpd/conf.d/ssl.conf //以下項目に取得した証明書を設定 SSLCertificateFile SSLCertificateKeyFile SSLCertificateChainFile //httpd起動 sudo systemctl start httpd openssl s_client -connect xxxxxxxx.xyz:443
これで繋がれば証明書に問題はないことになります。
httpdサービスが使えない場合、自己証明書で確認することもできます。
//任意の場所で以下コマンドを実行 openssl genrsa 2024 > key.pem openssl req -new -key key.pem > req.pem openssl x509 -req -in req.pem -signkey key.pem -out cert.pem
Express.jsでkey:key.pem、cert:cert.pemを設定することで自己証明書を使用したhttpsサーバを構築できます。
自己証明書なので信頼されていない証明書のメッセージが出力されますが、そこまでいければ証明書はOKです。
アプリケーションの確認
証明書に問題がなければアプリケーションでのコーディングミスが考えられます。
公式ドキュメントを参考にhttps.createServerの記載を再度確認してみてください。
ドキュメントにはありませんが、「key」「cert」「ca」の項目名は固定で記載してください。
今回は記載ミスが原因でした。
const http = require('http'); const https = require('https') option = { key: fs.readFileSync('/etc/letsencrypt/live/xxxxxxxx.xyz/privkey.pem'), cert: fs.readFileSync('/etc/letsencrypt/live/xxxxxxxx.xyz/cert.pem'), ca: fs.readFileSync('/etc/letsencrypt/live/xxxxxxxx.xyz/chain.pem') } const httpsServer = https.createServer(option, app); httpsServer.listen('4000');
コメントを残す