ARM 版 AL2023 で lego で Route53 認証をし、Let's Encrypt のワイルドカード証明証取得を自動化する
以前に lego を使い Route53 認証でサーバ証明書を取得する (2020/09/27 版) という、amd64 な Amazon Linux 2 ベースのメモを書きました。 今回は ARM 版 Amazon Linux 2023 をベースに、以前のメモと同じく lego を使って Let's Encrypt を Route53 認証し、ワイルドカード証明書を自動取得する方法をメモしておきます。
検証環境
Amazon Linux 2023 は ARM 版の t4g.micro インストールを利用しました。
対象 |
バージョン |
Amazon Linux |
2023.6.20241031 |
lego |
4.19.2 |
IAM ポリシーの作成
以下の内容で IAM ポリシーを新規作成します。 <INSERT_YOUR_HOSTED_ZONE_ID_HERE>
部分は Route53 の管理画面で該当 DNS Zone 情報から取得します。 IAM ポリシーを作成したら、それを参照するロールを作成し、更にそれを参照するように EC2 インスタンスを設定します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:GetChange",
"route53:ListHostedZonesByName",
"route53:ListResourceRecordSets"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/<INSERT_YOUR_HOSTED_ZONE_ID_HERE>"
]
}
]
}
|
lego のインストール
GitHub から ARM 用のバイナリをダウンロードし、インストールします。
curl -LO https://github.com/go-acme/lego/releases/download/v4.19.2/lego_v4.19.2_linux_arm64.tar.gz
tar zxvf lego_v4.19.2_linux_arm64.tar.gz
mv lego /usr/local/bin/
chmod 755 /usr/local/bin/lego
chown root:root /usr/local/bin/lego
rm CHANGELOG.md LICENSE lego_v4.19.2_linux_arm64.tar.gz
lego --version
を実行してバージョン情報が表示されれば正しくインストールされています。
# lego --version
lego version 4.19.2 linux/arm64
Region の設定
lego で証明書を取得しようとすると以下のように「Invalid Configuration: Missing Region
」というエラーになってしまいました。
| 2024/11/04 18:47:59 Could not obtain certificates:
error: one or more domains had a problem:
[*.example.com] [*.example.com] acme: error presenting token: route53: failed to determine hosted zone ID: operation error Route 53: ListHostedZonesByName, failed to resolve service endpoint, endpoint rule error, Invalid Configuration: Missing Region
[example.com] [example.com] acme: error presenting token: route53: failed to determine hosted zone ID: operation error Route 53: ListHostedZonesByName, failed to resolve service endpoint, endpoint rule error, Invalid Configuration: Missing Region
|
Region を設定するには aws configure
して設定ファイルを作成しても良いのですが、AccessKey / SecretKey を設定したく無い為、以下のように手動で ~/.aws/config
ファイルを作成しました。
| mkdir ~/.aws
cat << 'EOF' >> ~/.aws/config
[default]
region = ap-northeast-1
output = json
EOF
|
証明書の手動取得
lego を手動で実行し、証明書を取得する例は以下の通りです。 取得した証明書関連ファイルは /etc/letsencrypt/certificates
配下に保存されます。 IAM ポリシーベースで認証させている為、証明書取得時の DNS 認証用レコードは Route53 へ自動的に作成され、lego
は対話的な入力は不要で終了します。 デフォルトでは ECDSA が利用されます。
/usr/local/bin/lego \
--accept-tos \
--path=/etc/letsencrypt \
--email="email@example.com" \
--dns="route53" \
--domains="example.com" \
--domains="*.example.com" \
run
明示的に RSA 指定したい場合は --key-type rsa2048
を追加します。
/usr/local/bin/lego \
--accept-tos \
--path=/etc/letsencrypt \
--email="email@example.com" \
--dns="route53" \
--domains="example.com" \
--domains="*.example.com" \
--key-type rsa2048 \
run
証明書の自動更新
証明書の更新は Systemd Timer で定期実行します。 今回は以下のような設定ファイルを作成しました。
/etc/systemd/system/lego-renew.timer
| [Unit]
Description=Lego Cert Renewal Timer
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
AccuracySec=1m
[Install]
WantedBy=timers.target
|
/etc/systemd/system/lego-renew.service
証明書の有効期限が 10 日を切ってから更新処理を行うようにする為、--days 10
を指定します。 証明書の初回発行時と同様、明示的に RSA 指定したい場合は --key-type rsa2048
を追加します。
| [Unit]
Description=Lego Cert Renewal
[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/lego --accept-tos --path=/etc/letsencrypt --email="email@example.com" --dns="route53" --domains="example.com" --domains="*.example.com" renew --days 10
[Install]
WantedBy=multi-user.target
|
タイマーを開始します。
systemctl daemon-reload
systemctl start lego-renew.timer
systemctl enable lego-renew.timer
ログの確認
動作ログを確認したい場合は以下を実行します。
journalctl -u lego-renew.timer
また「スケジューリング状況」(次、いつ実行されるのか?) を確認したい場合は以下を実行します。
参考
lego のヘルプ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 | # lego --help
NAME:
lego - Let's Encrypt client written in Go
USAGE:
lego [global options] command [command options]
VERSION:
4.19.2
COMMANDS:
run Register an account, then create and install a certificate
revoke Revoke a certificate
renew Renew a certificate
dnshelp Shows additional help for the '--dns' global option
list Display certificates and accounts information.
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--domains value, -d value [ --domains value, -d value ] Add a domain to the process. Can be specified multiple times.
--server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory") [$LEGO_SERVER]
--accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service. (default: false)
--email value, -m value Email used for registration and recovery contact.
--csr value, -c value Certificate signing request filename, if an external CSR is to be used.
--eab Use External Account Binding for account registration. Requires --kid and --hmac. (default: false) [$LEGO_EAB]
--kid value Key identifier from External CA. Used for External Account Binding. [$LEGO_EAB_KID]
--hmac value MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding. [$LEGO_EAB_HMAC]
--key-type value, -k value Key type to use for private keys. Supported: rsa2048, rsa3072, rsa4096, rsa8192, ec256, ec384. (default: "ec256")
--filename value (deprecated) Filename of the generated certificate.
--path value Directory to use for storing the data. (default: "/root/.lego") [$LEGO_PATH]
--http Use the HTTP-01 challenge to solve challenges. Can be mixed with other types of challenges. (default: false)
--http.port value Set the port and interface to use for HTTP-01 based challenges to listen on. Supported: interface:port or :port. (default: ":80")
--http.proxy-header value Validate against this HTTP header when solving HTTP-01 based challenges behind a reverse proxy. (default: "Host")
--http.webroot value Set the webroot folder to use for HTTP-01 based challenges to write directly to the .well-known/acme-challenge file. This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge
--http.memcached-host value [ --http.memcached-host value ] Set the memcached host(s) to use for HTTP-01 based challenges. Challenges will be written to all specified hosts.
--http.s3-bucket value Set the S3 bucket name to use for HTTP-01 based challenges. Challenges will be written to the S3 bucket.
--tls Use the TLS-ALPN-01 challenge to solve challenges. Can be mixed with other types of challenges. (default: false)
--tls.port value Set the port and interface to use for TLS-ALPN-01 based challenges to listen on. Supported: interface:port or :port. (default: ":443")
--dns value Solve a DNS-01 challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.
--dns.disable-cp (deprecated) use dns.propagation-disable-ans instead. (default: false)
--dns.propagation-disable-ans By setting this flag to true, disables the need to await propagation of the TXT record to all authoritative name servers. (default: false)
--dns.propagation-rns By setting this flag to true, use all the recursive nameservers to check the propagation of the TXT record. (default: false)
--dns.propagation-wait value By setting this flag, disables all the propagation checks of the TXT record and uses a wait duration instead. (default: 0s)
--dns.resolvers value [ --dns.resolvers value ] Set the resolvers to use for performing (recursive) CNAME resolving and apex domain determination. For DNS-01 challenge verification, the authoritative DNS server is queried directly. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.
--http-timeout value Set the HTTP timeout value to a specific value in seconds. (default: 0)
--dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name server queries. (default: 10)
--pem Generate an additional .pem (base64) file by concatenating the .key and .crt files together. (default: false)
--pfx Generate an additional .pfx (PKCS#12) file by concatenating the .key and .crt and issuer .crt files together. (default: false) [$LEGO_PFX]
--pfx.pass value The password used to encrypt the .pfx (PCKS#12) file. (default: "changeit") [$LEGO_PFX_PASSWORD]
--pfx.format value The encoding format to use when encrypting the .pfx (PCKS#12) file. Supported: RC2, DES, SHA256. (default: "RC2") [$LEGO_PFX_FORMAT]
--cert.timeout value Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30)
--overall-request-limit value ACME overall requests limit. (default: 18)
--user-agent value Add to the user-agent sent to the CA to identify an application embedding lego-cli
--help, -h show help
--version, -v print the version
|
lego renew のヘルプ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | # lego renew --help
NAME:
lego renew - Renew a certificate
USAGE:
lego renew [command options]
OPTIONS:
--days value The number of days left on a certificate to renew it. (default: 30)
--ari-enable Use the renewalInfo endpoint (draft-ietf-acme-ari) to check if a certificate should be renewed. (default: false)
--ari-wait-to-renew-duration value The maximum duration you're willing to sleep for a renewal time returned by the renewalInfo endpoint. (default: 0s)
--reuse-key Used to indicate you want to reuse your current private key for the new certificate. (default: false)
--no-bundle Do not create a certificate bundle by adding the issuers certificate to the new certificate. (default: false)
--must-staple Include the OCSP must staple TLS extension in the CSR and generated certificate. Only works if the CSR is generated by lego. (default: false)
--not-before value Set the notBefore field in the certificate (RFC3339 format)
--not-after value Set the notAfter field in the certificate (RFC3339 format)
--preferred-chain value If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name. If no match, the default offered chain will be used.
--always-deactivate-authorizations value Force the authorizations to be relinquished even if the certificate request was successful.
--renew-hook value Define a hook. The hook is executed only when the certificates are effectively renewed.
--no-random-sleep Do not add a random sleep before the renewal. We do not recommend using this flag if you are doing your renewals in an automated way. (default: false)
--help, -h show help
|