LB(ALB)配下のec2からLetsEncrypt証明書を取得しようとしたら、別ホストが認証リクエストを受けて困った


やりたかったこと

  • AWS EC2(amazonLinux x 2) + ロードバランサ(ALB) という冗長構成のwebサーバー
  • うち片方にLetsEncryptのクライアント(certbot)を入れ、運用するドメインのSSL証明書を取得(http-01認証)
  • 取得した証明書をaws-cliでIAMにアップロード & ALBに適用

具体的には下記事の要領に沿ってやりました。
AWS Let's Encrypt 証明書の自動発行とALBへの自動登録

及び、その元記事であるこちら。
Let's Encrypt 証明書の自動発行とELB自動登録を行ったログ

途中、「certbotによる証明書取得のドメイン認証(http認証)のレスポンスを冗長構成のもう1台のサーバーが受けてしまって認証がコケる」という点でハマったので、当記事はその部分の補足です。

今回は対象ドメインのDNS権限がなかったので苦労しましたが、もしDNS権限があれば、認証方式をDNS-01にすれば以下の手順をしなくていいはず。さらにそれがRoute53なら素直にACM使えばいいんでないかと。

やったこと

の前に、元記事でやってる流れを整理するとこう。

  1. ec2にcertbotをインストール
  2. certbot-autoコマンドでLetsEncrypt証明書取得
  3. 取得した証明書をaws-cliコマンドでIAMに登録
  4. 登録した取得した証明書をaws-cliコマンドでALBのリスナーに登録

このうち、2-4の手順をシェルスクリプト化し、取得後の更新も自動化できるようにしてるんですが、そのスクリプトの2(certbot-autoコマンド)のところで、

The server could not connect to the client to verify the domain

とドメインのhttp認証がコケる。webroot認証は、ec2(以下web01)のcertbotが作ったトークンファイルを別の認証サーバがHTTPでアクセスして行いますが、この時の認証リクエストをcertbotを入れてない方のec2(以下web02)が受けてしまうと404になるわけです。

なんで、スクリプトを流す前に、web02(今回はnginx)の該当ドメインのvirtualhostのconfで、認証リクエストをweb01にリダイレクトする設定を追加。

nginx.conf
server {
    listen 80;
    server_name 証明書取得対象のドメイン名;

    ...

    rewrite ^/.well-known/(.*)$ http://web01にあてた別ドメイン名/.well-known/$1 permanent;
}

LB配下の各ホストに個別ドメインなんてあててないので、当初rewrite先をIPで指定してたんですが、それはそれで

Only domain names are supported, not IP addresses

と怒られます。DNS操作できる適当なドメインのサブドメインをRoute53でweb01にあててやることで無事スクリプトが走って、認証をクリアしました。