Let's Encryptでワイルドカード証明書を取得する

せと です。ここ最近の渋谷の通りは、さくらが咲きだして春めいてきました。

今日は、先日から始まったLet's Encryptによるワイルドカード証明書の取得についてかいつまんでご紹介しようと思います。

ドメインの確認プロセス



ドメイン認証型証明書を発行してくれるLet's Encryptは従来、http-01、dns-01という方式を用いて、ドメインの確認を行っていましたが、ワイルドカード証明書の取得を行うには、dns-01方式のみ使用することができます。

http-01方式は、指定されたファイルの存在と内容の確認が行われることで、証明書の取得を行うことができ、自動化の仕組みを実装する難易度は低かったのですが、dns-01方式は、TXTレコードで指定された値を登録する必要があります。そのため、http-01方式と比べ自動化の仕組みの実装には、API操作が可能なDNSサービスを利用するか、自前でのDNSサーバーの運用が必要となります。

取得プロセスの実装



今回は、実際に使用するためではなく、証明書の取得テストをするためだったので、Let's Encryptのstaging エンドポイントを使って確認をしました。

DNSサーバーはRoute 53を使用していたので、API操作は https://github.com/barnybug/cli53などのツールを使うことも考えましたが、とりあえずperlで。と思い、LWP::UserAgentNet::Amazon::Signature::V4を使用しました。

AWSはAPIのドキュメントが、細かく書いてあるので、それを参考にしています。

https://docs.aws.amazon.com/ja_jp/Route53/latest/APIReference/API_ChangeResourceRecordSets.html

証明書の取得自体は、perlのモジュールもありますが、従来から使用していたツール(https://github.com/lukas2511/dehydrated)と組み合わせて使うので、フック処理にroute53の書き換えをするperlスクリプトを実行するように、実装しました。

コードについては割愛します。(perlで無理にしなくてもいいじゃん説はあるし、今回はプログラムに組み込む訳ではなかったので、aws-cliを使ったほうが楽なのでは?というあなた正解です!)

ハマったところ



Route 53へPOSTしたら、PENDINGとして応答が返ってきますが、実際に数秒ほどクエリの内容が変わるまで時間がかかります。

また、証明書に含めるドメインの数、すなわち、Subject Alternative Names (SANsともいいますが)の数だけ確認の回数が発生するので、そのひとつ前での確認プロセスで入れた値が引けてしまい、エラーとして判定されてしまいました。(example.com、*.example.comというような場合に)

そのため、Route 53へのPOST後、数秒から十数秒ほどwaitを入れて、Let's Encrypt側の確認で、指定された値が引けるように、配慮をする必要があります。

まとめ



今回は、Let's Encryptでのワイルドカード証明書の取得を試してみましたが、自動化していくには、エラーハンドリングは入念にする必要があると感じました。また、ある程度自由度の効くDNSサーバーも必要であることがわかりました。

HTTPSでの配信の難易度については、こういった証明書周辺の歩み寄りで以前比べてかなり下がってきており、シーサーでもいくつかのサービスでそういった変更をさせていただいている最中です。


この記事へのコメント