Edit
Let's Encrypt とは

無料でSSLのサーバー証明書が取得できるサービス。多くのブラウザが対応しており、すでに全世界の50%前後がここの証明書を使っているらしい。

Edit
インストール

最初に証明書の自動取得・更新のためのスクリプトをダウンロードする。

# wget https://dl.eff.org/certbot-auto
# chmod a+x certbot-auto
# mv certbot-auto /usr/local/bin

Edit
Amazon Linux 2 の場合

上記では、OSの判定ができないのでcertbot-auto を下記のように修正する。

オリジナル(約853行目あたり)

else
   Bootstrap() {

修正後

elif [ -f /etc/os-release ] && grep -q "Amazon Linux 2" /etc/os-release ; then
   Bootstrap() {
      ExperimentalBootstrap "Amazon Linux" BootstrapRpmCommon
   }
   BOOTSTRAP_VERSION="BootstrapRpmCommon $BOOTSTRAP_RPM_COMMON_VERSION"
else
   Bootstrap() {

要するに else の上に新しい Amazon Linux 2用の判定を追加する。

Edit
最初の証明書取得

最初の証明書の取得にはWEBサーバーに合わせた方法もあるが、一番簡単な証明書だけを撮ってくる方法を紹介する。証明書にとってドメインを所有しているかのチェックに、実際のページに特殊な確認ページを埋め込んで、そのドメインを取得している証明を得るため、WEBサーバーがポート80 で開いて可動しており、そのフォルダを指定する必要がある。ここでは /var/www/html にあたる。(プロンプトで指定する事も可能)

# certbot-auto certonly -w /var/www/html -d www.mydomain.com -m info@mydomain.com

ちなみに、Let'sEncryptというサイトで提供されている、ACME(Automatic Certificate Management Environment)用のAPIと通信して、自動で指定されたドメインの証明書を取得している。よってドメインさえ所有していればユーザー登録などは必要無く証明書が取得できる。(いわゆる昔の証明書発行時の組織名やら部門名やら国コードなど、なにも設定する必要がない)

※ただし Amazon Linux 2の場合には、オプションに --debug をつける。

Edit
ワイルドカードによるサーバー証明書の最初の取得の場合

ワイルドカードの場合はドメイン全体の権利を証明するため、ドメインを監理しているDNSサーバーに、TXTレコードを追加することでドメインの保有チェックを行う。また定期更新時には再度 txt レコードの更新が必要となるため、DNSサーバー用の更新スクリプトが必要となる。

# certbot-auto certonly --manual --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory -d mydomain.com -d *.mydomain.com -m info@mydomain.com --debug

ここでは、mydomain.com と、*.mydomain.com の2つ表記のドメイン証明書で作成しようとしている。このコマンドを実行後数個の質疑に答えた後、表示された 秘密文字を、dnsサーバーの txt レコードとしてDNSサーバーに登録し反映を待つ。

TXT _acme-challenge <表示された秘密文字>

or

_acme-challenge.yourdomain.co.jp. 300 IN TXT "表示された秘密文字"

DNSサーバーの更新状況の確認には

# dig -t txt _acme-challenge.mydomain.com

or

# nslookup -q=txt _acme-challenge.mydomain.com.

でTXTレコードの反映状況を調べられる。

Edit
AWS Route53を利用した証明書更新

route53 DNS サーバー向けの証明書自動更新には、DNSのtxtレコードを更新するため、証明書の最初の作成時から準備を行う。

Edit
ポリシーを作成する。

IAMのポリシー作成から以下のJSONの内容のポリシーを作成する。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:ListHostedZones",
                "route53:GetChange"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "route53:ChangeResourceRecordSets"
            ],
            "Resource": "*"
        }
    ]
}

Edit
AWSでIAMを使ってユーザーを作成する。

IAMで「プログラムによるアクセス」でユーザーを作成。ユーザーの「アクセス権限を設定」では上記で作成したポリシーをアタッチする。作成した「アクセスキーID」と「シークレットアクセスキー」はメモしておく。

Edit
certbotの route53 プラグインをインストール

# pip install certbot-dns-route53

Edit
aws cli に新しい profileを登録する。

# aws configure --profile route53_certbot

ここで先ほど作った「アクセスキーID」と「シークレットアクセスキー」を aws cli に登録する。

Edit
最初の証明書を作成する。

# vi wildcard_certificate.sh
#!/bin/sh
export AWS_DEFAULT_PROFILE=route53_certbot 
certbot certonly \
--dns-route53 \
--preferred-challenges dns-01 \
--agree-tos \
--manual-public-ip-logging-ok \
--server https://acme-v02.api.letsencrypt.org/directory \
-d mydomain.com \
-d *.mydomain.com \
-m info@mydomain.com

この作成したスクリプトを実行してエラーが無ければ、サイトの証明がされたかを確認。

Edit
cron登録する

# vi certbot_renew.sh
  export AWS_DEFAULT_PROFILE=route53_certbot 
  certbot renew --post-hook 'systemctl reload nginx'
# chmod +x certbot_renew.sh

このファイルを crontab で1日1日程度呼び出すようにする。 ※ちなみに複数のドメインがあってもこの1個だけですべて更新される。

Edit
WEBサーバーへの設定

無事に証明書が取得されると以下のフォルダにデータが格納される。

/etc/letsencrypt/live/ドメイン名/cert.pem         <- 証明書本体
/etc/letsencrypt/live/ドメイン名/privkey.pem      <- 秘密鍵
/etc/letsencrypt/live/ドメイン名/fullchain.pem    <- 結合された中間証明書

あとは、WEBサーバーのSSL指定の中でこのファイルを参照すればよい。

Edit
自動更新の登録

基本的に、Let's Encrypt で提供される証明書は3ヶ月で切れるため、サーバーに自動更新のプログラムを定期実行させるタスクを登録する。

# vi /etc/crontab
....
0  1  *  *  *  root     /usr/local/bin/certbot-auto renew --post-hook "service httpd restart"
.....

※この設定は毎日深夜一時に更新する。公式では1日2回ぐらいと言っているが、サーバー負荷もあるので、ここでは1日1回を例に。