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(中間証明書)の連結ファイルのようです。それなら納得。
名前につられず中身を理解しないとダメだな。