Amazon Linux 1 に  acme.sh (HTTP-01 challenge)で Let's Encrypt を入れる

## 更新履歴
2021年10月01日
Let's Encryptルート証明書期限切れで更新エラー（curl error code: 60)が出る場合の対処法


## 概要
* とある有償SSLサーバ証明書の有効期限がそろそろ切れるので、これを機に、これまでの有償＋手動更新から、Let's Encrypt を利用した 無償＋自動更新 で幸せになろうと思ったけど、インストールするサーバが Amazon Linux 1 でしかも古いバージョンのため、Let's Encrypt の SSLサーバ証明書をインストールするのにいろいろ試行錯誤した記録。

## 環境
* Let's Encrypt の SSLサーバ証明書を入れるサーバ
 * Amazon Linux 1（AMI release 2015.09）←古すぎ！
<pre>
$ cat /etc/system-release
Amazon Linux AMI release 2015.09
</pre> 
* Webサーバ
 * Nginx（BASIC認証でアクセス制限している）
 * ドキュメントルート /usr/share/nginx/html

* ドメイン
 * foo.staging.co.jp（今回の説明用のダミードメイン）

* IPアドレス/ポート番号制限
 * 任意のIPアドレスから http://foo.staging.co.jp, https://foo.staging.co.jp への接続は全開放

## Certbot の断念

無償のSSLサーバ証明書といえば『Let's Encrypt』ということで、公式サイトの[Getting Started](https://letsencrypt.org/getting-started/)を読むと、Certbot ACME client を推奨している。ということで、まずはサーバに Certbot のインストールを試みる。

Amazon Linux 1 は CentOS 6 のパッケージを使えるので、[Let's Encrypt 総合ポータル サイトの "CentOS 6 / RHEL 6" のインストール方法](https://free-ssl.jp/usage/install-certbot.html#CentOS6
) に書いてある通り、EPEL6 リポジトリから入れようと思ったら、certbot パッケージが無いというエラー。確かに、[EPEL 6: x86_64 リポジトリ](https://dl.fedoraproject.org/pub/epel/6/x86_64/Packages/c/
) にcertbotパッケージが無い。。

なので、[Let's Encrypt 総合ポータル サイトの "その他の UNIX 系 OS" のインストール方法](https://free-ssl.jp/usage/install-certbot.html#OtherUNIX
)に書いてある通り実行すると・・・<font color="red">FATAL: Amazon Linux support is very experimental at present...</font>

<pre>
$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto
$ ./certbot-auto
Requesting to rerun ./certbot-auto with root privileges...
FATAL: Amazon Linux support is very experimental at present...
if you would like to work on improving it, please ensure you have backups
and then run this script again with the --debug flag!
Alternatively, you can install OS dependencies yourself and run this script
again with --no-bootstrap.</pre>

「--debug」オプションを付けて再度実行してみると、次のパッケージの Install/Update をしろと、、
<pre>
$ ./certbot-auto --debug
〜略〜
Installing:
 augeas-libs
 gcc48
     replacing  libquadmath48-devel.x86_64 4.8.3-9.109.amzn1
 gcc48-c++
     replacing  libstdc++48-devel.x86_64 4.8.3-9.109.amzn1
 libffi-devel
 python27-tools

Updating:
 ca-certificates
 gcc
 openssl
 openssl-devel
 python27-devel
 python27-pip
 python27-virtualenv
 system-rpm-config
Installing for dependencies:
 libgfortran
Updating for dependencies:
 cpp48
 gcc-c++
 gcc-gfortran
 gcc48-gfortran
 libffi
 libgcc48
 libgomp
 libstdc++48
 libtool
 python27
 python27-libs
</pre>

