はじめに
Let's Encrypt では、ワイルドカード証明書の発行が計画されおり、2018年 1月現在、ステージングサーバー上で ACME v2 によるワイルドカード証明書の発行がテストされています。
そこで、Go 言語で、ACME v2 クライアントツールを作成し、ワイルドカード証明書の発行をテストしてみます。
プロダクション環境への展開は、2018年 2月 終りごろが予定されている模様です。
2/22 追記
Let's Encrypt による ACME v2 のリリースは、延期の見込みとのことです。
プロダクションへのローンチ後、ワイルドカード証明書の実用発行の運用についての記事をアップする予定です。
3/14 追記
ACME v2 リリースされました。
必要なもの
-
TXT レコードを設定できるドメイン
-
Go 言語コンパイラー (v1.9.3)
-
openssl コマンド (Windows では、Git for Windows に付属)
本稿でのワークステーションの環境は、Windows 10 です。
以下、ドメイン名として example.jp と例示しますが、実際には、ご自分のドメイン名に読み替えてください。
ツールのビルド
> go get -u github.com/noumia/acme/cmd/wild-le
%GOPATH%\bin へ、実行ファイルが作成されるので、パスを通しておきます。
アカウントの作成
> openssl genrsa -out account.key 4096
> wild-le account -c acme@example.jp --agree-tos
メールアドレスの登録は任意ですが、利用規約には同意する必要があります。
証明書の発行リクエスト
サーバー秘密鍵を作成します。アカウント用の鍵と共用することはできません。
> openssl genrsa -out server.key 2048
証明書の発行
> wild-le renew -d *.example.jp server.crt
DNSSetup TXT: _acme-challenge.example.jp 8ZkX2so-Beyzq2RWmntJ_dsR_-W1B_j5X-7OXNNoPiI
Continue?
-d オプションで、'*.' から始まるドメイン名を指定すると、ワイルドカード証明書となります。通常のドメイン名を指定することもできます。
表示されたドメイン (_acme-challenge.example.jp) の TXT レコードへ、表示された認証用のテキスト (8ZkX2...) を設定してください。
設定できたら、y [Enter] とタイプすることで、処理が続行されます。(レコードの設定反映を確認するため、数分程度の時間を要することがあります。)
エラーが起きなければ、server.crt へ証明書が出力されます。
動作確認
caddy サーバーを使用して、動作確認します。
www.example.jp としてアクセスできるサーバーに、Caddyfile, server.crt, server.key を配置します。
Caddyfile
https://www.example.jp {
tls server.crt server.key
}
サーバーの起動
> caddy
Activating privacy features... done.
https://www.example.jp
クライアント側のテスト
ステージングサーバーでは、正規の証明書ではなく、テスト用証明書の発行なので、テスト用ルート証明書をダウンロードします。
> curl http://cert.stg-root-x1.letsencrypt.org/ | openssl x509 -inform der -outform pem -out stg-root-x1.pem
> curl -v --cacert stg-root-x1.pem https://www.example.jp
* Rebuilt URL to: https://www.example.jp/
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to www.example.jp (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: stg-root-x1.pem
CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=*.example.jp
* start date: Jan 26 08:16:33 2018 GMT
* expire date: Apr 26 08:16:33 2018 GMT
* subjectAltName: host "www.example.jp" matched cert's "*.example.jp"
* issuer: CN=Fake LE Intermediate X1
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x1e1406f40e0)
> GET / HTTP/2
> Host: www.example.jp
> User-Agent: curl/7.58.0
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 404
< content-type: text/plain; charset=utf-8
< server: Caddy
< x-content-type-options: nosniff
< content-length: 14
< date: Fri, 26 Jan 2018 09:30:40 GMT
<
404 Not Found
* Connection #0 to host www.example.jp left intact
証明書エラーが発生しなければ、成功です。