cloudflare DNSとcertbotでローカル用のワイルドカード証明書を取得する(自分向け完全版)

今や、総SSL/TLSと呼ばれる時代になり(ほんとか？)、ローカルで何か動かすにも証明書が必要になり、それも自己証明書では動かない事も多々あり、~~不便な~~セキュアな時代になりました。

特にDocker周りでもHTTPSとかTLSがデフォルトで要求されるので、回避しようとしても回避できない事態が発生しています。

そこで、「ローカルで使えるワイルドカードの証明書があればいいんだよ。」と作ってみた話になります。

あちこちに解説がありますが、certbotのコマンドが微妙に違っていたり、APIトークンの発行方法が違っていたりしたので、自分向けの完全版として記録しておきたいと思います。

# 1. はじめに

以下のような順番で作業をします。

1. Cloudflareのアカウントを作ります。Freeで構いません
1. Cloudflareでドメインを取得します。お金が掛かります
1. Linuxサーバーを立ち上げます。WSL2とかで構いません
1. Linuxサーバーにcertbotとcertbot-dns-cloudflareプラグインをインストールします
1. CloudflareでAPIトークンを発行します
1. APIトークンをiniファイルに保存します
1. certbotコマンドで証明書を発行します

本作業では、ACME DNS Challengeという方法でドメインの認証を行います。
一般的にLet's Encryptはドメインの所有者を確認するのにTLS証明書を利用するサーバーへ接続し、HTTP接続できたらTLS証明書を発行するという流れになりますが、プライベートにあるサーバーはHTTP接続できません。
そこで、DNSサーバーのTXTレコードにチャレンジ用の文字列を書き込むことでドメインの認証を行います。

certbotには、上記のドメインの認証を行う為にDNSサーバー(のサービス)を書き換えるための機構が備わっています。しかし、DNSサーバーのサービスを様々なプロバイダーが提供しており、接続方法や認証方法、書き換える方法が違うのでプラグインという形でそれぞれのプロバイダーにあったプラグインをインストールする必要があります。

Certbot Instructions \| Certbot 
https://certbot.eff.org/instructions?ws=nginx&os=snap&tab=wildcard

# 2. Cloudflareのアカウントを作ります

作るのは簡単です。以下のURLからメールアドレスとパスワードを入れて「サインナップ」をクリックするとアカウントが作製されます。Freeを選択すれば無料で開始できます。

https://dash.cloudflare.com/sign-up

プランは、Freeを選択しておきましょう。

# 3. Cloudflareでドメインを取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/dc5de505-4478-f5ef-4d67-d6629ec9da35.png)

「ドメインの管理」＞「ドメインの登録」で取得したいドメイン名を入れてドメインを購入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/b6b2989e-6db3-8368-9dc1-a5a4605aa86c.png)

クレカ払いかPaypalで支払いできます。継続にするかどうかはお任せします。
トップドメインがusだと6.5ドルぐらいなのでそれで十分です。

# 4. Linuxサーバーを立ち上げます

certbotを動かす為にLinuxが必要です。Windowsで動かすWSL2とかで構いません。
今時だとUbuntuとかかなと思います。

# 5. Linuxサーバーにcertbotとcertbot-dns-cloudflareプラグインをインストールします

以下の記事に沿って、certbotとプラグインをインストールします。
https://certbot.eff.org/instructions?ws=nginx&os=snap&tab=wildcard

Webサーバーは正直なんでもいいので、Apacheとかnginxを選択しておけばOKです。

## 5.1 certbotをインストール

以下のコマンド(Ubuntu向け)でインストールします。

```
sudo snap install --classic certbot
```

記事では、certbotを/usr/bin/certbotにシンボリックリンクしています。
必要？って思いますが、cronで実行したりするときにパスが違ったりすると動かないかもしれないので、実行しておきましょう。

```
sudo ln -s /snap/bin/certbot /usr/bin/certbot
```

あと、よく分からないのですが、snapでインストールすると書き込む領域が限られる(からかどうかは分からないが)ので、以下のコマンドを実行しておきます。rootでプラグイン実行を許可する？みたいなオプションでしょうか。

```
sudo snap set certbot trust-plugin-with-root=ok
```

## 5.2 certbot-dns-cloudflareプラグインをインストール

CloudflareのDNSを書き換える用のプラグインをインストールします。

```
sudo snap install certbot-dns-cloudflare
```

# 6. CloudflareでAPIトークンを発行します

