Let's Encryptのワイルドカード証明書を導入する

AlmaLinux OS 8上にLet's encryptのワイルドカード証明書を導入するまでの備忘録。

#Certbotのインストール
まずは証明書を取得するためのプログラムであるCertbotをインストールする。
epelリポジトリからのインストールとなるので、事前にepelを使えるようにしておく必要がある(省略)。

```Bash
dnf -y install certbot
```

一応バージョンを確認。

```Bash
certbot --version
```

現時点(2021/12/26)での最新版は1.22.0で、今回インストールされたものも1.22.0。

#CloudflareのDNSを利用したインストール(自動更新可能)
無料で利用可能なCloudflareのDNSを利用することで自動更新が可能となる。

##プラグインのインストール
Certbotは利用可能なDNSサービスごとにプラグインが用意されているが別パッケージになるので、Cloudflare用プラグインをインストールする。

```Bash
dnf install python3-certbot-dns-cloudflare
```

##Cloudflareのアカウント作成
[アカウント作成ページ](https://dash.cloudflare.com/sign-up)でメールアドレスとパスワードを入力し、「Create Account」をクリック。

メールアドレスの確認メール(タイトルが[Cloudflare]: Please verify your email addressのようなもの)がアカウント作成時に登録したメールアドレス宛に届くので、本文中のURLにアクセスすることでアカウント作成が完了する。

##対象ドメインのDNSサーバをCloudflareに変更
###CloudflareのDNS設定

[CloudflareのDashboard](https://dash.cloudflare.com/)から「Add Site」をクリック。

ドメイン名を入力して「Add Site」をクリック。

Select PlanでFreeを選択して「Continue」をクリック。

Review your DNS recordsで現在のDNSレコードが表示されるので、間違いがないかを確認。
環境によっては全てのレコードが得られない可能性があるので、**見直し必須**。
確認・編集が済んだら「Continue」をクリック。

Change your nameserversで表示されるCloudflare's nameserversをメモしてから「Done, check nameservers」をクリック。

###ドメイン管理サービスでのネームサーバ変更

ドメイン管理サービス(お名前.comなど)でメモしたCloudflare's nameserversにネームサーバを変更。

設定にもよるが数日かかる場合もあるので、気長に待つ。

Cloudflare側でネームサーバの変更が確認できると、[Dashboard](https://dash.cloudflare.com/)で該当ドメインのステータスがActiveになる。

##API Tokenの取得と保存

[CloudflareのAPI Tokens](https://dash.cloudflare.com/profile/api-tokens)で、「Create Token」をクリック。

:::note warn
API Keysではないことに注意。
API KeyではCloudflareの全てのサービスが操作可能になってしまうのでセキュリティ的によくない。
:::

Edit zone DNSの「Use template」をクリック。

Zone ResourcesをInclude:Specific zone:[証明書を取得するドメイン名]に変更し、「Continue to summary」をクリック。
PermissionsはZone:DNS:Editとなっているはずなので、これはいじらない。

確認画面で該当ドメインのDNS:Edit権限があることを確認し、「Create Token」をクリック。

API Tokenが表示されるのでメモ。

証明書発行時にAPI Tokenが記述されたファイルが必要となるので、そのファイルを作成。
ここでは /etc/letsencrypt/cloudflare.ini に以下の様に記述する。

```Bash:/etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = [API Tokenの値]
```

保存ファイルの権限が他ユーザからも読めるようになっているとCertbot実行時に警告が出るため権限を変更する。

```Bash
chmod 600 /etc/letsencrypt/cloudflare.ini
```

##証明書の発行テスト
API Tokenが正しく設定されているかも含めて念のためテストする。

```Bash
certbot certonly \
--dry-run \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-m ssl@example.com \
-d *.example.com
```

問題がなければ以下の様に表示される。

```Bash
The dry run was successful.
```

##証明書の発行
発行テストコマンドからdry-runオプションを除けば、実際に発行される。

```Bash
certbot certonly \
--dry-run \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-m ssl@example.com \
-d *.example.com
```

###規約の同意
同意するにはYを入力。
省略するにはコマンドオプションに--agree-tos(同意)を追加する。

```Bash
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:
```

###メールマガジンの購読
購読するにはYを入力、不要ならNを入力。
省略するにはコマンドオプションに--eff-email(購読)/--noeff-email(不要)を追加する。

```Bash
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:
```

###発行完了
問題がなければ発行される。
以下の場合、サーバ証明書は /etc/letsencrypt/live/example.com/fullchain.pem に、
秘密鍵は /etc/letsencrypt/live/example.com/privkey.pem に保存され、
有効期限が 2022-03-26 となる。

```Bash
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2022-03-26.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
```

##更新
設定は保存されているので、以下のコマンドだけで更新が可能。

```Bash
certbot renew
```

##systemdによる自動更新の設定
dnfでインストールすると自動更新用のtimerが含まれているのでこれを有効にする。

```Bash
systemctl enable --now certbot-renew.timer
```

スケジュールされていることを確認。

```Bash
systemctl list-timers
```

httpdを利用する際は証明書の更新後に再起動しないと有効にならないため、/etc/sysconfig/certbot を編集する必要がある。

例：Apache

```Bash:変更前の/etc/sysconfig/certbot
POST_HOOK=""
```

```Bash:変更後の/etc/sysconfig/certbot
POST_HOOK="--post-hook 'systemctl restart httpd'"
```

#マニュアルインストール(自動更新不可)
こちらの方法では利用しているDNSサービスに依存せずにワイルドカード証明書が発行できるが、更新の際にTXTレコードを毎回書き換える必要があるため、自動更新ができない。

```Bash
certbot certonly --manual \
--preferred-challenges dns-01 \
-m ssl@example.com \
-d *.example.com
```

certbotコマンド以降はCloudflareのDNSを利用したインストールと基本的に同じだが、以下が追加になる。

###DNS TXTレコード記述内容の表示
[DNS TXTレコードに記述する値]で表示された値を表示されているサブドメインのTXTレコードに設定する。
設定が反映した頃を見計らってEnterキーを押す。


```Bash
Please deploy a DNS TXT record under the name:

_acme-challenge.example.com

with the following value:

[DNS TXTレコードに記述する値]

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.example.com.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
```

###発行完了
発行は完了するが書いてあるとおり、自動更新はできないので、発行時と同様のコマンドを有効期限前に実行する必要がある。

```Bash
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2022-03-26.
These files will be updated when the certificate renews.

NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
```