certbot renew で Connection refused になってしまったので調べてみた。

Let's Encryptで証明書更新をしたのですが、Connection refused となってしまったので、原因を調べてみました。以下がエラーになったときのログです。ドメイン、IPは伏せています。


# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/web.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for web.example.com

Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
  Domain: web.example.com
  Type:   connection
  Detail: xxx.xxx.xxx.xxx: Fetching https://web.example.com/.well-known/acme-challenge/9109eVHrvSxOWX3e1EM94RDM42AGDBEk6pamz0Rm6qE: Connection refused

Hint: The Certificate Authority failed to download the temporary challenge files created by Certbot. Ensure that the listed domains serve their content from the provided --webroot-path/-w and that files created there can be downloaded from the internet.

Failed to renew certificate web.example.com with error: Some challenges have failed.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
All simulated renewals failed. The following certificates could not be renewed:
  /etc/letsencrypt/live/web.example.com/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.

certbotが https://web.example.com/.well-known 配下に一時ファイルを作成していて、それをLet's Encryptの認証局がダウンロードするようなのだけど、それができないらしい。certbot renew をして別画面を立ち上げて .well-known フォルダが作成されるかを確認したところ、フォルダは作成されているのはわかりました。ということは、外部からは .well-known フォルダがわかっていないらしい。

/var/log/letsencrypt/letsencrypt.log が出ているので、そちらを見てみたらポート80とポート443とではIPアドレスの名前解決方法が違うようです。ポート80ではIPv4を使い、ポート443ではIPv6を使っていることがわかりました。以下が、letsencrypt.log の抜粋です。


{
  "url": "http://web.example.com/.well-known/acme-challenge/9109eVHrvSxOWX3e1EM94RDM42AGDBEk6pamz0Rm6qE",
  "hostname": "web.example.com",
  "port": "80",
  "addressesResolved": [
    "xxx.xxx.xxx.xxx",
    "2406:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:1291"
   ],
   "addressUsed": "xxx.xxx.xxx.xxx"
},
{
  "url": "https://web.example.com/.well-known/acme-challenge/9109eVHrvSxOWX3e1EM94RDM42AGDBEk6pamz0Rm6qE",
  "hostname": "web.example.com",
  "port": "443",
  "addressesResolved": [
    "xxx.xxx.xxx.xxx",
    "2406:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:1291"
  ],
  "addressUsed": "2406:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:1291"
}

DNSの名前解決でIPv6を登録したのですが、どうやらそれが原因だったようです。なので、DNSのIPv6の名前解決を削除して改めて certbot renew をしてみました。


# certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/web.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Simulating renewal of an existing certificate for web.example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded: 
  /etc/letsencrypt/live/web.example.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

成功しました!

どうやらIPv6の名前解決に原因があったようでした。

Amazon Linux 2023 にcertbotを入れてWEBサーバーのTLS化をしてみた。

Amazon Linux 2023 で稼働しているWEBサイトをTLS化します。サーバー証明書が必要なので無料で取得が出来る Let's Encrypt のサーバー証明書を取得します。Let's Encrypt でサーバー証明書を取得するにはcertbotアプリをインストールする必要があります。

Amazon Linux 2023 のリポジトリ(/etc/yum.repos.d/amazonlinux.repo)にはcertbotが含まれているので、すぐにインストールができます。インストールはrootユーザーで行います。

# dnf install certbot

インストールが完了したらバージョンを確認してみます。

# certbot --version
certbot 2.6.0

2024年6月時点で ver.2.6.0 のようです。

事前準備としてポート80と443を開けておきます。以下はLightsailのファイアウォールの設定画面の例です。

certbotを使ってサーバー証明書を取得します。以下のコマンドを入力します。

# certbot certonly --webroot -w /var/www/html/example -d www.example.com

引数の意味ですが、以下です。

certonly
サーバー証明書を取得する。ApacheやNginxなどのWEBサーバーの設定ファイルの書き換えはしない。

--webroot -w パス指定
認証のために Let's Encrypt 側からアクセスをしてきて、ここに一時的に作成されたファイルを(Let's Encrypt 側が)確認する。トップページ(index.htmlを配置する場所)にすると良いと思われる。

-d ドメイン名
サーバー証明書を取得するドメイン名を指定する。

コマンドを実行したときのログのイメージです。途中で質問をされます。

① 連絡先のEメールアドレスを入力します。証明書の期限切れが近づくとメールが届きます。

② 同意するかどうかの確認です。ここは同意(Y)を入力します。

③ Electronic Frontier Foundation にEメールアドレスを公開するかどうか確認をされます。公開したくなければ(N)を入力します。

Successfully received certificate.と表示されていればサーバー証明書が発行されました。④の fullchain.pem がサーバー証明書です。⑤の privkey.pem が秘密鍵です。なお秘密鍵はrootでしかアクセスできません。④、⑤のファイルはWEBサーバーのTLS化の設定に必要なものです。

WEBサーバー側の設定をします。Nginxの例です。NginxでTLS化に必要な設定は以下です。

① listen ディレクティブで443ポートを指定して、sslパラメータを付与してTLSを有効にします。

② server_name ディレクティブでドメイン名を指定します。

③ ssl_certificate ディレクティブでサーバー証明書を指定します。

④ ssl_certificate_key ディレクティブで秘密鍵を指定します。

nginx -t コマンドでコンフィグの確認をします。

# nginx -t

問題がなければnginxを再起動します。

# systemctl restart nginx

「https://www.example.com」でウェブサイトにアクセスしてブラウザに鍵のマークがついていればTLSで保護されています。