去年から気になっていた Let's Encrypt がクローズドベータになり、申請すれば実際に証明書の発行がテストできると聞いたので、早速申請して証明書の発行を行ってみました。ただし IIS で使う前提です。
Let’s EncryptでValidなSSL/TLS証明書を取得する | DevelopersIO
DockerでLet’s Encryptしよっか - Qiita
既に証明書の発行を試した方も居たので参考にしていたのですが、既に微妙に挙動が変わっているので注意したいです。一応ドキュメントも公開されてますが、メールに書いてあった分で十分な感じです。
User Guide The Let’s Encrypt project — letsencrypt latest documentation
Let's Encrypt では Web サーバーへの証明書設定まで自動化するのが目標みたいですが、当然ながら IIS には対応してくれないと思うので、証明書だけ作成して後は自分で頑張ります。
今回は shibayan.jp への申請が通っているので、下のようなコマンドで証明書の発行を開始します。
./letsencrypt-auto certonly -a manual -d shibayan.jp --server https://acme-v01.api.letsencrypt.org/directory --agree-dev-preview
ちなみに Raspberry Pi 2 上で全ての処理を試してみました。コンパイルは遅かったですが普通に使えます。
Let's Encrypt のクライアントが起動すると、メールアドレスの入力を最初に求められます。これは緊急時やキーを失くして復旧する時などに通知するために使うみたいです。
メールアドレスを入力した後は、利用規約に同意するように言われます。PDF が利用規約になってます。
同意すると、今度は IP アドレス記録しますよという確認画面が出てきます。証明書を作成するのに使われた情報をログに書き出されても、普通の使い方では別に気にすることもなさそうです。
ドメインはコマンド実行時に指定してたので聞かれませんでした。
終わると発行したいドメイン上に特殊なファイルを置く作業が必要です。このファイルを取得できるかでドメインの所有者かどうか判別するようです。
Python で簡単にレスポンスを返すためのサンプルが付いてますが、shibayan.jp は IIS なので IIS で頑張ることにしました。と言っても静的なファイルを置くだけなのでたいした手間ではありません。
まずはファイルを Web Apps 上に作成するのですが、Kudu の Debug Console で下のようなコマンドを打ち込めば、指定された名前で空のファイルを作成するところまではあっという間に出来ると思います。
cd site\wwwroot mkdir ".well-known/acme-challenge" & cd .well-known/acme-challenge touch {コンソールに出力されているファイル名}
作成されたファイルを開いて、さっきの画面に出てきたトークンを張り付けて保存すれば準備は完了です。
しかし、IIS はデフォルトでは拡張子がないファイルを返さないので、Web.config を追加で作成して拡張子のないファイルに対する MIME マップを追加する必要があります。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <staticContent> <mimeMap fileExtension="." mimeType="text/plain" /> </staticContent> </system.webServer> </configuration>
今回は text/plain を返す必要があるので上のように定義します。ちなみに拡張子のないファイルを対象にする場合は、ピリオドだけを fileExtension に指定します。
これでファイルの準備が完了したので、クライアントに戻って検証を進めます。と言っても Enter キーを一回押すだけです。設置したファイルにちゃんとアクセス出来れば証明書が作成されます。
作成された証明書は /etc/letencrypt/live 以下に保存されています。Let's Encrypt は中間証明書が必要なので、基本的には全て含まれた fullchain.pem を使えば良さそうです。
Apache や nginx の場合は PEM で良いみたいですが、IIS の場合は PFX に変換する必要があるので、OpenSSL を使って fullchain.pem と privkey.pem から PFX 形式に変換を行います。
具体的なコマンドは以下のような感じで変換できます。
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out shibayan.pfx
途中でエクスポート用のパスワードを要求されるので、間違えないように入力します。失敗すると Web Apps へのアップロードが出来なくなります。
PFX に変換出来たら、これまでと同じように Azure ポータルから PFX をアップロードします。
パスワードは openssl で変換した時に入力したものです。
アップロードが完了するとドメインと証明書のマッピングが可能となっているので、適切なドメインと証明書を選択して設定保存すると、SSL の設定は全て完了です。ポータル
Let's Encrypt は今のところ 90 日有効な証明書しか発行できません。正式にリリースされたタイミングではもっと長い期間有効な証明書が取れるはずです。
追記
正式にリリースされても 90 日有効な証明書しか取れないようです。
Why ninety-day lifetimes for certificates? - Let's Encrypt
理由としてはキーが流出してしまった場合や証明書更新の自動化を促すためのようです。90 日ごとに手動で更新するのは大変なので、設定含めて全て自動化が求められることになります。
証明書の設定が完了したので https でアクセスしてみました。認証局が Let's Encrypt Authority X1 になっているのが確認できますね。証明書には問題がないことも確認できます。
シェルスクリプトや Python が当たり前のように使われているので Windows 環境だけだと難易度が高いですが、一度証明書を発行してしまえば IIS でも極々普通に利用できることが分かりました。
Windows 向けに ACME を喋るクライアントがあればいいのかも知れませんが、当分先になる気がします。とりあえずは OS X や仮想マシン上の Linux などで発行だけするのが良さそうです。