10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[AWS] Let's Encrypt で更新した証明書を自動的にアップロードして ELB の SSL 証明書を入れ替える

Last updated at Posted at 2016-11-07

AWS Certificate Manager 使えよって話なんですが、例えばドメイン認証に使用するためのメールアドレスは使えないけど、Web サーバ上に認証ファイルはおけるっていう限定的な環境で Let's Encrypt で更新した SSL 証明書を ELB にアップロードしたいとかって状況があるかもしれませんね。
実際あったんです。
そんな時は letsencrypt renew の後に aws-cli でアップロードするようにしてあげればいいんでないかなーと。

ELB 配下には複数のインスタンスがぶら下がってることが多いと思いますが、前提条件としては letsencrypt renew を実施するインスタンスは固定しておいて、ELB (application) のターゲットグループでパス /.well-known/* をそのインスタンスに流すように設定しておく必要があります。

あとは、そのインスタンスに以下のようなシェルスクリプトを作ります。

ELB v2(Application) の場合

upload-cert.sh
# !/bin/bash
set -eux

_domain='example.com'
_listener_arn='{ELB_LISTNER_ARN_HERE}'

_cert_path="/${_domain}/"
_date=$(date +%Y%m%d-%H%M%S)
_cert_name="${_domain}-${_date}"

# 新しいSSL証明書をアップロード
cd /etc/letsencrypt/live/${_domain}/
aws iam upload-server-certificate \
 --server-certificate-name ${_cert_name} \
 --certificate-body file://cert.pem \
 --private-key file://privkey.pem \
 --certificate-chain file://chain.pem \
 --path ${_cert_path}

# 新しいSSL証明書を ELB(Application) のターゲットグループにセット
sleep 60
_cert_arn=$(aws iam get-server-certificate --server-certificate-name ${_cert_name} | jq -r '.ServerCertificate.ServerCertificateMetadata.Arn')
aws elbv2 modify-listener \
 --listener-arn ${_listener_arn} \
 --certificates "CertificateArn=${_cert_arn}"

# 古いSSL証明書を削除
_certs=$(aws iam list-server-certificates --path-prefix ${_cert_path} | jq -r '.ServerCertificateMetadataList[].ServerCertificateName')
for _cert in ${_certs}; do
  if [ "${_cert_name}" != "${_cert}" ]; then
    aws iam delete-server-certificate --server-certificate-name ${_cert}
  fi
done

ELB v1(classic) の場合

upload-cert.sh
# !/bin/bash
set -eux

_domain='example.com'
_elb_name='{ELB_NAME_HERE}'
_elb_port='443'

_cert_path="/${_domain}/"
_date=$(date +%Y%m%d-%H%M%S)
_cert_name="${_domain}-${_date}"

# 新しいSSL証明書をアップロード
cd /etc/letsencrypt/live/${_domain}/
aws iam upload-server-certificate \
 --server-certificate-name ${_cert_name} \
 --certificate-body file://cert.pem \
 --private-key file://privkey.pem \
 --certificate-chain file://chain.pem \
 --path ${_cert_path}

# 新しいSSL証明書を ELB(classic) のリスナーにセット
sleep 60
_cert_arn=$(aws iam get-server-certificate --server-certificate-name ${_cert_name} | jq -r '.ServerCertificate.ServerCertificateMetadata.Arn')
aws elb set-load-balancer-listener-ssl-certificate \
 --load-balancer-name ${_elb_name} \
 --load-balancer-port ${_elb_port} \
 --ssl-certificate-id ${_cert_arn}

# 古いSSL証明書を削除
_certs=$(aws iam list-server-certificates --path-prefix ${_cert_path} | jq -r '.ServerCertificateMetadataList[].ServerCertificateName')
for _cert in ${_certs}; do
  if [ "${_cert_name}" != "${_cert}" ]; then
    aws iam delete-server-certificate --server-certificate-name ${_cert}
  fi
done

_domain_listener_arn (_elb_name, _elb_port) は、環境によって変更してあげてくださいね。
あと、jq 使ってるんで yum install jq とかでインストールしてあげてください。

そんで letsencrypt renew--renew-hook オプションで、証明書が更新された時に実行するコマンドとして登録するわけです。

letsencrypt renew --renew-hook '/root/bin/upload-cert.sh'

あとは、上のコマンドを crontab で定期的(週一回とか)に実行してあげれば、Let's Encrypt の SSL証明書が更新された時に自動的に ELB のターゲットグループに設定されてる証明書も更新されて古い証明書が削除されるってわけです。

10
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?