ICOS Firewallを使ったアクセス制御


1. ICOS Firewallとは

ICOS(IBM Cloud Object Storage)にFirewallがGAされました。ドキュメントはこちら。以下の特徴があります。

  • 旧SoftLayerポータル(https://control.softlayer.com) から購入したICOSでは利用不可。https://cloud.ibm.com から購入したICOSでのみ利用可能。
  • whitelist方式(指定したIP subnetからのアクセスのみを許し、それ以外からのアクセスは禁じる)。ICOS Firewallの設定がない場合は、全てのsubnetからのアクセスを許可します。
  • IPv4/IPv6に対応
  • bucketごとのルール指定
  • 無償
  • 設定にはIAMのManager権限が必要
  • Customer Portalから容易に設定可能

既知の制約として、もしIBM CloudのAsperaやSQL Queryなどのサービスまでも、(このwhitelistに列挙していない限りは)ブロックしてしまうことです。一般的にIBM Cloudのサービスの発信元IPアドレスは公開しておらず確認する方法がないため、「自社からのIPアドレス+SQL Queryのみをアクセス許可する」といった使い方は難しいでしょう。サービス連携機能を高めるためには、引き続きの改善が待たれるところです。

2. 検証準備

ICOSのオブジェクトへのcurlでのアクセス方法はここを参照してください。

  • Public Access curl https://s3.private.jp-tok.cloud-object-storage.appdomain.cloud/<bucket>/<object-key> -H "Authorization: bearer $ACCESS_TOKEN"
  • Private Access curl https://s3.private.jp-tok.cloud-object-storage.appdomain.cloud/<bucket>/<object-key> -H "Authorization: bearer $ACCESS_TOKEN"

IAM Tokenの取得方法はここを参照してください。

3. 検証

3-1. Private NWからしかアクセスさせない

ICOS Firewallに10.0.0.0/8のみを登録し、IBM CloudにあるVSIからアクセスしてみます。(IBM CloudのVSIはPublic IPとしてGlobal IPを持ち、Private IPとして10.0.0.0/8上のIPを持っています)

PublicEndpoint経由でのアクセス(PublicIPを使ってアクセスするので失敗)
# curl https://s3.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: bearer $ACCESS_TOKEN"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message><Resource>/mybucketxxx/index.html</Resource><RequestId>2deef42e-372b-46ef-abbb-6eaac9ab5cc1</RequestId><httpStatusCode>403</httpStatusCode></Error>
PrivateEndpoint経由でのアクセス(10.x.x.xのPrivateIPを使ってアクセスに成功)
# curl https://s3.private.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: bearer $ACCESS_TOKEN"
Hello World

3-2. 特定のPrivate IPからしかアクセスさせない

ICOS FirewallにIBM CloudにあるVSIのPrivate IPのみを指定し、それ以外のアドレスからのアクセスを禁じてみます。

VSIからPublicEndpoint経由でのアクセス(PublicIPを使ってアクセスするので失敗)
# curl https://s3.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: beaCCESS_TOKEN"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message><Resource>/mybucketxxx/index.html</Resource><RequestId>af382318-f8f6-440d-a6d3-c5ece5c9a8dc</RequestId><httpStatusCode>403</httpStatusCode></Error>
VSIからPrivateEndpoint経由でのアクセス(ICOSFirewallで指定したPrivateIPを使ってアクセスするので成功)
# curl https://s3.private.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: bearer $ACCESS_TOKEN"
Hello World!
別のVSIからPrivateEndpoint経由でのアクセス(ICOSFirewallで指定していないPrivateを使ってアクセスするので失敗)
# curl https://s3.private.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: bearer $ACCESS_TOKEN"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message><Resource>/mybucketxxx/index.html</Resource><RequestId>a17f2ce6-5a8f-4008-8a38-605c22fb83f0</RequestId><httpStatusCode>403</httpStatusCode></Error>

3-3. 特定のGlobal IP(Public IP)からしかアクセスさせない

今回のテストに利用したIBM Cloud上のVSIのIPアドレスはAA.AA.AA.AAであったため、これをwhitelistに追加します。その他のIPアドレスからのアクセスは禁じます。

VSIからPublicEndpoint経由でのアクセス(ICOSFirewallで指定したPublicIPを使ってアクセスするので成功)
# curl https://s3.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: bearer $ACCESS_TOKEN"
Hello World
VSIからPrivateEndpoint経由でのアクセス(ICOSFirewallにPrivateIPを登録していないので失敗)
# curl https://s3.private.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: bearer $ACCESS_TOKEN"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message><Resource>/mybucketxxx/index.html</Resource><RequestId>1e347877-a4a8-42b1-9768-3432dc0718eb</RequestId><httpStatusCode>403</httpStatusCode></Error>
VSI以外のサーバーからPublicEndpoint経由でのアクセス(ICOSFirewallに登録したPublicIPを利用していないので失敗)
# # curl https://s3.jp-tok.cloud-object-storage.appdomain.cloud/mybucketxxx/index.html -H "Authorization: bearer $ACCESS_TOKEN"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message><Resource>/mybucketxxx/index.html</Resource><RequestId>c90d9189-6010-4ab2-87f1-17d0e78af988</RequestId><httpStatusCode>403</httpStatusCode></Error>