next.js
で作ったアプリをSSL化しようとしたところ以下のエラーに悩まされた。
Error: error:0909006C:PEM routines:get_name:no start line
調べて出てくる情報が色々とおかしかったので大分苦労しました。
今回の内容は基本的にexpress
でLet's Encrypt
の証明を行うための方法です。
certbot
とりあえず証明書をつくります。
これまでやってきた方法が古かったので最初は失敗の連続でした。
そこで公式ドキュメントのcertbot-auto
を使う方法に変えると一発でした。
httpsモジュールとhttp2モジュール
証明書の読み込みでhttps.createServer
を使っていましたが、後述する読み込み失敗の連続でhttp2.createSecureServer
に変えたりしました。
certbot-express
も試してみたり。
結局無関係でしたが最終的にhttps
モジュールに戻りました。
証明書の読み込み
ここがきつかったです。
「express https」、「express certbot」や「http2 certbot」など調べると出てくる内容がかなり違います。
失敗自体は他にもありましたが頑なに解決しない以下のエラーだけ対象にします。
Error: error:0909006C:PEM routines:get_name:no start line
失敗例1
最初に参照した内容です。
1 2 3 4 5 6 7 8 |
const exp = express(); const server = https.createServer( { key: fs.readFileSync("/etc/letsencrypt/live/narumium.net/cert.pem"), cert: fs.readFileSync("/etc/letsencrypt/live/narumium.net/privkey.pem") }, exp ); |
ちょっとよく見るとkey
とcert
で読み込む内容が逆です。
この間違いがしばらく後を引いて大分遠回りしました。
ネット上の情報をそのまま使うのはいけない(再確認)。
失敗例2
これはかなり多くのサイトに載っている方法です。
1 2 3 4 5 6 7 8 |
const server = https.createServer( { key: fs.readFileSync("/etc/letsencrypt/live/narumium.net/privkey.pem"), cert: fs.readFileSync("/etc/letsencrypt/live/narumium.net/cert.pem") //,ca: fs.readFileSync("/etc/letsencrypt/live/narumium.net/chain.pem") }, exp ); |
ca(中間証明書)の有無は今回のエラーとは関係ありません。
配列で指定するような内容も見かけましたが駄目でした。
またreadFileSync
のutf8
指定の有無も関係ありませんでした。
fs.readFileSync
で失敗してるのかと思いきや別途読み込んでtoString()
してみると全てちゃんと読み込めていました。
成功例
今回多く調べた中の一部でこの方法を書いていました。
1 2 3 4 5 6 7 |
const server = https.createServer( { key: fs.readFileSync("/etc/letsencrypt/live/narumium.net/privkey.pem"), cert: fs.readFileSync("/etc/letsencrypt/live/narumium.net/fullchain.pem") }, exp ); |
cert
にcert.pem
ではなくfullchain.pem
を指定します。
正直納得いきませんでしたがこの方法で動きました。
fullchain.pem
はなんなんだと調べるとcert.pem
(証明書)とchain.pem
(中間証明書)の連結ファイルのようです。それなら納得。
名前につられず中身を理解しないとダメだな。