AWSとGCP におけるセキュリティの勘所

AWSやGCPを利用する際によく対面するセキュリティ対応について各クラウドでのソリューションを比較しながら、サービスや方針についてまとめました。

# この記事の範囲

- 主に、Webサービス／アプリ開発でのクラウド利用におけるセキュリティについての話がメインです
- PCI DSS とか ISMS とかの難しい話はしません(というかできないよ\\(^o^)/)

# パブリッククラウドにおけるセキュリティ

パブリッククラウドにおいて、まず最初に押さえるべきは「責任分担モデル」です。簡単にいうと、**クラウドサービス自体の運用に関しての責任はクラウドプロバイダが持つ。クラウドサービスの利用の仕方に関する責任は自分たちで持つ。**ってやつです。

これは大体どのプロバイダも一緒なので、覚えておくといいと思います。
![Shared_Responsibility_Model_V2_JP.a4acd9721218c9d7d4ab5083c349e706e8ad300d.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18114/afa81c6f-cab4-1c87-2601-a6ba12a46769.jpeg)
引用: https://aws.amazon.com/jp/compliance/shared-responsibility-model/

どっちに責任があるのかを明確にするのも大事なのですが、自分が一番大事にしたいのは、有事の際に一番困るのは**"自分たちのサービスを利用してくれるユーザー"**ってことです。だからこそ、可用性と共にセキュリティは重要だと考えています。

また、パブリッククラウドのセキュリティに対する考え方は**各プロバイダでホワイトペーパーが出てるので一読しておくのをおすすめ**します。

