Termuxネイティブ環境でacme-nginxを使いワイルドカード証明書を自動取得!

前回、別記事にすると言っていた件です。

Termux環境で動作するLet’s Encryptのワイルドカードドメインに対応した自動化ツールを探せ!

https://junkhack.gpl.jp/2020/09/11/wildcard-domain-acme/

今日のネタは、Termuxネイティブ環境で acme-nginx というPythonで、作られた自動化ツールで Let’s Encrypt のワイルドカードドメイン証明書を取得します。さぁうまく出来るでしょうか? ちなみに、ワイルドカード証明書とは、以下のようなことを言います。

ワイルドカード証明書とは

「*.example.jp」のように、コモンネームの一番左のラベルにアスタリスク(*)を指定したサーバー証明書です。

ワイルドカード証明書は「www.example.jp」「login.example.jp」「member.example.jp」のように、アスタリスクと同一階層のサブドメインのみが異なるすべてのサーバーにインストールできます。
また、JPRSの提供するワイルドカード証明書なら、「*.example.jp」の証明書を「example.jp」のようにアスタリスク(*)を除いたホスト名のサーバーでも利用できます。

https://jprs.jp/pubcert/about/wildcard/

では作ってみましょう。acme-nginx はもう入れてあるものとします。DNSはデジタルオーシャンに変更して、APIトークンを取得してあります。

ステップ1

適当な証明証を入れておくディレクトリを作っておきます。例では、example.jp というドメインで説明しています。

cd
mkdir -p ssl/example.jp
cd ssl/example.jp

ステップ2

アカウントキーと、ドメインキーを作成します。

openssl genrsa 4096 > account.key
openssl genrsa 4096 > example.jp.key

ステップ3

digitaloceanのトークンを環境変数に入れておきます。

export API_TOKEN=digitaloceanのトークン

ステップ4

証明書を発行します。WEBの認証はないので便利ですね。パスは、Termuxxの環境変数 $PREFIX に置き換えたほうが見やすいかもですね。

acme-nginx \
	--no-reload-nginx \
	-k /data/data/com.termux/files/home/ssl/example.jp/account.key \
	--dns-provider digitalocean \
	--domain-private-key /data/data/com.termux/files/home/ssl/example.jp/example.jp.key \
	-o /data/data/com.termux/files/home/ssl/example.jp/example.jp.crt \
	-d '*.example.jp' -d 'example.jp'

ドメインの指定は、*.example.jp と example.jp を指定します。そうしないと、example.jp でのドメインだけのアクセスで証明書が無効となります。
 実際のログは(ドメイン名は置き換えていますが)以下のようになります。

2020-09-13 02:45:40,777 - INFO - trying to create account key /data/data/com.termux/files/home/ssl/example.jp/account.key
2020-09-13 02:45:41,727 - INFO - trying to register acmev2 account
2020-09-13 02:45:43,612 - INFO - already registered
2020-09-13 02:45:43,613 - INFO - trying to create domain key
2020-09-13 02:45:43,615 - INFO - acmev2 dns challenge
2020-09-13 02:45:43,615 - INFO - preparing new order
2020-09-13 02:45:46,648 - INFO - order created
2020-09-13 02:45:47,644 - INFO - verifying domain example.jp
2020-09-13 02:45:47,670 - INFO - creating TXT dns record _acme-challenge.example.jp IN TXT uWmLyGGgK1Jyj(省略)RHo-A5TUKBAac
2020-09-13 02:45:50,642 - INFO - asking acme server to verify challenge
2020-09-13 02:45:52,486 - INFO - waiting for example.jp challenge verification
2020-09-13 02:45:53,239 - INFO - example.jp verified!
2020-09-13 02:45:53,240 - INFO - delete dns record
2020-09-13 02:45:56,793 - INFO - verifying domain example.jp
2020-09-13 02:45:56,817 - INFO - creating TXT dns record _acme-challenge.example.jp IN TXT hP2bwoYASAQYL(省略)VkiKGDupZxfw0
2020-09-13 02:45:59,551 - INFO - asking acme server to verify challenge
2020-09-13 02:46:02,005 - INFO - waiting for example.jp challenge verification
2020-09-13 02:46:02,884 - INFO - example.jp verified!
2020-09-13 02:46:02,885 - INFO - delete dns record
2020-09-13 02:46:05,385 - INFO - signing certificate
2020-09-13 02:46:08,480 - INFO - certificate signed!
2020-09-13 02:46:08,480 - INFO - downloading certificate
2020-09-13 02:46:09,472 - INFO - writing result file in /data/data/com.termux/files/home/ssl/example.jp/example.jp.crt

