ICOS Firewallを使ったアクセス制御（アドバンスト編）

#1. はじめに
昔、[ICOS Firewallを使ったアクセス制御](https://qiita.com/testnin2/items/0d23bb5b46f32e45eeb3)という記事を書いたことがあるが、その記事ではアクセスを許可するIPアドレスレンジをUIから指定することで通信制御をするというものであった。

このままでも十分に役に立つFirewall機能だが、ICOSのResource ConfigurationのAPIを調べてみると、APIを使えばさらに細かい指定ができることに気がついた。APIによってICOS Firewallでは

- `allowed_ip`: アクセス許可するIPアドレス・サブネットのリストを指定する（この項目がUIから指定できる内容に等しい）
- `denied_ip`: アクセス禁止するIPアドレス・サブネットのリストを指定する
- `allowed_network_type`: 以下の3つを指定できる。
    - `public`: public endpointを利用
    - `private`: private endpointを利用（主にClassic Infrastuctureで利用するprivate NW側のエンドポイント）
    - `direct`: direct endpointを利用（主にVPCで利用するprivate NW側のエンドポイント）

を組み合わせて指定できるので試してみる。

https://cloud.ibm.com/apidocs/cos/cos-configuration#getbucketconfig
https://cloud.ibm.com/apidocs/cos/cos-configuration#updatebucketconfig

#2. 環境変数の設定と初期状態の確認

[この記事](https://qiita.com/testnin2/items/3a4ca8a1a2b79b713c48)を参照してIAMトークンを取得する。また、Bucket名も環境変数で指定しておくことで、以下が汎用的にスクリプト実行できるようにした。

```shell:環境変数の設定
$ export MYBUCKET=<自分のICOS bucket名>
$ export ACCESS_TOKEN=`ibmcloud iam oauth-tokens | awk '{printf $4}'`
```

また、以下で初期化できるので、途中でうまく行かなくなったり戻せなくなったら実行してみると良い。

```shell:初期状態に戻す
$ curl -X PATCH https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN" -d '{"firewall": {"allowed_ip":[], "denied_ip":[], "allowed_network_type":[]}}'

$ curl -s https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN"|jq
{
  "name": "(bucket名)",
  "service_instance_id": "2c66d594-86d5-4a50-ba34-cedb18fe3126",
  "time_created": "2021-03-19T02:07:15.431Z",
  "time_updated": "2021-03-22T12:09:07.476Z",
  "object_count": 1,
  "bytes_used": 11,
  "crn": "（省略）",
  "service_instance_crn": "（省略）"
}
```

また、ICOSへのpublic/private/directアクセスの実行例は以下の通り。

- [endpoint情報](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-endpoints)
- 検証にはus-southにあるbucketを利用し、あらかじめ`index.html`というファイルを配置しておいた。

```shell:public_private_directアクセス
#public endpointへのアクセス
$ curl -I https://s3.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 200 OK
Date: Mon, 22 Mar 2021 12:11:37 GMT
X-Clv-Request-Id: c7043305-f8b7-4108-b093-ae34336a82ed
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: c7043305-f8b7-4108-b093-ae34336a82ed
ETag: "5eb63bbbe01eeed093cb22bb8f5acdc3"
Content-Type: text/html
Last-Modified: Fri, 19 Mar 2021 02:09:46 GMT
Content-Length: 11


#private endpointへのアクセス
$ curl -I https://s3.private.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 200 OK
Date: Mon, 22 Mar 2021 12:10:44 GMT
X-Clv-Request-Id: 23e1caa0-8f00-4dbd-9774-2489b4047f49
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: 23e1caa0-8f00-4dbd-9774-2489b4047f49
ETag: "5eb63bbbe01eeed093cb22bb8f5acdc3"
Content-Type: text/html
Last-Modified: Fri, 19 Mar 2021 02:09:46 GMT
Content-Length: 11

#direct endpointへのアクセス
$ curl -I https://s3.direct.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 200 OK
Date: Mon, 22 Mar 2021 12:13:13 GMT
X-Clv-Request-Id: da31e7fa-659f-4503-a96f-0520f9ee9079
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: da31e7fa-659f-4503-a96f-0520f9ee9079
ETag: "5eb63bbbe01eeed093cb22bb8f5acdc3"
Content-Type: text/html
Last-Modified: Fri, 19 Mar 2021 02:09:46 GMT
Content-Length: 11
```

#3. テスト 
##3-1. public endpointの利用禁止

`allowed_network_type`に`private`と`direct`のみ構成することで、public endpointが利用できなくなることを確認。

```shell:
$ curl -X PATCH https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN" -d '{"firewall": {"allowed_ip":[], "denied_ip":[], "allowed_network_type":["private","direct"]}}'
$ curl -s https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN"|jq
{
  "firewall": {
    "allowed_network_type": [
      "private",
      "direct"
    ]
  },
  "crn": "省略",
  "service_instance_crn": "省略"
}

#public endpointへのアクセス
$ curl -I https://s3.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 403 Forbidden
Date: Mon, 22 Mar 2021 12:15:48 GMT
X-Clv-Request-Id: db90992e-fa08-4b86-8ddf-91453cbd7e90
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: db90992e-fa08-4b86-8ddf-91453cbd7e90
Content-Type: application/xml
Content-Length: 279

#private endpointへのアクセス
$ curl -I https://s3.private.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 200 OK
Date: Mon, 22 Mar 2021 12:15:55 GMT
X-Clv-Request-Id: aeff2545-01f5-40b8-bc6c-12befc0bb22e
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: aeff2545-01f5-40b8-bc6c-12befc0bb22e
ETag: "5eb63bbbe01eeed093cb22bb8f5acdc3"
Content-Type: text/html
Last-Modified: Fri, 19 Mar 2021 02:09:46 GMT
Content-Length: 11

#direct endpointへのアクセス
$ curl -I https://s3.direct.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 200 OK
Date: Mon, 22 Mar 2021 12:16:02 GMT
X-Clv-Request-Id: e5c70f37-6aff-4609-9454-a404b8528c72
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: e5c70f37-6aff-4609-9454-a404b8528c72
ETag: "5eb63bbbe01eeed093cb22bb8f5acdc3"
Content-Type: text/html
Last-Modified: Fri, 19 Mar 2021 02:09:46 GMT
Content-Length: 11
```

##3-2. 10.200.0.0/24からのアクセスを許可
アクセス試行するサーバーのIPアドレスは10.212.15.57であり、allowed_ipに含まれていないためアクセスができなくなる。

```shell
$ curl -X PATCH https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN" -d '{"firewall": {"allowed_ip":["10.200.0.0/24"], "denied_ip":[], "allowed_network_type":[]}}'

$ curl -s https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN"|jq
{
  "firewall": {
    "allowed_ip": [
      "10.200.0.0/24"
    ]
  },
  "crn": "（省略）",
  "service_instance_crn": "（省略）"
}

#10.212.15.57からのアクセス試行（アクセスできない）
$ curl -I https://s3.private.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 403 Forbidden
Date: Mon, 22 Mar 2021 12:21:27 GMT
X-Clv-Request-Id: 0ec0681e-857c-48ab-91ea-42b6a573b01a
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: 0ec0681e-857c-48ab-91ea-42b6a573b01a
Content-Type: application/xml
Content-Length: 279
```
##3-3. 10.212.15.0/24からのアクセスを許可

アクセス試行するサーバーのIPアドレスは10.212.15.57であり、allowed_ipに含まれているためアクセスができる。

```shell
$ curl -X PATCH https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN" -d '{"firewall": {"allowed_ip":["10.212.15.0/24"], "denied_ip":[], "allowed_network_type":[]}}'

$ curl -s https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN"|jq
{
  "firewall": {
    "allowed_ip": [
      "10.212.15.0/24"
    ]
  },
  "crn": "（省略)",
  "service_instance_crn": "（省略)"
}

#10.212.15.57からのアクセス試行（アクセスできる）
$ curl -I https://s3.private.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 200 OK
Date: Mon, 22 Mar 2021 12:23:18 GMT
X-Clv-Request-Id: 822c3eca-6ff0-404b-970c-b67910332c2d
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: 822c3eca-6ff0-404b-970c-b67910332c2d
ETag: "5eb63bbbe01eeed093cb22bb8f5acdc3"
Content-Type: text/html
Last-Modified: Fri, 19 Mar 2021 02:09:46 GMT
Content-Length: 11
```

##3-4 10.212.15.0/24からのアクセスを許可。ただし、10.212.15.57からは禁止。

アクセス試行するサーバーのIPアドレスは10.212.15.57であり、allowed_ipに含まれているが、denied_ipにも指定されているためアクセスができない。

```shell
$ curl -X PATCH https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN" -d '{"firewall": {"allowed_ip":["10.212.15.0/24"], "denied_ip":["10.212.15.57"], "allowed_network_type":[]}}'

$ curl -s https://config.cloud-object-storage.cloud.ibm.com/v1/b/$MYBUCKET -H "authorization: bearer $ACCESS_TOKEN"|jq
{
  "firewall": {
    "allowed_ip": [
      "10.212.15.0/24"
    ],
    "denied_ip": [
      "10.212.15.57"
    ]
  },
  "crn": "（省略)",
  "service_instance_crn": "（省略)"
}

#10.212.15.57からのアクセス試行（アクセスできない）
$ curl -I https://s3.private.us-south.cloud-object-storage.appdomain.cloud/$MYBUCKET/index.html -H "authorization: bearer $ACCESS_TOKEN"
HTTP/1.1 403 Forbidden
Date: Mon, 22 Mar 2021 12:25:48 GMT
X-Clv-Request-Id: 48f52b5d-ffc5-40d3-af22-8d676796f405
Server: Cleversafe
X-Clv-S3-Version: 2.5
Accept-Ranges: bytes
x-amz-request-id: 48f52b5d-ffc5-40d3-af22-8d676796f405
Content-Type: application/xml
Content-Length: 279

```