主要クラウドサービスの公開 IP アドレスレンジ（AWS/Azure/GCP/OracleCloud）

## はじめに
ネットワーク制限が厳しい環境などで明示的に通信許可を設定する場合などに、主要なクラウドサービスが所有しているパブリック IP アドレスの範囲を確認したい時があります。
そこで、主要なクラウドサービスが保持する IP アドレスリストを取得する方法について調査し整理しておきます。

## Amazon Web Service(AWS)
AWS では、JSON 形式でリストを公開しています。

 AWS IP アドレスの範囲
 https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-ip-ranges.html

次のエンドポイントで最新の IP アドレスリストを取得することができるため、定期的に参照するのが良いと思われます。

 AWS ip-ranges.json 
 https://ip-ranges.amazonaws.com/ip-ranges.json

なお、createDate の項目が更新日時のため、プログラムなどで自動参照する際は、更新時に最新を取り込むようにするのが良いでしょう。

```json

{
  "syncToken": "1576148589",
  "createDate": "2019-12-12-11-03-09",
  "prefixes": [
    {
      "ip_prefix": "13.248.118.0/24",
      "region": "eu-west-1",
      "service": "AMAZON"
    },
    {
      "ip_prefix": "18.208.0.0/13",
      "region": "us-east-1",
      "service": "AMAZON"
    },
    ~以下略〜
```

## Microsoft Azure 
Microsoft Azure も JSON 形式で IP アドレスのリストを提供しています。リストのファイルは以下からダウンロードすることができます。

 Azure IP Ranges and Service Tags – Public Cloud 
 https://www.microsoft.com/en-us/download/details.aspx?id=56519

ファイルのダウンロード URL は更新ごとに変わるためプログラムなどから参照する場合は、URL 固定の RESTエンドポイントが別に存在しています。サンプルコマンドは以下で説明されていますが、POST でリストを取得することができます。

 Azure: Get Datacenter IP address ranges via API
 https://social.technet.microsoft.com/wiki/contents/articles/50886.azure-get-datacenter-ip-address-ranges-via-api.aspx

```powershell
$body = @{"region"="all";"request"="dcip"} | ConvertTo-Json
$webrequest= Invoke-WebRequest -Method “POST” -uri `https://azuredcip.azurewebsites.net/api/azuredcipranges -Body $body
```

しかし、上記のエンドポイントでは、リージョン毎のIPレンジはわかりますが、VM、ストレージなどのサービス毎のレンジはわかりません。それは別になっているようで、次の API で参照できます。

 Service Tags - List
 https://docs.microsoft.com/en-us/rest/api/virtualnetwork/servicetags/list

## Google Cloud Platform(GCP)
GCPでは、パブリック IP アドレスのリストは _cloud-netblocks.googleusercontent.com の SPF レコードとして公開されています。

```sh
$ dig @8.8.8.8 -t TXT _cloud-netblocks.googleusercontent.com

; <<>> DiG 9.10.6 <<>> @8.8.8.8 -t TXT _cloud-netblocks.googleusercontent.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5516
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;_cloud-netblocks.googleusercontent.com.	IN TXT

;; ANSWER SECTION:
_cloud-netblocks.googleusercontent.com.	3599 IN	TXT "v=spf1 include:_cloud-netblocks1.googleusercontent.com include:_cloud-netblocks2.googleusercontent.com include:_cloud-netblocks3.googleusercontent.com include:_cloud-netblocks4.googleusercontent.com include:_cloud-netblocks5.googleusercontent.com ?all"

;; Query time: 46 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Dec 14 21:27:37 JST 2019
;; MSG SIZE  rcvd: 331
```

上記で応答されたドメイン（_cloud-netblocks1.googleusercontent.com、_cloud-netblocks2.googleusercontent.com、_cloud-netblocks3.googleusercontent.com、_cloud-netblocks4.googleusercontent.com、_cloud-netblocks5.googleusercontent.com）のTXTレコードを取得します。

```sh
$ dig @8.8.8.8 -t TXT _cloud-netblocks1.googleusercontent.com

; <<>> DiG 9.10.6 <<>> @8.8.8.8 -t TXT _cloud-netblocks1.googleusercontent.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31299
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;_cloud-netblocks1.googleusercontent.com. IN TXT

