Let's Encrypt のワイルドカード証明書発行がリリースされました。
プロダクション環境でのワイルドカード証明書が可能になったので、example.jp と、*.example.jp のマルチドメインで使用できるワイルドカード証明書を発行してみます。
必要なもの
-
TXT レコードを設定できるドメイン (Google Cloud DNS 等 API 対応のサービス利用が望ましい)
-
Go 言語コンパイラー (v1.10)
-
openssl コマンド (Windows では、Git for Windows に付属)
本稿でのワークステーション環境は、Windows 10 です。
ドメイン名として example.jp と例示していますが、実際には、ご自分のドメイン名に読み替えてください。
ツールのビルド
> go get -u github.com/noumia/acme/cmd/wild-le
%GOPATH%\bin へ、実行ファイルが作成されるので、パスを通しておきます。
アカウントの作成
今回は、ECDSA の鍵を使用してみます。(RSA でも勿論可です。)
> openssl ecparam -out account.key -name prime256v1 -genkey
> wild-le account -c acme@example.jp --agree-tos
メールアドレスの登録は任意ですが、利用規約には同意する必要があります。
証明書の発行リクエスト
サーバー秘密鍵を作成します。アカウント用の鍵と共用することはできません。
サーバー用の鍵も ECDSA にしてみます。
> openssl ecparam -out server.key -name prime256v1 -genkey
CSR の作成
example.jp と、*.example.jp の両方で使用できるようにマルチドメインの設定を行った CSR を作成します。
まず、テンプレートファイル (example.jp.conf) を作成します。
[req]
distinguished_name=dn
req_extensions=ex
[dn]
[ex]
subjectAltName=@alt_names
[alt_names]
DNS.1=example.jp
DNS.2=*.example.jp
キーポイントは、最終 2 行での subjectAltName 設定です。
> openssl req -new -key server.key -sha256 -out server.csr -subj "/CN=example.jp" -config example.jp.conf
以下コマンドで、CSR の内容を確認します。
> openssl req -in server.csr -text -noout
X509v3 Subject Alternative Name: が設定されているか確認してください。
証明書の発行
> wild-le renew server.crt
DNSSetup TXT: _acme-challenge.example.jp 8ZkX2so-Beyzq2RWmntJ_dsR_-W1B_j5X-7OXNNoPiI
Continue?
表示されたドメイン (_acme-challenge.example.jp) の TXT レコードへ、表示された認証用のテキスト (8ZkX2...) を設定してください。
設定できたら、y [Enter] とタイプすることで、処理が続行されます。(レコードの設定反映を確認するため、数分程度の時間を要することがあります。)
example.jp と、*.example.jp の両方の認証を行う場合は、2回確認手続きが必要になります。
エラーが起きなければ、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 コマンド等でアクセスできれば、成功です。
example.jp, api.example.jp 等のドメイン名も、同じ証明書で使用できるはずです。
自動更新
Let's Encrypt から発行される証明書は、有効期間が 90 日と短めですので、証明書の自動更新が必要です。
本ツールでも、DNS 認証設定用のフックスクリプトに対応していますので、対応する DNS プロバイダーを使用することで、自動更新が可能です。
wild-le renew -l フックスクリプト
Let's Encrypt クライアントである lego をベースとした DNS 設定ツールを用意したので、Google Cloud DNS 等の自動設定可能な DNS サービスを利用されている場合には、自動更新を実現できます。
DNS 設定ツールのビルド
> go get -u github.com/noumia/acme/cmd/dns-lego
自動更新の運用例
Google Cloud DNS を使用している場合の例を説明します。
Google Cloud DNS API を使用するために適切な権限を割り当てた Service Account を作成して、その Key JSON ファイルを、機密の確保された場所に保存します。
スクリプトの所定の環境変数に、KeyJSON ファイルパスと、Google Cloud のプロジェクト名を設定してください。
LEGO_DNS_PROVIDER には、対応するプロバイダーを設定します。(gcloud: Google Cloud DNS)
使用できるプロバイダーの一覧は、以下の通りになります。
定期実行するスクリプトの例
@rem renew.cmd
@echo off
set GOOGLE_APPLICATION_CREDENTIALS=<pathToServiceAccountKeyJSON>
set GCE_PROJECT=<projectName>
set LEGO_DNS_PROVIDER=gcloud
rem 証明書の有効期間をチェックしている
rem 30 日以上有効期間がある場合は、何もせず終了
wild-le cert server.crt
if not ERRORLEVEL 1 exit /b 0
wild-le renew -l dns-lego server.crt
if ERRORLEVEL 1 (
echo error!
exit /b 1
)
echo Congratulations! Your certificate and chain have been saved.
rem 証明書の更新が成功した
rem サーバーの更新処理などを記述する
exit /b 0
上記のようなスクリプトファイルを、スケジューラー等で 1日 1回 実行することで、自動更新を実現できます。