IBM Cloud Internet Service(CIS): ドメイン移行方法についての考察

# 1. はじめに
IBM Cloud Internet Service(CIS)にどのようにスムーズに移行させるかというのは各プロジェクトで必ず考慮すべき難問ではある。CIS(及びCloudflare)およびDNSの知識を持ち合わせてアプリレベルまで含めて検討が必要である。今回は、移行方法についていくつか考慮事項をまとめてみた。


# 2. ドメインレベルで移行するべきか？FQDNレベルで移行するべきか

すでに、`example.com`というドメインを管理している場合に、もし`www.example.com`というFQDNをCISで保護したい場合は、以下の3つの選択肢がある。

- 案1. `example.com`というドメインをCISに丸ごと移行する。
- 案2. `www.example.com`だけをCISに移行し、それ以外は既存のDNSで管理する(NSレコードで委任）。
- 案3. `www.example.com`だけをCISに移行し、それ以外は既存のDNSで管理する(CNAMEで参照。いわゆる[CNAME Setup](https://qiita.com/testnin2/items/9dbde2a594d571eb56d4)）。



|  | 案1. `example.com`というドメインをCISに丸ごと移行する | 案2. `www.example.com`だけをCISに移行し、それ以外は既存のDNSで管理する(NSレコードで委任）|案3. `www.example.com`だけをCISに移行し、それ以外は既存のDNSで管理する(CNAMEで参照。いわゆる[CNAME Setup](https://qiita.com/testnin2/items/9dbde2a594d571eb56d4)）|
|:-----------|:------------|:------------|:------------|
| DNSレコードの移行  | ドメイン配下の全DNSレコードを移行  | `www.example.com`のみしか移行しない |`www.example.com`のみしか移行しない|
|上位DNSで追加・変更するDNSレコード|NSレコードを`既存のname server`から`CISのname server`に変更|`www`というAレコードをCISのname serverを指すNSレコードに変更。|TXTレコードの追加(Verificationに使用）、`www`というAレコードをCISを指すCNAMEレコードに変更。|
|ドメインのActive化のタイミング|NSレコード更新よるドメイン移行のタイミング|AレコードからNSレコード変更によるドメイン移行のタイミング|TXTレコードによるVerification Code追加のタイミング(CNAMEによる切替え前に実施可能）|
|Edge証明書の作成やCDN/WAFの検証を行えるタイミング|ドメイン移行後に可能。|ドメイン移行後に可能。|ドメイン移行前から可能。|
| セキュリティー | `example.com`配下の全てのドメインがDDoS防御などのセキュリティー機能の恩恵を受けられる。      | `www.example.com`しかセキュリティー機能の恩恵を受けられない       |`www.example.com`しかセキュリティー機能の恩恵を受けられない |
|運用|一回移行が完了すれば、CISのみの管理で良い|移行完了後も、既存DNSとCISの両方の運用が必要。逆にいうとCISへの移行は限定的であるため既存環境への影響は少ない。|移行完了後も、既存DNSとCISの両方の運用が必要。逆にいうとCISへの移行は限定的であるため既存環境への影響は少ない。2022/02/20頃にCISで利用可能であることがわかったため、実績に乏しい。また、（UIでもほとんど動いているように見えるが）厳密にはCLIでのみサポート|


# 3 案１・案２のDNS移行前に、どこまで動作確認ができるか？

過去には、

1.  CISにドメインを登録
2. （上位DNSでNSレコードをCISに変更する前のZoneがPending状態で）DNSやGLBをCISに登録。Proxy Mode=ON(Orange Cloud)を構成。Edge証明書を注文。
3. （上位DNSでNSレコードをCISに変更する前のZoneがPending状態で）テスト端末の/etc/hostsに、「<適当なEdgeのIP> <FQDN>」 を設定してテスト。
4. DNS移行を実施してドメインをActive状態にする。

の流れで事前に稼働確認した上で移行することも可能であった。


しかし、今は挙動が変わっており、ドメインがPending状態でProxyが使えないのであればCDNやWAFや証明書を使ったアクセスを事前に動作確認はできない。よって、まずProxyMode=OFFでDNSをCISに移行してドメインをActive状態にしてからProxyを有効化する必要がある。


## 3-1. ZoneがPendingの状態では、Edge証明書を注文することができない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/cbd9701b-2395-f210-b50a-052a406addb9.png)

ただし、事前に証明書をUploadしておくこと自体は可能のようだ。

https://developers.cloudflare.com/ssl/edge-certificates/universal-ssl/
> By default, Cloudflare issues — and renews — free, unshared, publicly trusted SSL certificates to all domains added to and **activated on Cloudflare**.
> Universal certificates are Domain Validated (DV). For setup details, refer to Enable Universal SSL.
> **If your website or application requires an SSL certificate prior to migrating traffic to Cloudflare, or if you need to customize cipher suites, refer to Advanced or Custom certificates.**


## 3-2. ZoneがPendingの状態では、Proxy=ONにならない。

このドメインに割り当てられているCISのNameServerを使って名前解決しようとすると、以下のように（例えProxy=ONになっているレコードであっても）Edge IPを返さない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/c7d23681-aef9-c69c-3de3-0f5045c65cd0.png)

```
syasuda@ShinobunoMacBook-Pro ~ % dig +noall +ans www1.xxxxx.com @ns020.name.cloud.ibm.com
www1.xxxxx.com.	300	IN	A	<Proxy化されていない元のアドレス>
```

https://developers.cloudflare.com/dns/zone-setups/reference/domain-status
> Pending zones cannot be used to proxy traffic to Cloudflare.


https://developers.cloudflare.com/dns/manage-dns-records/reference/proxied-dns-records#limitations-for-pending-domains
>When your domain status is Pending Nameserver Update, that domain's DNS records cannot yet be proxied.
This means that pending domains cannot take advantage of Cloudflare caching and other settings — even if the proxy status is enabled for their DNS records — and any requests to your DNS records will return your origin server's IP address and not Cloudflare IP addresses.


## 3-3. ZoneがPendingの状態では、WAFの設定できるが、上記のようにProxy=ONにならないので事前の挙動検証はできない。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/7e8092f1-b9ed-08e9-5b79-0f42cbaeee6b.png)


## 3-4. ZoneがPending状態で、無理やりEdgeに対してアクセスを試みた時。


```
syasuda@ShinobunoMacBook-Pro ~ % cat /etc/hosts|grep www1
104.xx.xx.xx www1.xxxxx.com

syasuda@ShinobunoMacBook-Pro ~ % curl http://www1.xxxxx.com
error code: 1001%

syasuda@ShinobunoMacBook-Pro ~ % curl -I http://www1.xxxxx.com
HTTP/1.1 409 Conflict
Date: Mon, 21 Feb 2022 00:25:08 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 16
Connection: close
X-Frame-Options: SAMEORIGIN
Referrer-Policy: same-origin
Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Expires: Thu, 01 Jan 1970 00:00:01 GMT
Server: cloudflare
CF-RAY: 6e0bd5f5e81f34f3-NRT
```

# 4. 最初にDNS移行を完了した後に、CDN/WAF/証明書などをテストする際の流れ

例として、`www.example.com`をCISに委任する場合は以下の流れになる。

## Step 1. 初期状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/bf8470e2-000e-e56f-b5bc-076172841e6a.png)

## Step 2. 事前準備
切り替えをスムーズに行うために、移行元DNSでTTLを短くしておく。CISでドメイン登録し、CISのDNSで既存のWebサーバーにアクセスできるようにAレコードをProxy=Offで登録しておく(ドメインはまだPending状態)。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d5af25bd-a03b-f916-aa63-6879a8bcd5e7.png)

## Step 3. DNSレコードの切り替え
移行元DNSで既存のAレコードを、NSレコードに変更しCISのNameServerを指定する。既存DNSが使われる場合は既存DNSが名前解決してくれるし、CISのDNSが使われた場合はCISのドメインがPending状態であってもProxy=Offであれば名前解決をして既存サーバーのIPアドレスを返してくれるので、クライアントには影響を与えない。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/3cfdb52e-144b-1674-c506-b614c591d1e6.png)

## Step 4. 十分時間が経過した後(=DNS移行が完了し、ドメインがActiveになった状態)
十分時間が経てば、CISのドメインはActive状態になり、全てのリクエストがCIS経由で名前解決される。 <br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/5fa6e381-8037-4d15-52b7-c8a1cdde5547.png)

## Step 5. CDN/WAF/Edge証明書などの事前動作確認
この後は、ドメインがActive状態なので、Edge証明書は作成可能となる。また、サブドメインなどを作成したり、別ホストを登録してWAFやCDNの検証を行う。なお、この状態ではまだwww.example.comに対して名前解決するAレコードがProxy=Offで構成されているが、この状態でもクライアント端末にEdgeIPを登録することでProxy=ONの挙動を確認することができた。



```txt:AレコードがProxy=offのままでアクセスした場合。元のサーバーのIPを使ってアクセスする。
syasuda@ShinobunoMacBook-Pro ~ % curl -I www1.xxxxx.com
HTTP/1.1 200 OK
Date: Tue, 22 Feb 2022 01:18:53 GMT
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/5.4.16
Last-Modified: Tue, 01 Feb 2022 03:17:09 GMT
ETag: "153-5d6ec562aae98"
Accept-Ranges: bytes
Content-Length: 339
Content-Type: text/html; charset=UTF-8
```
 
```txt:AレコードがProxy=offで登録したままだが、/etc/hostsにEdgeIPを登録した場合。EdgeIPを使ってアクセスする。
syasuda@ShinobunoMacBook-Pro ~ % cat /etc/hosts|grep www1
104.xx.xx.xx www1.xxxxx.com

syasuda@ShinobunoMacBook-Pro ~ % curl -I www1.xxxxx.com
HTTP/1.1 200 OK
Date: Mon, 21 Feb 2022 07:47:52 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Last-Modified: Tue, 01 Feb 2022 03:17:09 GMT
Accept-Ranges: bytes
CF-Cache-Status: DYNAMIC
Server: cloudflare
CF-RAY: 6e0e5e7b09e62023-NRT
```

もしくは/etc/hostsを書きたくない場合は(ブラウザを使わずにCLIを使う場合は）、`--resolve`オプションを使うことで以下のようにテストすることもできる。

```txt:AレコードがProxy=offで登録したまま。--resolveオプションを利用。
syasuda@ShinobunoMacBook-Pro ~ % curl -I http://www1.xxxxx.com --resolve www1.xxxxx.com:80:104.xx.xx.xx
HTTP/1.1 200 OK
Date: Tue, 22 Feb 2022 01:42:47 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Last-Modified: Tue, 01 Feb 2022 03:17:09 GMT
Accept-Ranges: bytes
CF-Cache-Status: DYNAMIC
Server: cloudflare
CF-RAY: 6e1485120d6b8a56-NRT
```

## Step 6. 最終移行
Proxyを有効化して最終移行を実施する（CIS上でAレコードのProxyを有効化する。もしくは、GLBを作成してAレコードを削除する。）


- GLB作成には注意。例えば、上記の案2で移行した場合、www.example.comに対して名前解決するAレコードが構成されている。この状態でGLBを作成すると、仮にGLBがdisabled状態であったとしても、GLBのための暗黙的なAレコードも返すようになる（DNSで定義したIPとGLBで構成されるIPの両方が同時に返るようになる）。GLBに移行したい場合は、GLB作成後にDNSで作成したAレコードを削除する必要があるが、そのためにはDNSで作成したAレコードのTTLを事前に短くしておくと良い。CISではProxy=OffのAレコードはUI上では2分が最小だが、以下のようなコマンドでそれ以下にすることが可能。

```
ibmcloud cis instance-set CIS-Enterprise-Usage1
$ ibmcloud cis dns-record-update 3476b3464d25f1ba478e1d0753a34bf7 7102a24680db91ceeb8659e114203e7f --ttl 60
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ddfd6a44-7001-d8c0-f673-0b9e0695d233.png)