30秒くらいで、完了していますね。dnsにテキストレコードを書いている部分が2回あります。ちゃんと認証が通ればテキストレコードは削除していますね。これは便利!作者に感謝です!

ステップ4

あとは、キーと証明書をnginxに設定して再起動しておきます。

・Key
 /data/data/com.termux/files/home/ssl/example.jp/example.jp.key

・CRT
 /data/data/com.termux/files/home/ssl/example.jp/example.jp.crt

あとは、実際のクライアントから確認してみます。

おー、鍵マークがかかっていますね。うまくできているようです! 今度は、curlで https://gpl.jp にアクセスできるか確認してみます。WordPressには、このドメインはマッピングしていないので、静的ファイルが置いてあるURLに対してアクセスしてみます。curlクライアントはリモートのMacからです。

$ curl -Iv https://gpl.jp/license.txt
*   Trying 116.58.181.140...
* TCP_NODELAY set
* Connected to gpl.jp (116.58.181.140) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=*.gpl.jp
*  start date: Sep 12 16:46:12 2020 GMT
*  expire date: Dec 11 16:46:12 2020 GMT
*  subjectAltName: host "gpl.jp" matched cert's "gpl.jp"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fd360002000)
> HEAD /license.txt HTTP/2
> Host: gpl.jp
> User-Agent: curl/7.54.0
> Accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
HTTP/2 200 
< server: nginx
server: nginx
< date: Sat, 12 Sep 2020 18:09:29 GMT
date: Sat, 12 Sep 2020 18:09:29 GMT
< content-type: text/plain; charset=utf-8
content-type: text/plain; charset=utf-8
< content-length: 19915
content-length: 19915
< last-modified: Wed, 12 Feb 2020 11:54:05 GMT
last-modified: Wed, 12 Feb 2020 11:54:05 GMT
< vary: Accept-Encoding
vary: Accept-Encoding
< etag: "5e43e75d-4dcb"
etag: "5e43e75d-4dcb"
< strict-transport-security: max-age=15552000
strict-transport-security: max-age=15552000
< x-xss-protection: 1; mode=block
x-xss-protection: 1; mode=block
< x-frame-options: DENY
x-frame-options: DENY
< x-frame-options: SAMEORIGIN
x-frame-options: SAMEORIGIN
< x-frame-options: ALLOW-FROM https://www.youtube.com https://www.wordpress.com
x-frame-options: ALLOW-FROM https://www.youtube.com https://www.wordpress.com
< x-content-type-options: nosniff
x-content-type-options: nosniff
< content-security-policy: default-src * 'self' data: 'unsafe-inline' 'unsafe-eval' ;
content-security-policy: default-src * 'self' data: 'unsafe-inline' 'unsafe-eval' ;
< referrer-policy: strict-origin
referrer-policy: strict-origin
< permissions-policy: fullscreen=() geolocation=()
permissions-policy: fullscreen=() geolocation=()
< x-hacker: Hello. :-)
x-hacker: Hello. :-)
< accept-ranges: bytes
accept-ranges: bytes

< 
* Connection #0 to host gpl.jp left intact

ちょっと長いですが、途中「SSL certificate verify ok.」が出ていますね。接続は、TLS2 でHTTP/2 プロトコルになっていますね。これで当初の目的は達成できました! チェックサイトでは、A+判定出ていました。問題なさそうですね。