- [AWSのホワイトペーパー](https://aws.amazon.com/jp/whitepapers/#security)
- [GCPのホワイトペーパー](https://cloud.google.com/security/overview/whitepaper?hl=ja)



# セキュリティ設計・実装パターン比較

## IAM(Identity and Access Management) 権限

IAMは、ここを避けては通れないほど**AWS/GCPともにめちゃくちゃ重要な概念**です。できることはほぼ同じなのですが、用語とコンセプトがやや違うため混乱します。

たとえば、「IAMポリシー」という用語を取ってみても、AWSだと単純に権限を定義するドキュメントで、GCPだと役割とメンバーのバインディングリストだったりします。

AWSからGCPにスイッチする人向けに、権限管理についての比較表があるので抜粋します。

<img width="685" alt="スクリーンショット 2019-09-30 14.36.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18114/7baabd37-356d-88e6-b105-c7040534d878.png">
引用：https://cloud.google.com/docs/compare/aws/management?hl=ja

用語の差異以外にも、「バージョニングの有無」なども気になるポイントです。

### 権限の継承

AWSにおけるIAM権限の継承は、IAMグループにIAMユーザをアタッチすることで、グループの権限をユーザに継承することができます。**継承の仕組みとしてはわかりやすくシンプル**ですね。

- [IAM ユーザーへのアクセス許可を割り当てるためにグループを使用する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#use-groups-for-permissions)


GCPでは「**リソース階層を使用したアクセス制御**」が可能です。これはAWS同様「権限が継承される」仕組みなのですが、**スコープが大きく違います。**

AWSの場合、同じアカウントに閉じられていますが、GCPの場合、GCPプロジェクトの上位リソース（組織やフォルダ）から権限を継承させることができます。

![IAM roles.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18114/d66fe141-39c7-514c-ec1b-e1c605d5ddcd.png)
引用：https://cloudplatform-jp.googleblog.com/2016/04/iam.html

このメリットは、「**権限の一元管理ができる**」ことと、「**権限管理のライフサイクルがプロジェクトに依存しない**」ことだと思います。

権限管理には棚卸しがつきものなので、こういった一括で設定できような仕組みがあるのは助かります。

詳細は、GCPの[リソース階層](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy?hl=ja)を参照してください。


### リソースごとの権限管理

AWSでは、リソースに一意の名前(Amazonリソースネーム)があるので、リソース単位で細かく権限管理することが可能です。

- [Amazon リソースネーム (ARN) と AWS サービスの名前空間](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-arns-and-namespaces.html)


それに比べ、**GCPではリソースレベルで制限できるものが決まっています。**

権限管理ができるリソースとして具体的には、Big Query (Table)、PubSub (Topic)、Cloud Storage (Bucket)、Compute Engine(VM Instance、disk、image)があります。

この思想については、「リソース階層を使用したアクセス制御」のベストプラクティスに以下のように述べられています。

> リソースレベルではなく、組織レベルまたはプロジェクトレベルでポリシーを設定してください。新しいリソースが追加されたとき、それらが親リソースからポリシーを自動的に継承すると便利です。たとえば、新しい仮想マシンが自動スケーリングによってプロジェクトに追加されたときに、それらが自動的にプロジェクトのポリシーを継承するようにします。

引用:https://cloud.google.com/iam/docs/resource-hierarchy-access-control?hl=ja

### IAMベストプラクティス

同じIAMでも、クラウドによって異なるものだということがわかります。なので、それぞれのベストプラクティスに乗っ取る形がおすすめです。

- AWS [IAM のベストプラクティス](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html)
- GCP [IAM ベスト プラクティス ガイドを公開](https://cloudplatform-jp.googleblog.com/2016/04/iam.html)


## Bastion(踏み台)サーバーについて

Bastionサーバーとは、外から接続できないサーバーに対して、メンテなどの目的でSSH/RDPするための"踏み台"として利用するサーバーです。

Bastionサーバーは上げたり落としたりなども検討する必要があるし、セキュリティ的にも気をつかうリソースです。

Bastionサーバーに関しては、3段階でアプローチするとよいと考えています。

1. SSH/RDPでの接続ができないアーキテクチャの検討 
2. Bastionサーバーを立てない 
3. Bastionサーバーを立てる

### SSH/RDPでの接続ができないアーキテクチャを検討する

そもそもBastionサーバーどころか、SSH/RDPが必要なのかどうかから検討するのがおすすめです。おそらく、小さいアプリなどに限られると思いますが、アプリケーションやインフラの要件に合うのであれば、sshできないマネージドサービス(AWS lambda, Cloud Functions, GooleAppEngine StandardEnvironmentなど)を使うなど検討してみましょう。

つまり、「SSHでのアクセスを許容する設定がない」サービスを使うことでオペミスすらできない状態を作ることができます。

### Bastionサーバーを立てない

AWS/GCPともにBastionサーバーを立てずに、SSHできる仕組みがあります。

AWSだと、「[AWS Systems Manager Session Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager.html)」の利用が考えられます。[Plugin](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)を利用すれば、CLIを使ってローカルのMacから接続することもできます。
また、接続して実行するコマンドが決まっている場合は、「[AWS Systems Manager Run Command](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/execute-remote-commands.html)」がおすすめです。

GCPの場合は、「[Cloud Identity-Aware Proxy(IAP)](https://cloud.google.com/iap/docs/concepts-overview?hl=ja)」が利用できます。TCP転送にCloudIAPを利用することで実現可能です。アナウンスはこの[記事](https://cloud.google.com/blog/products/identity-security/cloud-iap-enables-context-aware-access-to-vms-via-ssh-and-rdp-without-bastion-hosts)でドキュメントは[こちら](https://cloud.google.com/iap/docs/using-tcp-forwarding)です。ただ、Cloud IAPはアプリケーションへのアクセスを制御するものなので、社内向けツールなどにアクセス制限ありきのサービスに使われるケースが多いと感じます。

### Bastionサーバーを立てる

Bastionサーバーを立てる方法は、Webに事例がいくつもありますが、一応公式として良さそうなものを載せておきますので参考に構築してください。

- [AWS クラウドでの Linux 踏み台ホスト: クイックスタートリファレンスデプロイ](https://docs.aws.amazon.com/ja_jp/quickstart/latest/linux-bastion/welcome.html)
- [Google Cloud Codelabs and Challenges - Bastion Host](https://codelabs.developers.google.com/codelabs/gcp-infra-bastion-host/index.html?index=..%2F..cloud#0)

## IAMでSSHアクセスを認証する

IAMを使ってSSHアクセスを管理する方法もあります。どちらかというとパブリックなインスタンス向けですが、知っておくと便利に使えます。

AWSでは、「[EC2 Instance Connect](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/Connect-using-EC2-Instance-Connect.html)」が使えます。このサービスは、テンポラリな公開鍵をインスタンス(メタデータ)に登録し、その鍵を使ってSSH接続の認証をするものです。毎回秘密鍵／公開鍵は作り直しになりますが、それらを意識することはほぼ無いので、安全に接続することが可能です。

GCPでは、「[OSログイン](https://cloud.google.com/compute/docs/oslogin/?hl=ja)」を使います。OSログインはIAMを使用してインスタンスへのSSHアクセスを管理できるサービスです。OSログインは、IAM権限で許可するだけでなく、プロジェクトまたはインスタンスへのメタデータ(enable-oslogin=TRUE)の登録により利用可能になります。

## Web Application Firewall

XSSやSQLiへの防御策としての役割です。

AWSでは、「[AWS WAF](https://aws.amazon.com/jp/waf/)」が利用できます。AWS WAFはサードパーティのルール(F5 Web Application CVE Signatures For AWS WAFなど)も適用できたりします。
安いとはいい難いですが、社内でガッツリとWAFを運用できる人材が確保できないなら導入検討の余地はあります。

GCPでは、[Cloud Armor](https://cloud.google.com/armor/?hl=ja)(DoSやウェブ攻撃からの防御)の追加機能としてルールが登録できるようになる予定ですが、**一般的に利用できるようになる時期は未定**です。

[サードパーティーのソリューション](https://cloud.google.com/security/partners/?hl=ja)を利用したり、デプロイ前に[Security Scanner](https://cloud.google.com/security-scanner/?hl=ja)をかけるなど運用でカバーする必要があります。


## DDoS対策

分散型サービス拒否(DDoS)攻撃対策 を見ていきます。それぞれL4レイヤー(一部L7)での防御がメインになり、いわゆるSynフラッドやUDPリフレクション からの防御です。

AWSでは、「[AWS Shield](https://aws.amazon.com/jp/shield/) Standard / Advanced」が利用できます。Advancedは、Standardに加えサポートが手厚く、例えば実際にDDoS攻撃があった場合の「スケーリングへのDDoSコスト保護」など攻撃を受けたときの保険として有効です。

GCPに関しては、特にサービスというわけではなく Global HTTP(S) Load Balancer にBuilt-inされています。またGAE/SEも同様にL4レイヤーでの防御されます。Googleのサービスを守るDDoS対策と聞けば、**その凄さは想像に難くない**ですね。

以下、GCP中の人の[記事から引用](https://medium.com/google-cloud-jp/%E6%96%B0%E3%81%97%E3%81%8F%E5%87%BA%E3%81%9F-cloud-armor-%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F-29885a9432b5)します。

> GCP の Global HTTP(S) LB はネットワークのエッジに存在し、GCP のデータセンタにたどり着くこともなく DDoS 攻撃をエッジでブロックします。なお、この DDoS 対策機能は Google の Search、YouTube や Gmail などにも使用されており、万全な守備となっているかと思います。

また、各社それぞれホワイトペーパー(pdf)がありますので、そちらも参照してください。

- [AWS Best Practices for DDoS Resiliency](https://d1.awsstatic.com/whitepapers/Security/DDoS_White_Paper.pdf)
- [Google Cloud Platform での DDoS 攻撃の防御と軽
減に関するベスト プラクティス](https://cloud.google.com/files/GCPDDoSprotection-04122016.pdf?hl=ja)


## 脆弱性スキャン

### ディストリビューションに対する脆弱性スキャン

AWSだと、「[Amazon Inspector](https://aws.amazon.com/jp/inspector/)」を使います。これは評価ターゲットに対して評価テンプレートを適用し、結果を可視化することができます。
例えば、EC2インスタンス(評価ターゲット)に対して、CVEの脆弱性を検知するための評価テンプレートを適用し、インスタンスの脆弱性を可視化することができます。
しかし、現時点では評価ターゲットはEC2インスタンスのみでコンテナには対応していません。

GCPでは、Google Container Registryの機能のひとつとして[Container Analysis](https://cloud.google.com/container-registry/docs/container-analysis?hl=ja)があります。Debian、Ubuntu、Alpine、Red Hat Enterprise Linux と CentOSに対するCVEの脆弱性をスキャンをすることができます。
しかし、名前からも分かる通りComputeEngineには対応していません。AWSとは逆にインスタンスに対する脆弱性スキャンの仕組みはありません。


### Webアプリケーションに対する脆弱性スキャン

AWSだと、AWS WAFを利用し、ワークロードにおいてルールベースでの防御を実現することは可能ですが、事前にスキャンを実行するようなサービスは現時点ではありません。

GCPでは、[Cloud Web Security Scanner](https://cloud.google.com/security-scanner/using-the-scanner?hl=ja)を使って、脆弱性を事前にスキャンすることが可能です。
ただし、対象はComputeEngine,AppEngine,GKEになり、対応する脆弱性はXSS、Flashインジェクション、混合コンテンツ(http/https)、安全でないJavaScriptライブラリの使用に限られます。

## VPC ネットワークアクセスコントロール

AWSにおける一般的なネットワーク設計の入門資料としては下記資料が参考になります。

- [AWSのネットワーク設計入門](https://d1.awsstatic.com/events/jp/2018/summit/tokyo/aws/07.pdf)

Network ACL + Security Group での制御するのが基本で、Subnet構成やRoutingを工夫したりすることで実装します。

GCPはデフォルトでグローバルなネットワークが使えることがポイントですが、アクセスコントロール関しては、グローバルもローカルを特に意識せず[VCPファイアウォールルール](https://cloud.google.com/vpc/docs/firewalls?hl=ja) で制御します。 またファイアウォールルールは GAE/SEにも存在しますが、VPCのものとは別なので注意が必要です。

VPCファイアウォールルールで特徴的なのは、[暗黙のルール](https://cloud.google.com/vpc/docs/firewalls?hl=ja#default_firewall_rules)が存在することです。何も設定しないと、上り(inbound)は全て拒否、下り(outbound)は全て許可になっています。また、常に許可/拒否されるルールとして、「TCP ポート 25(SMTP)での下りトラフィック は拒否」だったり、「DHCP, NTP, メタデータサーバー (169.254.169.254) は許可」だったり、**暗黙のルールは厳密に制限したい場合には注意が必要**です。

## 秘匿情報の管理

APIシークレットなどをどのように保存するかについて考えます。

[SOPS](https://github.com/mozilla/sops)などを使って暗号化してリポジトリに含める方法もありますが、できればクラウドのサービスでなんとかしたいですよね。

AWSだと、[AWS Systems Manager パラメータストア](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html)のSecure Stringを利用するケースが多いと思います。似たようなサービスで、ライフサイクル管理が必要であれば[AWS シークレットマネージャー](https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/intro.html)もあります。一般的には前者を利用することが多いと思いますが、DBのパスワードを定期的に変更したいような監査的なワークロードがある場合は後者を利用します。

一方、GCPでは現時点では便利に使えるサービスというものはありません。
KMS + Cloud Storageがよくあるパターンだと思いますが、そこらへんをまるっとやってくれるOSS([berglas](https://github.com/GoogleCloudPlatform/berglas))をGCPが提供していたりします。

# まとめ

いろいろと見てきましたが、それぞれ特徴があっておもしろいですね。

個人的にクラウドにおけるセキュリティへの意識は、以下３つに集約されるのかなと思っています。

#### 1.トレードオフを意識する

全部やれるにこしたことはないですが、コスト（実装、運用、リソース使用量）をきちんと検討したうえで、トレードオフがあることを意識しましょう。

#### 2.守らなくて良いように設計する

開けなくて良い穴は開けない。やらなくていいことはやらない。たとえば、Bastionサーバーの必要是非など。オペミスできないように設計することも検討しましょう。

#### 3.クラウドらしさを忘れずに

クラウドらしい使い方として、マネージド・サービスを積極的に利用したり、調達コストを低く保ち、自動化を推進していきましょう。

### 最後に

セキュリティは、納期ドリブン開発のときは放置されることも多々あるかと思いますが、**手軽にやれることもたくさんある**ので、できるだけ後回しにしないようにすることが大切だと考えています。
セキュアな環境を継続的に保つためにクラウドっぽく自動化し、より安全なサービスを提供できるといいですね。

この記事が、みなさんの勘所になれば幸いです:grinning:

最後に、セキュリティ云々の前に「**ログはとにかく取っておく**」のを忘れずに！