[Let's Encrypt 総合ポータル サイト](https://free-ssl.jp/usage/install-certbot.html#OtherUNIX)に、しれっと注意書きがある。。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/c3b48d61-18b4-82de-d020-1db51c4a9ffe.png" width=120%>うーん、、 Install/Update するのは怖いよね。。

ということで、certbot は諦めて、別の ACME client を使ってみようということで、[ACME v2 Compatible Clients](https://letsencrypt.org/docs/client-options/)から[acme.sh](https://github.com/Neilpang/acme.sh) を選択。acme.sh はシェルスクリプトで書かれていて、シェルが動く環境であれば導入が楽ですぐに使えるらしい。

## acme.sh を使って Let's Encrypt SSLサーバ証明書をインストールする

#### acme.sh をインストールする

[公式サイト](https://github.com/Neilpang/acme.sh)の通りに実行、

<pre>
 # cd /root
 # curl https://get.acme.sh | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current	
                                 Dload  Upload   Total   Spent    Left  Speed	
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0

curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).	
</pre>

あれ、curl が古い。。nssをアップグレードする。

<pre>
 # yum upgrade nss
</pre>

再度、、

<pre>
 # cd /root
 # curl https://get.acme.sh | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   705    0   705    0     0   4617      0 --:--:-- --:--:-- --:--:--  4607
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  184k  100  184k    0     0   492k      0 --:--:-- --:--:-- --:--:--  492k
[Fri Jul 19 12:11:23 JST 2019] Installing from online archive.
[Fri Jul 19 12:11:23 JST 2019] Downloading https://github.com/Neilpang/acme.sh/archive/master.tar.gz
[Fri Jul 19 12:11:24 JST 2019] Extracting master.tar.gz
[Fri Jul 19 12:11:24 JST 2019] It is recommended to install socat first.
[Fri Jul 19 12:11:24 JST 2019] We use socat for standalone server if you use standalone mode.
[Fri Jul 19 12:11:24 JST 2019] If you don't use standalone mode, just ignore this warning.
[Fri Jul 19 12:11:24 JST 2019] Installing to /root/.acme.sh
[Fri Jul 19 12:11:24 JST 2019] Installed to /root/.acme.sh/acme.sh
[Fri Jul 19 12:11:24 JST 2019] Installing alias to '/root/.bashrc'
[Fri Jul 19 12:11:24 JST 2019] OK, Close and reopen your terminal to start using acme.sh
[Fri Jul 19 12:11:24 JST 2019] Installing alias to '/root/.cshrc'
[Fri Jul 19 12:11:24 JST 2019] Installing alias to '/root/.tcshrc'
[Fri Jul 19 12:11:24 JST 2019] Installing cron job
[Fri Jul 19 12:11:24 JST 2019] Good, bash is found, so change the shebang to use bash as preferred.
[Fri Jul 19 12:11:24 JST 2019] OK
[Fri Jul 19 12:11:24 JST 2019] Install success!
</pre>

入った。
crontab (/var/spool/cron/root) に次のような設定（自動更新用）が追加される。

<pre>
24 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
</pre>

#### Nginx mode で SSLサーバ証明書を発行してみる
* acme.sh のオプション
 * --issue・・・SSLサーバ証明書発行
 * --nginx・・・Nginx mode
 * -d・・・SSLサーバ証明書を発行するドメイン  

<pre>
 # cd /root/.acme.sh
 # ./acme.sh --issue --nginx -d foo.staging.co.jp
[Fri Jul 19 12:17:47 JST 2019] Create account key ok.
[Fri Jul 19 12:17:47 JST 2019] Registering account
[Fri Jul 19 12:17:48 JST 2019] Registered
[Fri Jul 19 12:17:48 JST 2019] ACCOUNT_THUMBPRINT='1W2zh17CQyWXgr3TCI5DVgl_728ut2X7oi5r4RByFwg'
[Fri Jul 19 12:17:48 JST 2019] Creating domain key
[Fri Jul 19 12:17:48 JST 2019] The domain key is here: /root/.acme.sh/foo.staging.co.jp/foo.staging.co.jp.key
[Fri Jul 19 12:17:48 JST 2019] Single domain='foo.staging.co.jp'
[Fri Jul 19 12:17:48 JST 2019] Getting domain auth token for each domain
[Fri Jul 19 12:17:49 JST 2019] Getting webroot for domain='foo.staging.co.jp'
[Fri Jul 19 12:17:49 JST 2019] Verifying: foo.staging.co.jp
[Fri Jul 19 12:17:49 JST 2019] Nginx mode for domain:foo.staging.co.jp
[Fri Jul 19 12:17:49 JST 2019] Found conf file: /etc/nginx/nginx.conf
[Fri Jul 19 12:17:49 JST 2019] Backup /etc/nginx/nginx.conf to /root/.acme.sh/foo.staging.co.jp/backup/foo.staging.co.jp.nginx.conf
[Fri Jul 19 12:17:49 JST 2019] Check the nginx conf before setting up.
[Fri Jul 19 12:17:49 JST 2019] OK, Set up nginx config file
[Fri Jul 19 12:17:49 JST 2019] nginx conf is done, let's check it again.
[Fri Jul 19 12:17:49 JST 2019] Reload nginx
[Fri Jul 19 12:17:54 JST 2019] foo.staging.co.jp:Verify error:Invalid response from http://foo.staging.co.jp/.well-known/acme-challenge/6Tb5KM3d0jhtiRJ6eoqfa68u_0BFBF1eqgdvtH7g4sU [x.x.x.x]: 401
[Fri Jul 19 12:17:54 JST 2019] Restoring from /root/.acme.sh/foo.staging.co.jp/backup/foo.staging.co.jp.nginx.conf to /etc/nginx/nginx.conf
[Fri Jul 19 12:17:54 JST 2019] Reload nginx
[Fri Jul 19 12:17:54 JST 2019] Please add '--debug' or '--log' to check more details.
[Fri Jul 19 12:17:54 JST 2019] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
</pre>

エラー出た。。
<font color="red">Verify error:Invalid response from http://foo.staging.co.jp/.well-known/acme-challenge/6Tb5KM3d0jhtiRJ6eoqfa68u_0BFBF1eqgdvtH7g4sU [x.x.x.x]: 401</font>

そもそも、何やっているの？

acme.sh は SSLサーバ証明書を発行する際に [HTTP-01 challenge](https://letsencrypt.org/docs/challenge-types/) で検証を行っている。
acme.sh --issue 実行時に、acme.sh は Nginx の "ルートディレクトリ/.well-known/acme-challenge/" ディレクトリ内にトークンファイルを一時的に作成して、acme.sh がトークンファイルの準備が出来たことを Let's Encrypt に伝えたら、Let's Encrypt は "http://foo.staging.co.jp/.well-known/acme-challenge/トークン" にアクセスを試みる。Let's Encrypt が正しい応答を得られたら検証は成功とみなされ、SSLサーバ証明書が発行される。

Nginx mode は、自動的に nginx コンフィグファイルを探して、"ルートディレクトリ/.well-known/acme-challenge/トークンファイル" へのアクセス設定を施して、検証が終わったら、設定を元に戻す。

今回は、Nginx で Basic 認証を行っているため、Let's Encrypt からのアクセスが 401 となり、検証が失敗してしまった。

ちなみに、HTTP-01 challenge アクセスは、[Let's Encryptの接続元IPアドレスは公開していない](https://letsencrypt.org/docs/faq/)ため、クライアント側は HTTP ポート80番で任意のIPアドレスからの接続を許可しておく必要がある。

#### トークンへのアクセスはBASIC認証対象外として、ノーマルモードで SSLサーバ証明書を発行してみる
まずは、HTTP-01 challenge 用のディレクトリを手動で作成する。

<pre>
 # cd /usr/share/nginx/html
 # mkdir -p .well-known/acme-challenge
 # chmod -R 755 .well-known/acme-challenge
 # chown -R nginx:nginx /usr/share/nginx/html/.well-known/acme-challenge
</pre>

"http://foo.staging.co.jp/.well-known/acme-challenge/トークン" へのアクセスは BASIC認証対象外とする
/etc/nginx/nginx.conf 設定例

<pre>
〜
  location /.well-known  {
    satisfy any;
    allow   all;
  }
  location /.well-known/acme-challenge  {
    satisfy any;
    allow   all;
  }
〜
</pre>

nginx 再起動

<pre>
 # service nginx configtest
 # service nginx restart
</pre>

ノーマルモードでSSLサーバ証明書を発行する

* acme.sh のオプション
 * -w・・・ドキュメントルート

<pre>
 # cd /root/.acme.sh
 # ./acme.sh --issue -d foo.staging.co.jp -w /usr/share/nginx/html
[Fri Jul 26 12:48:13 JST 2019] Create account key ok.
[Fri Jul 26 12:48:13 JST 2019] Registering account
[Fri Jul 26 12:48:14 JST 2019] Registered
[Fri Jul 26 12:48:14 JST 2019] ACCOUNT_THUMBPRINT='6k1I3oh7R3iEIrnWIEWMsRt0rmUzf4T2CXgn9TaXvoE'
[Fri Jul 26 12:48:14 JST 2019] Creating domain key
[Fri Jul 26 12:48:14 JST 2019] The domain key is here: /root/.acme.sh/foo.staging.co.jp/foo.staging.co.jp.key
[Fri Jul 26 12:48:14 JST 2019] Single domain='foo.staging.co.jp'
[Fri Jul 26 12:48:14 JST 2019] Getting domain auth token for each domain
[Fri Jul 26 12:48:15 JST 2019] Getting webroot for domain='foo.staging.co.jp'
[Fri Jul 26 12:48:15 JST 2019] Verifying: foo.staging.co.jp
[Fri Jul 26 12:48:18 JST 2019] Success
[Fri Jul 26 12:48:18 JST 2019] Verify finished, start to sign.
[Fri Jul 26 12:48:18 JST 2019] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/62039946/782487887
[Fri Jul 26 12:48:20 JST 2019] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/03d9bc51c44775de73e376f19b890cc6f5bf
[Fri Jul 26 12:48:20 JST 2019] Cert success.
-----BEGIN CERTIFICATE-----
MIIFcjCCBFqgAwIBAgISA9m8UcRHdd5z43bxm4kMxvW/MA0GCSqGSIb3DQEBCwUA
〜略〜
5Kh5eZhP
-----END CERTIFICATE-----
[Fri Jul 26 12:48:20 JST 2019] Your cert is in  /root/.acme.sh/foo.staging.co.jp/foo.staging.co.jp.cer
[Fri Jul 26 12:48:20 JST 2019] Your cert key is in  /root/.acme.sh/foo.staging.co.jp/foo.staging.co.jp.key
[Fri Jul 26 12:48:20 JST 2019] The intermediate CA cert is in  /root/.acme.sh/foo.staging.co.jp/ca.cer
[Fri Jul 26 12:48:20 JST 2019] And the full chain certs is there:  /root/.acme.sh/foo.staging.co.jp/fullchain.cer
</pre>

おぉ、発行された！

発行されたSSLサーバ証明書を確認する。

<pre>
 # ./acme.sh --list
Main_Domain        KeyLength  SAN_Domains  Created                       Renew
foo.staging.co.jp  ""         no           Fri Jul 26 03:48:20 UTC 2019  Tue Sep 24 03:48:20 UTC 2019
</pre>

#### 発行されたSSLサーバ証明書を Nginx にインストールする
cert keyファイルと、full chain certs ファイルをを置くディレクトリを作成する。

<pre>
 # mkdir -p /etc/nginx/certs/letsencrypt/foo.staging.co.jp
</pre>

/etc/nginx/certs/letsencrypt/foo.staging.co.jp ディレクトリに、foo.staging.co.jp.key ファイルと、fullchain.cer ファイルをインストール (--install-cert) する。

<pre>
 # cd /root/.acme.sh/
 # ./acme.sh --install-cert -d foo.staging.co.jp --key-file /etc/nginx/certs/letsencrypt/foo.staging.co.jp/foo.staging.co.jp.key --fullchain-file /etc/nginx/certs/letsencrypt/foo.staging.co.jp/fullchain.cer
</pre>

nginx コンフィグファイルで証明書のパスを設定する
/etc/nginx/conf.d/ssl.conf 設定例

<pre>
〜
  ssl_certificate     /etc/nginx/certs/letsencrypt/foo.staging.co.jp/fullchain.cer;
  ssl_certificate_key /etc/nginx/certs/letsencrypt/foo.staging.co.jp/foo.staging.co.jp.key;
〜
</pre>

nginx 再起動

<pre>
 # service nginx configtest	
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

 # service nginx restart
Stopping nginx:     [  OK  ]
Starting nginx:     [  OK  ]
</pre>

ブラウザから https://foo.staging.co.jp へアクセスして、SSLサーバ証明書を確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148868/6405b5f4-3287-46d2-7192-e3c28464bea9.png)

インストール出来た。

#### 自動更新設定
自動更新では、SSLサーバ証明書発行後に、"--install-cert でインストールしてnginxをリロード" させる。
そのジョブを実行する。

<pre>
 # /root/.acme.sh
 # ./acme.sh --install-cert -d foo.staging.co.jp --key-file /etc/nginx/certs/letsencrypt/foo.staging.co.jp/foo.staging.co.jp.key --fullchain-file /etc/nginx/certs/letsencrypt/foo.staging.co.jp/fullchain.cer --reloadcmd "service nginx force-reload"
[Fri Jul 19 17:18:49 JST 2019] Installing key to:/etc/nginx/certs/letsencrypt/foo.staging.co.jp/foo.staging.co.jp.key
[Fri Jul 19 17:18:49 JST 2019] Installing full chain to:/etc/nginx/certs/letsencrypt/foo.staging.co.jp/fullchain.cer
[Fri Jul 19 17:18:49 JST 2019] Run reload cmd: service nginx force-reload
Reloading nginx:          [  OK  ]
</pre>

これで、cronによる自動更新ジョブで、SSLサーバ証明書発行後に、"--install-cert でインストールしてnginxをリロード" するようになる。

acme.sh インストール時に crontab に自動更新のコマンドが追加されているので、
crontab (/var/spool/cron/root) 

<pre>
24 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
</pre>

これを使って、手動で強制的 (--force) に更新処理を実行してみる。

<pre>
 # "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --force
[Fri Jul 26 13:24:13 JST 2019] ===Starting cron===
[Fri Jul 26 13:24:13 JST 2019] Renew: 'foo.staging.co.jp'
[Fri Jul 26 13:24:14 JST 2019] Single domain='foo.staging.co.jp'
[Fri Jul 26 13:24:14 JST 2019] Getting domain auth token for each domain
[Fri Jul 26 13:24:15 JST 2019] Getting webroot for domain='foo.staging.co.jp'
[Fri Jul 26 13:24:15 JST 2019] foo.staging.co.jp is already verified, skip http-01.
[Fri Jul 26 13:24:15 JST 2019] Verify finished, start to sign.
[Fri Jul 26 13:24:15 JST 2019] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/62039946/782634405
[Fri Jul 26 13:24:16 JST 2019] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/037597c36c53830c77a547a4c949f57d0974
[Fri Jul 26 13:24:17 JST 2019] Cert success.
-----BEGIN CERTIFICATE-----
MIIFcjCCBFqgAwIBAgISA3WXw2xTgwx3pUekyUn1fQl0MA0GCSqGSIb3DQEBCwUA
〜略〜
7AFa7o7V
-----END CERTIFICATE-----
[Fri Jul 26 13:24:17 JST 2019] Your cert is in  /root/.acme.sh/foo.staging.co.jp/foo.staging.co.jp.cer
[Fri Jul 26 13:24:17 JST 2019] Your cert key is in  /root/.acme.sh/foo.staging.co.jp/foo.staging.co.jp.key
[Fri Jul 26 13:24:17 JST 2019] The intermediate CA cert is in  /root/.acme.sh/foo.staging.co.jp/ca.cer
[Fri Jul 26 13:24:17 JST 2019] And the full chain certs is there:  /root/.acme.sh/foo.staging.co.jp/fullchain.cer
[Fri Jul 26 13:24:17 JST 2019] Installing key to:/etc/nginx/certs/letsencrypt/foo.staging.co.jp/foo.staging.co.jp.key
[Fri Jul 26 13:24:17 JST 2019] Installing full chain to:/etc/nginx/certs/letsencrypt/fullchain.pem
[Fri Jul 26 13:24:17 JST 2019] Installing full chain to:/etc/nginx/certs/letsencrypt/foo.staging.co.jp/fullchain.cer
Reloading nginx:                                           [  OK  ]
[Fri Jul 26 13:24:17 JST 2019] Reload success
[Fri Jul 26 13:24:17 JST 2019] ===End cron===
</pre>

SSLサーバ証明書発行して、インストールして、nginx 再起動してる。
ブラウザからSSLサーバ証明書の有効期限を確認する。
有効期限が新しく発行したSSLサーバ証明書になっていれば、成功。

ちなみに、Let's Encrypt の SSLサーバ証明書の有効期限は90日だけど、
acme.sh は cronで毎日更新処理を試行して、SSLサーバ証明書発行から60日経過している場合に、更新処理を実行する。


#### 補足
バージョン管理している場合は、"ルートディレクトリ/.well-known/acme-challenge/"の追加を忘れずに。
デプロイしたら"ルートディレクトリ/.well-known/acme-challenge/"ディレクトリが消えないように。

#### 運用時に発生した問題
##### 1. 「It seems the CA server is busy now, let's wait and retry. Sleeping 1 seconds.」
いざ、更新時に発生したエラー。

<pre>
[2020年  4月 22日 水曜日 00:16:02 JST] ===Starting cron===
[2020年  4月 22日 水曜日 00:16:02 JST] Renew: 'ドメイン名'
[2020年  4月 22日 水曜日 00:16:03 JST] Single domain='ドメイン名'
[2020年  4月 22日 水曜日 00:16:03 JST] Getting domain auth token for each domain
[2020年  4月 22日 水曜日 00:21:04 JST] It seems the CA server is busy now, let's wait and retry. Sleeping 1 seconds.
[2020年  4月 22日 水曜日 00:26:05 JST] It seems the CA server is busy now, let's wait and retry. Sleeping 1 seconds.
[2020年  4月 22日 水曜日 00:31:07 JST] It seems the CA server is busy now, let's wait and retry. Sleeping 1 seconds.
[2020年  4月 22日 水曜日 00:36:08 JST] It seems the CA server is busy now, let's wait and retry. Sleeping 1 seconds.
〜
[2020年  4月 22日 水曜日 01:56:36 JST] Create new order error. Le_OrderFinalize not found. {
  "type": "urn:ietf:params:acme:error:badNonce",
  "detail": "JWS has an invalid anti-replay nonce: \"0002dbS1IRfgFLnk4wAEVzwHbe7-BRBS5HFBRDVqyho6Ri4\"",
  "status": 400
}
</pre>

acme.sh をアップグレードしたら、正常に更新処理が走った。

```
# acme.sh --upgrade
```

手動更新

```
# "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"
```

crontab に upgrade を追加

```
6 0 * * * cd /root/.acme.sh && ./acme.sh --upgrade
```

## Let's Encryptルート証明書期限切れで更新エラー（curl error code: 60)が出る場合の対処法
* 2021年09年30日に、Let's Encryptルート証明書の有効期限が切れた。<br />【参考】[2021年にLet’s Encryptのルート証明書が変更！影響や備えておくべきこととは？](https://ssl.sakura.ad.jp/column/letsencrypt-root-certificate/)


* 古いOS（OpenSSL）の場合、そのサーバ内にあるCA証明書ファイルの内容も古い。<br />新しいルート証明書に対応していない場合、証明書更新処理で次のような CURL エラーが発生する。
https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 60

```
# "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"
[Thu Sep 30 23:22:41 UTC 2021] ===Starting cron===
[Thu Sep 30 23:22:41 UTC 2021] Renew: '***.***.***.jp'
[Thu Sep 30 23:23:00 UTC 2021] Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: 60
[Thu Sep 30 23:23:02 UTC 2021] Can not init api for: https://acme-v02.api.letsencrypt.org/directory.
[Thu Sep 30 23:23:02 UTC 2021] Sleep 10 and retry.
```
* 対処法として、新しいCA証明書ファイルに置き換える方法がある
 * 最新のCA証明書ファイルをダウンロードして、対象サーバの /etc/pki/tls/certs/ ディレクトリ配下に置く<br />https://curl.haxx.se/ca/cacert.pem
 * 対象サーバにSSHログインして、現存の ca-bundle.crt をバックアップとり、cacert.pem を ca-bundle.crt にリネームし、パーミッションを変更する。

```
# cd /etc/pki/tls/certs/
# mv ca-bundle.crt ca-bundle.crt_20211001
# mv cacert.pem ca-bundle.crt
# chmod 644 ca-bundle.crt
```

* 手動で強制自動更新を実行して動作確認

```
# "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --force
```