NAT＋VM環境でBigbluebuttonサーバを立ててみた(その2)

#ドメインの取得

[その1](https://qiita.com/maron2000/items/4ff878c1984f408efb4c)でUbuntuの仮想マシンを構築した。
https://qiita.com/maron2000/items/4ff878c1984f408efb4c

ここでは、フリーのドメインと、ワイルドカードのSSL証明書(必須ではない)を取得する。
当方はIPアドレス非固定なので、Cloudflareを使って定期的にDNSを更新するスクリプト<sup>※</sup>も作成した。
※後述するが、Cloudflareで若干の問題ありのため、対応検討中。

##1.フリーのドメイン取得
色々なところでフリーのドメインを取得可能である。
自分はfreenom https://www.freenom.com/ja/index.html で取得した。

手続きは難しくないが、日本語でも詳細な解説があるので、そちらを参照されたい。
5種類のドメインから選べるようになっているが、選択しても「利用不可」となる場合は、**TLD(Top Level Domain)も含めて入力**(hogehoge→hogehoge.tk)すると良い。

[freenomでドメインの取得](https://qiita.com/hanbaga324/items/da0c4f6fa8d365db10c9)
https://qiita.com/hanbaga324/items/da0c4f6fa8d365db10c9

##2.DNSサーバの登録 (非固定アドレス対応)
非固定のIPアドレス変更をスクリプトから反映するために、CloudflareのDNSサービスに切り替える。
(ただし、一部TLDで問題あり。下記の※参照)
次のページも参考になる。
https://outlook.aptrust.net/start-up-cloudflare-free-plan/

+ Cloudflareにサインアップ https://dash.cloudflare.com/sign-up?lang=ja-jp
+ ドメイン名を設定
+ 設定プランを選択 (FreeプランでOK)
+ DNSレコードの設定(IPv4はAレコード、IPv6はAAAAレコード)
 + 名前: ドメイン名　コンテンツ: IPアドレス
 + (必要に応じて)名前: サブドメイン(wwwなど) コンテンツ: IPアドレス  
+ ドメイン(上記の例ではfreenom)のネームサーバーをCloudflareへ変更する
  + 上記でDNSレコードを設定すると、ドメインのネームサーバーを変更するような指示の画面が表示される
  + 一旦、別のウィンドウでfreenomの設定画面を開き、ネームサーバをfreenomからCloudflareの指示の通りに変更
   (https://my.freenom.com/knowledgebase.php?action=displayarticle&id=3)
  + Cloudflareのウィンドウに戻り、手続きを進める
  + 上記設定が反映されるとCloudflareから設定完了メールが届く
  
※IPアドレスはルータの設定画面などで確認可能。
　確認用サイト例：https://whatismyipaddress.com/

DNSレコードの設定画面
![DNSレコード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/7fe60b39-5825-84dc-a392-7fd2f62f9f54.png)
![nameserver](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/9600e5e7-b90d-041f-288d-6837a8e4034c.png)

 ※4/23よりCloudflareでfreenomで取得できるドメインに **DDNSの設定関連で制限** がかかっているので、freenomのままとするか、他のサーバも検討して下さい。
https://community.cloudflare.com/t/unable-to-update-ddns-using-api-for-some-tlds/167228
※freenomでDDNSするスクリプトもあるようです。(未検証)
https://github.com/maxisoft/Freenom-dns-updater


##3.DDNS設定用データの取得
IPアドレスの変更をCloudflareに反映させるための設定用データ(**ゾーンIDとAPIトークン**)を取得する。

+ ゾーンID(下図: 概要画面を下の方にスクロール)
![ゾーンID(「概要」画面)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/2819a93e-6924-5fb7-f736-4533af5cea7f.png)

+ APIトークン(上図の「APIトークンを取得」→「トークンを作成する」)
  + 「ゾーンDNSを編集する」のテンプレートを使用
  + 「ゾーンリソース」の指定を「特定のゾーン」-「ドメイン名」とする 
  + 「概要に進む」→「トークンを作成する」でAPIトークンが表示される
 
※表示されるトークンは**再表示できない**ので、控えておくこと。

![APIトークンの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/680b912f-6464-1f75-1781-d26dc0a47a40.png)

##4.IPアドレス変更をCloudflare DNSに反映するスクリプト
定期的にIPアドレスを確認し、CloudflareのDNSレコードと異なる場合は更新するスクリプト。

```shell:dns-update.sh
#!/bin/bash

# 参考: https://gist.github.com/lifehome/eb3f7d798f9bc6720cdc7d2be1238d4f
# CHANGE THESE
# auth_email="XXXXXXXX@XXXXXXXXXXX"  # The email used to login 'https://dash.cloudflare.com'
# auth_key="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
api_token="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" #3.で取得したAPIトークン
record_name="www.hogehoge.com"     # Which record you want to be synced
zone_identifier="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"   #3.で確認したZone ID

# DO NOT CHANGE LINES BELOW
while [ -z $ip ]
do
	ip=$(curl -s https://ipv4.icanhazip.com/)    # IPアドレスの取得
	sleep 1s
done

echo `date`

# SCRIPT START
echo "[Cloudflare DDNS] Check Initiated"

# Seek for the record
record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer $api_token")
#     -H "X-Auth-Key:$auth_key" \    #APIトークンがうまく使えない場合のみ
#     -H "X-Auth-Email:$auth_email") #APIトークンがうまく使えない場合のみ

#echo "$record"

# Can't do anything without the record
if [[ $record == *"\"count\":0"* ]]; then
  >&2 echo -e "[Cloudflare DDNS] Record does not exist, perhaps create one first?"
  exit 1
fi

# Set existing IP address from the fetched record
#old_ip=$(echo "$record" | grep -Po '(?<="content":")[^"]*' | head -1)
old_ip=$(echo "$record" | grep -Po '(?<="content": ")[0-9\.]*')
echo "old_ip = $old_ip"

# Compare if they're the same
if [ $ip == $old_ip ]; then
  echo "[Cloudflare DDNS] IP has not changed."
  exit 0
fi

echo "old_ip = $old_ip"

# Set the record identifier from result
#record_identifier=$(echo "$record" | grep -Po '(?<="id":")[^"]*' | head -1)
record_identifier=$(echo "$record" | grep -Po '(?<="id": ")[0-9a-f]*')

echo "record_identifier = $record_identifier"

# The execution of update
update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" \
	-H "Authorization: Bearer $api_token" \
	-H "Content-Type: application/json" \
	--data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"proxied\":false,\"name\":\"$record_name\",\"content\":\"$ip\"}")

# The moment of truth
case "$update" in
*"\"success\":false"*)
  >&2 echo -e "[Cloudflare DDNS] Update failed for $record_identifier. DUMPING RESULTS:\n$update"
  exit 1;;
*"\"error\""*)
  >&2 echo -e "[Cloudflare DDNS] Update failed for $record_identifier. DUMPING RESULTS:\n$update"
  exit 1;;
*)
  echo "[Cloudflare DDNS] IPv4 context '$ip' has been synced to Cloudflare.";;
esac
```

※上述しましたが、freenomでDDNSするスクリプトもあるようです。(未検証)
https://github.com/maxisoft/Freenom-dns-updater

スクリプトを適当なところ(/usr/local/binなど)に保存し、crontabで自動実行の設定(再起動時と5分おきにIPアドレスを確認)

```shell-session
sudo chown root:root dns-update.sh
sudo chmod 700 dns-update.sh
sudo crontab -e
```
```shell:crontab
#以下の2行を追加
4-59/5 * * * * bash /usr/local/bin/dns-update.sh > /var/log/dns-update.log 2>&1
@reboot bash /usr/local/bin/dns-update.sh > /var/log/dns-update.log 2>&1
```

#ワイルドカードSSL証明書(Let's Encrypt)の取得
BigBlueButtonのインストーラでSSL証明書の取得も自動でやってくれるのだが、**ワイルドカードのSSL証明書**を使いたいので、自分でインストールを実施することにした。
(ワイルドカードでなくてもいいや、という人はこちらを飛ばしてもインストールは可能）

※参考：https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx
       https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9

##1.Certbotのインストール
```shell
# Certbot PPAインストール
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update

#Certbot インストール
sudo apt-get install certbot python3-certbot-nginx

#DNSプラグイン(ここではCloudflare)
sudo apt-get install python3-certbot-dns-cloudflare
```
※DNSプラグインについては、https://certbot.eff.org/docs/using.html#dns-plugins参照

##2.設定用データの作成
```shell:~/.secrets/certbot/cloudflare.ini
# Cloudflare API token used by Certbot (上記「ドメイン取得」の3.で取得したAPIトークン)
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567

#certbotのバージョンが古い(2.3.1未満)場合、APIトークン使用不可。APIキーはAPIトークン取得のページから取得可能
dns_cloudflare_email = cloudflare@example.com
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234
```
```shell
# 権限を設定しておく
sudo chown root:root ~/.secrets/certbot/cloudflare.ini
sudo chmod 600 ~/.secrets/certbot/cloudflare.ini
```

##3.SSL証明書の取得

```shell
#DNSプラグインを使う場合
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
  -d *.example.com

#DNSプラグインを使わない場合 (途中で指示されたTXTレコードを手動でDNSサーバに登録)
sudo certbot certonly --manual \
 --preferred-challenges=dns \
 --email XXXX@YYYY.com \
 --agree-tos \
 -d *.example.com
```
```shell:DNSプラグインを使わない場合の画面表示例
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.bbb.example.com with the following value:

0bIA-3-RqbRo2EfbYTkuKk7xq2mzszUgVlr6l1OWjW8

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
```
```shell:DNSにTXTレコードを追加(DNSプラグインを使わない場合)
#画面表示に合わせて、レコードを作成する。
#設定したらEnterを押せと書いてあるが、その前にレコードが拡散されるまで1分程度待つこと。
_acme-challenge.bbb.example.com.  TXT   "0bIA-3-RqbRo2EfbYTkuKk7xq2mzszUgVlr6l1OWjW8"   60
```
#その３へ
その３でいよいよBigBlueButtonをインストールする。
https://qiita.com/maron2000/items/e81ff9f5196dcf78cd87