;; ANSWER SECTION:
_cloud-netblocks1.googleusercontent.com. 3599 IN TXT "v=spf1 include:_cloud-netblocks6.googleusercontent.com include:_cloud-netblocks7.googleusercontent.com ip4:8.34.208.0/20 ip4:8.35.192.0/21 ip4:8.35.200.0/23 ip4:108.59.80.0/20 ip4:108.170.192.0/20 ip4:108.170.208.0/21 ?all"

;; Query time: 40 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sat Dec 14 21:29:06 JST 2019
;; MSG SIZE  rcvd: 303
```

次のように、その時点の IP レンジが応答されます。
ip4:8.34.208.0/20 ip4:8.35.192.0/21 ip4:8.35.200.0/23 ip4:108.59.80.0/20 ip4:108.170.192.0/20 ip4:108.170.208.0/21 ?all"

今現在(2019/12)では、次の範囲が含まれているようです。

```
104.154.0.0/15
104.196.0.0/14
107.167.160.0/19
107.178.192.0/18
108.170.192.0/20
108.170.208.0/21
108.170.216.0/22
108.170.220.0/23
108.170.222.0/24
108.59.80.0/20
130.211.128.0/17
130.211.16.0/20
130.211.32.0/19
130.211.4.0/22
130.211.64.0/18
130.211.8.0/21
146.148.16.0/20
146.148.2.0/23
146.148.32.0/19
146.148.4.0/22
146.148.64.0/18
146.148.8.0/21
162.216.148.0/22
162.222.176.0/21
173.255.112.0/20
192.158.28.0/22
199.192.112.0/22
199.223.232.0/22
199.223.236.0/23
208.68.108.0/23
23.236.48.0/20
23.251.128.0/19
34.100.0.0/16
34.102.0.0/15
34.104.0.0/14
34.124.0.0/18
34.64.0.0/11
34.96.0.0/14
35.184.0.0/14
35.188.0.0/15
35.190.0.0/17
35.190.128.0/18
35.190.192.0/19
35.190.224.0/20
35.190.240.0/22
35.192.0.0/14
35.196.0.0/15
35.198.0.0/16
35.199.0.0/17
35.199.128.0/18
35.200.0.0/13
35.208.0.0/13
35.216.0.0/15
35.220.0.0/14
35.224.0.0/13
35.232.0.0/15
35.234.0.0/16
35.235.0.0/17
35.235.192.0/20
35.235.216.0/21
35.235.224.0/20
35.236.0.0/14
35.240.0.0/13
8.34.208.0/20
8.35.192.0/21
8.35.200.0/23
```

RESTなどのエンドポイントは提供されていないようなので、プログラムから参照する際は、DNSクエリを再帰的に呼び出す必要がありちょっと手間な気がします。

　Compute Engine の IP 範囲はどこで確認できますか？
　https://cloud.google.com/compute/docs/faq#find_ip_range

## Oracle Cloud 
Oracle Cloud でも JSON 形式でリストを公開しています。

　Oracle Cloud - IP Address Ranges
　https://docs.cloud.oracle.com/iaas/Content/General/Concepts/addressranges.htm

次のエンドポイントで最新の IP アドレスリストを取得することができるため、定期的に参照するのが良いと思われます。

　https://docs.cloud.oracle.com/iaas/tools/public_ip_ranges.json

また、last_updated_timestamp がリストの最終更新日時のため、この値が更新されているかを確認すると良いでしょう。

```sh
{
    "last_updated_timestamp": "2019-12-05T17:08:50.165960",
    "regions": [
        {
            "region": "us-phoenix-1",
            "cidrs": [
                {
                    "cidr": "129.146.0.0/21",
                    "tags": [
                        "OCI"
                    ]
             ~以下略〜
```

## Github
パブリッククラウドではないですが、Github も IPアドレスを公開しています。

　GitHubのIPアドレスについて
　https://help.github.com/ja/github/authenticating-to-github/about-githubs-ip-addresses

次のエンドポイントで最新の IP アドレスリストを取得することができます。
https://api.github.com/meta