SSL Server Test (Qualys SSL Labs)

https://www.ssllabs.com/ssltest/

あとは、自動実行すればいいんですが termux の限られたリソースの中で cronjobを回して、ログを出し、何かあったらメールするっていうのをやるべきか、その他の方法を採用するかで迷っています。

 そもそも、termux でcronjobはちゃんと動くか確認しておかないとです。なんたって、androidシステム上で動いているわけですから。Dozeモードの影響とかそういうのは大丈夫なのか確認しないとです。

あとがき

気になることはいろいろありますが、そろそろデータの引っ越しをやりますかね。 WordPress.com から速めに引っ越しして、新環境で記事を書いて行きたいです。

スマホ上に作った自宅サーバのWordPressで、テスト評価がほぼオールAになった!

はい、ただ今引っ越し準備中でして、このブログをスマートフォン上に作ったWordPressサーバに引っ越しします。9月末か10月頭予定で各種チューニングをやっていましたが、ついにスピードテスト系の評価サイトでほぼオールAを取ることに成功しました。

いくつかある評価サイトの中では、ここが一番好きです。ここの計測サイトは東京リージョンもあり、また各種グラフが見やすくビデオプレビューまで付いて来ます。

WEBPAGETEST

https://www.webpagetest.org/

主な評価観点は、左から以下のようになっています。

  1. セキュリティ
  2. 初期アクセスまでの時間
  3. Keep-alive通信がONか?
  4. 圧縮転送されているか?
  5. イメージの圧縮はどうか?
  6. 静的コンテンツがキャッシュされているか?
  7. CDNを使っているか?

7番のCDNは一部、WordPressのをつかっていますが、全部は使っていないので、x になっています。これはどうするかまだ迷っています。一度、国内のCDNをテストで使ってみようと思ったのですがうまく動作せずでした。まだ原因がわかっていません。

 難易度的には、簡単なものから3・4・5・6・2・1・7で難しかったです。今回は、自分なりの考えをメモりつつ、1つづつ紹介していきたいなと思います。必ず正解っていう部分はないところでもあるので、あくまで自分はこんな対策と対応をしたよっていう感じです。いろいろツッコミどころはあるとは思いますが、何かあればコメントでお気軽にどうぞ。

難易度G・Keep-alive通信がONか?

これは apache を使おうが、nginx を使おうが最初からデフォルトONになっているので意識せずともAになると思います。今回は、最終的に nginx を使うことにしましたので、nginx.conf に以下を設定しています。タイムアウト時間は短いほうが良いと思います。でも、ここは突き詰めると難しい部分です。興味がある方は、以下などを一読されると良いかなと思います。

ぜんぶTIME_WAITのせいだ!