ものの記事には、「Global API Keyを使う」とか書かれていますが、Global APIキーはあまりにも権力が強大すぎるので漏れたときの影響が甚大です。そうではなくて、DNSの書き換えだけに特化したAPIキーを作成して、これを利用するようにしましょう。

APIトークンの発行画面は、プロフィールページの「APIトークン」から発行できます。

API トークン \| Cloudflare 
https://dash.cloudflare.com/profile/api-tokens

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/a6b66ad5-e700-8271-9b36-7586c20a7a39.png)

右の「トークンを作成する」ボタンを押します。

下記の「ゾーンDNSを書き換える」の「テンプレートを使用する」が楽なので、これをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/c85eda9c-6f05-d1b3-d3e5-99c95ffab186.png)

「アクセス許可」は「ゾーン」の「DNS」の「編集」になっているので変更不要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/2ee49a3b-67a2-63ba-734b-3aae9078ef49.png)

ゾーンリソースの一番右側で自分の書き換えたいドメインだけ選択します。

以下の「クライアント IP アドレスフィルタリング」と「TTL」は指定した方がベターですが、今回は指定しないでおきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/26d77bd9-8fb2-6aaa-6bb8-c642a3e37b3f.png)

「DNS:編集」になっているのを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/3773dac7-2664-bdfc-3134-6ef446625a20.png)

次のページでトークンが発行されるので、curlコマンドのテストを使ってテストしておきましょう。

うまくいったら、トークンはどこか安全な場所に保管しておきます。

# 7. APIトークンをiniファイルに保存します

/rootディレクトリに.cloudflareというディレクトリを作って、
CloudflareのAPIトークンCredentialファイル
を作ります。

```
mkdir ~root/.cloudflare/
chmod 700 ~root/.cloudflare/
```

## 7.1 CloudflareのAPIトークンCredentialファイルを作る

```
echo 'dns_cloudflare_api_token = ＜APIトークンを入れる＞' > ~root/.cloudflare/cloudflare.ini
chmod 600 ~root/.cloudflare/cloudflare.ini
```

# 8. certbotコマンドで証明書を発行します

```bash
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.cloudflare/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 \
  --server https://acme-v02.api.letsencrypt.org/directory \
  -d ＜取得したドメイン＞ \
  -d *.＜取得したドメイン＞ \
  -m ＜メールアドレス＞ \
  -n
```

オプションで、ACME利用規約に同意を付けても良い
```
  --agree-tos
```

## 8.1 1回ドライランしておく

以下のコマンドでDry-runできる。

```bash
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.cloudflare/cloudflare.ini \
  --dns-cloudflare-propagation-seconds 60 \
  --server https://acme-v02.api.letsencrypt.org/directory \
  -d ＜取得したドメイン＞ \
  -d *.＜取得したドメイン＞ \
  -m ＜メールアドレス＞ \
  -n \
  --agree-tos
```

# 9. certbotを実行する

実行画面は以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/ab04fb7d-cee5-8884-816c-3c1fd679b0dc.png)

実行すると自動的にCloudflare DNSに以下のようなエントリーが登録されます。
DNS認証が終了したら自動的に削除されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/13e5f4d0-63e2-0b98-1289-d40a8d70679e.png)

`/etc/letsencrypt/live/` 配下に証明書が保存されます。
作られた証明書は、ワイルドカード証明書なのでホスト名が違っていても利用できます。

```
ls -la /etc/letsencrypt/live/**/*
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/fe5c8c7b-e790-04ae-8d17-1191a10c39b6.png)

# 10. まとめ

Let's EncryptとCloudflareで簡単に取得できるいい時代になりました。

# 11. 参考

https://qiita.com/ooxif/items/99ad3c93d4d6862d45f0#4-%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%82%92%E6%9B%B4%E6%96%B0%E3%81%99%E3%82%8B

CloudflareのDNSを使ってCertbotで証明書を発行する \| minetaro12 
https://0sn.net/posts/20220217/cloudflaredns-certbot/

LAN 内の開発用 Ubuntu に Let's Encrypt の無料 SSL 証明書をインストール \| Peddals Blog 
https://blog.peddals.com/lets-encrypt-for-apache-dev-site-on-ubuntu/

Proxmox WebUIからCloudflare DNS API経由でSSL証明書を取得できるようにする \#Let’sEncrypt \- Qiita 
https://qiita.com/katori_m/items/20ec2773000a89103774