lego+docker-composeでワイルドカード証明書を爆速ゲット

[lego](https://github.com/go-acme/lego)を使えば簡単にワイルドカード証明書を取得できるので、docker-composeでお手軽環境を作ってみました。

# 結論

1. [APIを使用するためのトークンを取得する｜ConoHa VPSサポート](https://support.conoha.jp/v/apitokens/) を参考にアクセストークンを取得
2. 以下のdocker-composeにトークン、ドメイン、メールアドレスを設定する
3. `mkdir lego && docker-compose up`


```yaml
version: '3.3'

services:
  lego:
    image: xenolf/lego
    environment:
      - CONOHA_REGION=tyo1
      - CONOHA_TENANT_ID=********************************
      - CONOHA_API_USERNAME=************
      - CONOHA_API_PASSWORD=************
    command: >
      --path /lego
      --dns conoha
      --email hogehoge@dummy.com
      --domains "*.mydomain.com"
      --domains "mydomain.com"
      --accept-tos
      run
    volumes:
      - type: bind
        source: ./lego
        target: /lego

```

# legoについて

legoはGo製の`Let's Encrypt`のクライアントアプリです。certbotよりもお手軽に使える感じで良いです。

docker化しなくとも、[Release v2.6.0 · go-acme/lego](https://github.com/go-acme/lego/releases/tag/v2.6.0) からバイナリを習得して設置すれば使えるので、docker化するメリットもあまり無いのですが環境をまとめる意味でdocker-composeで構成を書いておきました。

今回は個人で借りている[ConoHa](https://www.conoha.jp/)のVPSにあるDNS  APIを利用して証明書を発行しました。
[ConoHaのDNSをAPIから操作する話 - NaruseJunのメモ帳](https://narusejun.com/archives/25/)の方がConoha対応していただいたみたいです。ありがとうございます。


その他で対応しているプロバイダは以下にまとめられていました。
[DNS Providers :: Let’s Encrypt client and ACME library written in Go.](https://go-acme.github.io/lego/dns/)  
AWSの場合は以下のサイトが参考になります。Route53のパーミッションの設定等がわかればすぐわかる内容かな、という感じでした。

* [Let'sEncryptのワイルドカード証明書取得ならlegoがお薦め - re:inventing the wheel](https://blog.eksy.tokyo/post/lego-is-recommend-to-wildcard-certificate-for-letsencrypt/)
* [lego で Let's Encrypt の証明書を Route53 DNS 認証で取得する - らくがきちょう](http://sig9.hatenablog.com/entry/2018/04/11/000000)


# Conohaでの作業手順

1. ConohaのAPI利用のためのトークンを取得
2. docker-compose.ymlの設定
3. 実行

これだけです。

アクセストークの習得は [APIを使用するためのトークンを取得する｜ConoHa VPSサポート](https://support.conoha.jp/v/apitokens/) を参考にお願いします。


# docker-composeの設定

以下の`docker-compose.yml`ファイルを用意します

```yaml
version: '3.3'

services:
  lego:
    image: xenolf/lego
    environment:
      - CONOHA_REGION=tyo1
      - CONOHA_TENANT_ID=********************************
      - CONOHA_API_USERNAME=************
      - CONOHA_API_PASSWORD=************
    command: >
      --path /lego
      --dns conoha
      --email hogehoge@dummy.com
      --domains "*.mydomain.com"
      --domains "mydomain.com"
      --accept-tos
      run
    volumes:
      - type: bind
        source: ./lego
        target: /lego

```

`environment`のところは管理ページにしたがって自身のものを使ってください。

|環境変数| 設定値|備考|
|---|---|---|
|CONOHA_REGION|tyo1|シンガポールリージョンなら`sin1`?|
|CONOHA_TENANT_ID|[管理ページ](https://manage.conoha.jp/API/)のテナントID|
|CONOHA_API_USERNAME|[管理ページ](https://manage.conoha.jp/API/)のユーザー名|
|CONOHA_API_PASSWORD|[管理ページ](https://manage.conoha.jp/API/)のパスワード|


その他、`email`を自分の物に、`domains`を発行したい自身のドメイン名に書き変えて以下を実行します。

```console
$ mkdir lego
$ docker-compose up

Recreating lego_lego_1 ... done
Attaching to lego_lego_1
lego_1  | 2019/06/09 06:03:19 [INFO] [*.mydomain.com] acme: Obtaining bundled SAN certificate
lego_1  | 2019/06/09 06:03:20 [INFO] [*.mydomain.com] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/nQXbiz2zp5iqoG7fetDLx76RxpSOF0SXAHy8mcGKRew
lego_1  | 2019/06/09 06:03:20 [INFO] [*.mydomain.com] acme: use dns-01 solver
lego_1  | 2019/06/09 06:03:20 [INFO] [*.mydomain.com] acme: Preparing to solve DNS-01
lego_1  | 2019/06/09 06:03:20 [INFO] [*.mydomain.com] acme: Trying to solve DNS-01
lego_1  | 2019/06/09 06:03:20 [INFO] [*.mydomain.com] acme: Checking DNS record propagation using [127.0.0.11:53]
lego_1  | 2019/06/09 06:03:20 [INFO] Wait for propagation [timeout: 1m0s, interval: 2s]
lego_1  | 2019/06/09 06:03:25 [INFO] [*.mydomain.com] The server validated our request
lego_1  | 2019/06/09 06:03:25 [INFO] [*.mydomain.com] acme: Cleaning DNS-01 challenge
lego_1  | 2019/06/09 06:03:26 [INFO] [*.mydomain.com] acme: Validations succeeded; requesting certificates
lego_1  | 2019/06/09 06:03:27 [INFO] [*.mydomain.com] Server responded with a certificate.
lego_lego_1 exited with code 0
```

こんな感じで出力されればOKです。

以下のようなファイルができているはずです。

```console
$ sudo find lego
lego
lego/certificates
lego/certificates/_.mydomain.com.json
lego/certificates/_.mydomain.com.crt
lego/certificates/_.mydomain.com.issuer.crt
lego/certificates/mydomain.com.crt
lego/certificates/mydomain.com.json
lego/certificates/mydomain.com.key
lego/certificates/_.mydomain.com.key
lego/certificates/mydomain.com.issuer.crt
lego/accounts
lego/accounts/acme-staging-v02.api.letsencrypt.org
lego/accounts/acme-staging-v02.api.letsencrypt.org/hogehoge@dummy.com
lego/accounts/acme-staging-v02.api.letsencrypt.org/hogehoge@dummy.com/keys
lego/accounts/acme-staging-v02.api.letsencrypt.org/hogehoge@dummy.com/keys/hogehoge@dummy.com.key
lego/accounts/acme-staging-v02.api.letsencrypt.org/hogehoge@dummy.com/account.json
lego/accounts/acme-v02.api.letsencrypt.org
lego/accounts/acme-v02.api.letsencrypt.org/hogehoge@dummy.com
lego/accounts/acme-v02.api.letsencrypt.org/hogehoge@dummy.com/keys
lego/accounts/acme-v02.api.letsencrypt.org/hogehoge@dummy.com/keys/hogehoge@dummy.com.key
lego/accounts/acme-v02.api.letsencrypt.org/hogehoge@dummy.com/account.json
```

あとはnginx等で読みこめばOKです。

```nginx
    ssl_certificate /etc/lego/certificates/_.mydomain.com.crt;
    ssl_certificate_key /etc/lego/certificates/_.mydomain.com.key;
```

ファイルの出力先を変えたい場合はvolumes属性を変えれば良いです。

```diff
    volumes:
      - type: bind
-        source: ./lego
+        source: /path/to/output
        target: /lego
```

# 更新について

証明書の更新は`run`ではなく`renew`コマンドで実行します。  
その際に`--days`オプションをつけておけば、例えば30日未満にならないと更新処理を走らないようにできます。  

```diff
version: '3.3'

services:
  lego:
    image: xenolf/lego
    environment:
      - CONOHA_REGION=tyo1
      - CONOHA_TENANT_ID=********************************
      - CONOHA_API_USERNAME=************
      - CONOHA_API_PASSWORD=************
    command: >
      --path /lego
      --dns conoha
      --email hogehoge@dummy.com
      --domains "*.mydomain.com"
      --domains "mydomain.com"
      --accept-tos
-      run
+      renew
+      --days 30
    volumes:
      - type: bind
        source: ./lego
        target: /lego
```


# 参考

[Let'sEncryptのワイルドカード証明書取得ならlegoがお薦め - re:inventing the wheel](https://blog.eksy.tokyo/post/lego-is-recommend-to-wildcard-certificate-for-letsencrypt/)

[ConoHaのDNSをAPIから操作する話 - NaruseJunのメモ帳](https://narusejun.com/archives/25/)

[DNS Providers :: Let’s Encrypt client and ACME library written in Go.](https://go-acme.github.io/lego/dns/) 

[Let'sEncryptのワイルドカード証明書取得ならlegoがお薦め - re:inventing the wheel](https://blog.eksy.tokyo/post/lego-is-recommend-to-wildcard-certificate-for-letsencrypt/)

[lego で Let's Encrypt の証明書を Route53 DNS 認証で取得する - らくがきちょう](http://sig9.hatenablog.com/entry/2018/04/11/000000)