https://qiita.com/kuni-nakaji/items/c07004c7d9e5bb683bc2
http {
::(省略)
    keepalive_requests 100;
    keepalive_timeout  3;
::(省略)

termux 上の android OSでは、一般的なLinuxと違ってKernelパラメータも調整されているはずですので、ここが何が適切なのかを明確にするには root権限のあるスマホで termux を動かし負荷テストをしながら、各種TCPの状態遷移を見ていくのが正しい姿勢です。という意味では一番難しい部類ですが、今回はそこまで突っ込まないことにします。

難易度F・圧縮転送されているか?

圧縮レベルは1でも十分という意見はありそうです。

http {
::(省略)
    gzip  on;
    gzip_vary       on;
    gzip_proxied    any;
    gzip_comp_level 6;
    gzip_types      text/plain text/css text/xml text/javascript
                    application/json application/javascript application/x-javascript
                    application/xml application/rss+xml application/atom+xml
                    image/svg+xml;
::(省略)

難易度E・イメージの圧縮はどうか?

これは今回は、ジェットパックのプラグインでwordpress のCDN側から画像が出ています。そこで適切に圧縮してくれているので簡単です。ただ、やりだすと奥が深いので、中間くらいの位置付けにしてあります。

難易度D・静的コンテンツがキャッシュされているか?

これは、レスポンスヘッダにNo max-age または expiresをつければ解決します。具体的には、nginxの設定で以下を設定すればOKです。

location ~* \.(jpg|jpeg|gif|png|css|js|swf|ico|pdf|svg|eot|ttf|woff)$ {
    expires 60d;
    add_header Cache-Control "public, no-transform";
    access_log off;
}

難易度C・初期アクセスまでの時間

これは、WordPress側でキャッシュを作るのが一番最速です。各種プラグインがありますが、いろいろ試した結果、今の所はAutoptimizeに落ち着いています。

デフォルト設定でも十分効果はあります。迷ってる設定としては、Google フォントの削除 をするかしないかです。表示の綺麗さを取るか、お客様に快適にアクセスしてもらうのを取るか ですね。あとは、ネットワーク的な速度の部分があります。今は InterLink の回線上にいますが、少し工夫してある部分といえば、常時利用する経路とは分離してあるくらいでしょうか? WiFiの5G接続でもこのくらいは出ますよという参考値になればと思います。WiFiルーターの側にスマホ(サーバ)は置いてあります。距離を離すと応答速度が遅れます。

難易度B・セキュリティ

これが結構難しかったです。まず、WordPress の最新を使ってもjquery 1.12.4でした。これは脆弱性があるので、あげて置きたいところですが WordPressはIE8のことも考えて意図的に落としているようです(たぶん)。なので、以下プラグインで上書きしています。

しかし、これ以外もやることがあって以下のチェックサイトに行ったほうがわかりやすいかもしれません。各種セキュリー関連のhttpヘッダーを付与する必要があります。

https://securityheaders.com/

最初はここ、真っ赤でF判定だったです。

対策としては、NGINXの設定でヘッダに以下をつければA判定となりクリアになりますが、まだiFrameの設定が未完結です。X-Frame-Optionsは、古く Content-Security-Policy の指定で行うのが良さそうです。frame-ancestors を指定し組み込める参照元を制限する方法が良いということはわかっているのですが、まだ設定値が決まりません。A判定は取っていますが、内容がない状態です。

add_header Strict-Transport-Security "max-age=15552000"; 
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Frame-Options "ALLOW-FROM https://www.youtube.com";
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src * 'self' data: 'unsafe-inline' 'unsafe-eval' ;";
add_header Referrer-Policy strict-origin always;
add_header Permissions-Policy "fullscreen=() geolocation=()";

難易度A・CDNを使っているか?

ここは、DNSの向け先を変えたり、CDNのキャッシュをコントロールしたりする必要があり、運用とも関わる部分です。一度設定したのですが、うまく動作せずここは今の所一番の課題となっています。そもそも、月間5000ページビューにも行かないこのサイトでCDNを導入する必要があるかどうか? という点もありますが、一度やって見ないとわかりません。あと仕事ではなく、趣味なので無料のものしか使う気はありません。さて、どこがいいんでしょうかね?

あとがき

このサーバは、スマホで動いていてWiFiの無線で繋がっていますが、こんなちっさな筐体でもWordPressが動く、しかもA評価までもらえるなんて! 感動です。Termuxは最高のアプリですね。神アプリ認定です。

 しかも、常時SSL対応ですよ。もちろん、無料のSSL証明書です。なんだか時代は刻々と進化していますね。

Termux環境で動作するLet’s Encryptのワイルドカードドメインに対応した自動化ツールを探せ!

termuxで動作するのがほしい!

先日、termux上で動作を試したちっさな acme-tiny というPython製のACMEクライアントですがどうやら調べたらワイルドカードには対応していないようです。ACMEとは、Automatic Certificate Management Environment の略で、ざっくり言えばSSL証明書発行の管理をやりとりするプロトコルです。rfc8555 にあるようです。この中でワイルドカード証明書はDNSチャレンジによる認証が必要ということです。

acmy-tinyの設計方針

acmy-tiny のプログラムは全部で198行です。作者は小さなプログラムにとどめておきたいようです。以下のように、200行くらいにとどめておきたいので、DNSチャレンジのサポート(ワイルドカードサポート)はしませんということです。

I don’t plan on adding DNS challenge support (thus no wildcard support)

https://github.com/diafygi/acme-tiny/issues/195#issuecomment-372097617

I don’t plan on increasing the line limit above 200.

https://github.com/diafygi/acme-tiny/issues/195#issuecomment-372097580

作者の方針なんで、仕方ないですね。でも、必要以上の機能は追加しないと言い切るのは立派なことです。当初のコンセプトは崩さず。きっと200行以内の小さなプログラムであることがどこかで生きてくるはずです。

 で、通常はこれで十分事足ります。このブログでも junkhack.gpl.jpというドメインの証明書が取れればいいので問題ありませんが、*.gpl.jp にも使えるようにしてみたいので、一度触れておきたいんですよね。昔は、ワイルドカードドメインの証明書って結構高くて手が出なかったのを覚えています。

ワイルドカードの証明書がほしい!

 使いたい理由として、ワイルドカードの証明書を入れておくと、移行がスムーズになるというのもあります。実は、サブドメインを hack.gpl.jp にしようかなと思っていますので、junkhack.gpl.jp もマッピングしておこうかなと。つまり、今作っているスマホ新サーバでは、hack.gpl.jp として運用しておいて、wordpress の設定で複数のドメインにもマッピングできるようにしておけば、DNSの切替でどっちも同じところにアクセスできるようになります。(たぶん)

https://junkhack.gpl.jp/
https://hack.gpl.jp/

そういう運用や移行はやったことないんですが、理論上はできそうです。これを実現するためには、ワイルドカードの証明書があると便利かなと。使わないならば、バーチャルホストの設定を2つ作り、シングルの証明書を2つ発行するという方法でもいいのですが。

acme-nginx ワイルドカード証明書対応の小さなやつ!

 さて、なんか良いのは無さそうかなと、世界は広いので誰か絶対作ってるはずです。・・・はい! ありました。acme-nginx です。まだ未確認ですが termuxでも動作するはずです。

ReadMeを読んでみると、どうやらDNSのテキストレコードも自動的に書き換えるようで、APIが完備したDNSプロバイダーじゃないとダメなようです。現在、動作するのは、デジタルオーシャンと、AWS Route53のDNSです。

バリュードメインのAPI

acme-nginxが、デジタルオーシャンのDNSと、AWS Toute53に対応しているのはわかりましたが、現在使っているのはバリュードメインです。ここもつい最近、APIが完備されたので、使えないか調査してみることにしました。もし使える感じなら、acme-nginx に機能を拡張すればいいだけです。

バリュードメインのAPIマニュアルはここにあります。

バリュードメインAPIドキュメント (1.0.0)

https://www.value-domain.com/api/doc/domain/

実際に、APIトークンを発行していじってみました。curlに、jq をパイプしてjsonデータを見やすくしています。jqは、termuxにもあるし、macの brewにもあります。jq、便利ですね。Qitaで知りました!

curl -H 'Authorization: Bearer ★トークン' \
-H 'Content-Type:application/json' \
-X GET \
'https://api.value-domain.com/v1/freedns/{★domainid or domianname}' | jq

トークンや、ドメインID or ドメイン名など入れると以下のように出てきます。

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1388    0  1388    0     0   2258      0 --:--:-- --:--:-- --:--:--  2260
{
  "results": {
    "domainid": "xxxxxx",
    "domainname": "gpl.jp",
    "records": "#InterLink\na www 116.58.181.140\n# gpl.jp\na @ 116.58.181.140\na hack 116.58.181.140\na jh 116.58.181.140〜省略〜\na * 116.58.181.140",
    "ttl": "60"
  },
  "request_id": "20200911xxxxxxxxxxxxxxxxxxV",
  "request": {
    "path": "/v1/freedns/xxxxxxxx",
    "method": "GET",
    "params": []
  }
}

で、このrecordsっていう値、バリュードメイン使ったことがある人ならわかると思いますが、設定のテキストがずらっと出てきます。APIドキュメントの「DNS設定の変更」を読んでみると、レコードごとに改行区切りの文字列です。

はい! つまり、aレコード単体で追加や削除とか、txtレコードだけ追加とかそういうことはできません。まぁ、その荒さがバリュードメインの良いところでもあるのですが。(設定ファイルをテキストファイルで管理しているだけなので、コンパネから登録するのが便利なんです)

ということで、寝ました! このテキストファイルを処理する部分まで作るとメンドくさいので、デジタルオーシャンのAPIはどうなっているのか気力が復活した時にでも調べることにします。

デジタルオーシャンのAPI

さて、日が暮れて夜があけました。ぼちぼち、デジタルオーシャンのAPIでも調べることにします。ということで、以下がドキュメントです。

Create a New Domain Record

https://developers.digitalocean.com/documentation/v2/#create-a-new-domain-record

なるほど、良くできていますね。個別にレコードタイプ(A、MX、CNAMEなど)を指定し、データを更新も可能です。これなら、DNSを変更したほうが速いですね!

バリュードメインから、デジタルオーシャンへDNSを変更

というわけで、デジタルオーシャンのDNSだけ使うなら無料なんで、ネームサーバの向け先を変更しました。なかなか管理パネル、使いやすかったです。google のG Suite Toolbox で引くとNSが切り替わっていました。

https://toolbox.googleapps.com/apps/dig/#NS/

;QUESTION
gpl.jp. IN NS
;ANSWER
gpl.jp. 1799 IN NS ns2.digitalocean.com.
gpl.jp. 1799 IN NS ns3.digitalocean.com.
gpl.jp. 1799 IN NS ns1.digitalocean.com.

ようこそ、デジタルオーシャンへ

名前が直接的でいいですね! デジタルの海です。ここはレジストラ業務はやっていないので、ドメイン取得はできないです。しかし、どこで取得したドメインでもネームサーバの向け先をデジタルオーシャンにすれば使えます。更新料金は、自分の場合はバリュードメインに支払います。デジタルオーシャンはAPIも充実していて、使いやすそうです。仮想サーバは日本にリージョンがまだないと思うので、安くて使いやすければそのうち、使ってみるかもしれません。

DNS周りでは、以下の制約がありますのでご注意を。自動翻訳なんでちょっと変ですが。

DigitalOceanは現在ドメイン登録サービスを提供していません。DigitalOcean DNSを使用するには、ドメイン名をレジストラに登録し、DigitalOceanのネームサーバーを指すようにドメインのNSレコードを更新する必要があります

デフォルトでは、最大50のドメインを追加できます。サポートチケット開いて、増加が必要な理由を説明することで、制限を引き上げることができます。

すべてのDNSレコードには、30秒以上のTTL値が必要です。
DigitalOcean DNSは、以下のCAAレコード機能をサポートしていません。

値にセミコロン(;)を送信して、証明書の発行を禁止します。
CA名の後に名前と値のタグを許可します。例:letsencrypt.org; abc=cde

ワイルドカードレコードでカバーされるホスト名で作成されたレコードは、そのホスト名のワイルドカード解決を停止します。たとえば、にAワイルドカードレコードがあり*.example.com、ホスト名にMXレコードを追加するemail.example.comと、Aワイルドカードレコードはで提供されなくなりますemail.example.com。ただし、email.example.comユースケースで必要な場合は、ホスト名に明示的なAレコードを追加できます。

DigitalOcean DNSはタグをサポートしていません。

DigitalOceanの利用規約では、OFAC認定国からの国コードトップレベルドメイン(ccTLD)を追加することは禁止されています。国のリストなどの詳細については、参照ネットワークの合法的な使用にセクションを利用規約

https://www.digitalocean.com/docs/networking/dns/

さて、では記事が長くなりすぎるので、acme-nginx でワイルドカードドメイン証明書を取得するお楽しみは、別記事にします。では、また〜!