無理しない範囲でCompute Engineに対して多層防御アプローチ導入を行う

# はじめに

セキュリティ対応はいつの時代でも課題となります。セキュリティに対してのアプローチとして多層防御といった考え方があります。
IT用語辞典e-Wordでは[このように](https://e-words.jp/w/%E5%A4%9A%E5%B1%A4%E9%98%B2%E5%BE%A1.html)記載されています

>多層防御とは、企業などの組織における情報セキュリティの対策方針の一つで、システム内の複数の構成要素や攻撃者の活動の複数の局面に対して、何重にも防御策を講じること。
>一般的な方針としては、入口対策、内部対策、出口対策の三階層で防御することが多い

Google Cloudでも多層防御を用いてセキュリティを担保することをテーマとした[ブログ記事](https://cloud.google.com/blog/ja/products/identity-security/preventing-lateral-movement-in-google-compute-engine)があったりします。
しかしできる限りやりたくても組織権限対応を行ったりする必要があり手軽には行いにくいです。
開発環境でサクッと作りたいが、ある程度のセキュリティは気にしておきたい！って時に全部の対応を行うとスピード感が出なかったりします。
そこで今回は**無理しない範囲で**、**比較的面倒なことをせずに**Compute Engineに対して多層防御アプローチ導入を行います（コマンド実行可能なものはサンプルコマンドも記載します）

# 多層防御アプローチの導入
## 具体的にどの範囲を行う？

先程のブログ記事では下記内容が記載されています

>Compute Engine に多層防御アプローチを導入するには、以下のことを実施する必要があります。
>
>- 本番環境リソースをインターネットから切り離す
>- デフォルト サービス アカウントを無効にする
>- サービス アカウントの認証情報へのアクセスを制限する
>- OS Login を使用して VM へのアクセスを管理する
>- 最小権限の原則を適用する
>- ログを収集してシステムをモニタリングする 

今回は手軽にできる範囲として3つの内容をピックアップします。アプローチとしては上記ブログに記載されている内容含めて下記で対応していきます。

- 本番環境リソースをインターネットから切り離す
    - Identity-Aware Proxyを利用
- デフォルト サービス アカウントを無効にする
    - サービスアカウントの無効化コマンドの実施
    - VMインスタンスに利用するサービスアカウントの作成
- サービス アカウントの認証情報へのアクセスを制限する
    - --impersonate-service-accountオプションを利用

## 本番環境リソースをインターネットから切り離す

VMインスタンスのグローバルIPを付与せず利用しましょうといった内容です。
プロジェクトレベルの対応で簡単として、[Identity-Aware Proxy](https://cloud.google.com/iap?hl=ja)（以下IAP）を利用する方法があります。

IAPを利用することで、Google Cloud上の許可されたユーザのみがアクセス可能となります。

IAP設定は下記コマンドを実行することで、IAPからSSH接続とRDP接続を許可するFWルール設定ができます。

```
gcloud compute firewall-rules create allow-iap-rules \
  --network=[ネットワーク名] \
  --description="Allow IAP firewall rules(SSH and RDP)" \
  --direction=INGRESS \
  --action=allow \
  --rules=tcp:22,tcp:3389 \
  --source-ranges=35.235.240.0/20
```

実行例

```
$ gcloud compute firewall-rules create allow-iap-rules \
  --network=default \
  --description="Allow IAP firewall rules(SSH and RDP)" \
  --direction=INGRESS \
  --action=allow \
  --rules=tcp:22,tcp:3389 \
  --source-ranges=35.235.240.0/20
Creating firewall...working..Created [https://www.googleapis.com/compute/v1/projects/[プロジェクトID]/global/firewalls/allow-iap-rules].
Creating firewall...done.
NAME: allow-iap-rules
NETWORK: default
DIRECTION: INGRESS
PRIORITY: 1000
ALLOW: tcp:22,tcp:3389
DENY:
DISABLED: False
```

実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283423/15a9dd45-83f9-33ee-7748-558ad15a55dd.png)

IAPは利用時に `IAPで許可されたトンネルユーザー（roles/iap.tunnelResourceAccessor）` が必要となりますのでご注意ください。
権限付与コマンドは以下の通りです

```
gcloud projects add-iam-policy-binding [プロジェクトID] \
    --member=user:[ユーザアドレス] \
    --role=roles/iap.tunnelResourceAccessor
``` 

## デフォルト サービス アカウントを無効にする

VM作成時、通常下記画像のように `Compute Engine default service account` が設定されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283423/946dd50e-de06-f658-583c-d1a0e79d2608.png)

こちらのアカウントは編集者権限が付与されており、例えばGCSのバケット一覧を見る作業を行う場合は権限が過剰に付与されています。
このようなロールはGoogle Cloud上の方針としては権限付与をしないことが望ましいです。そのため権限を変更するか、別のサービスアカウントを作成して指定することが望ましいです。

今回はデフォルトのサービスアカウントを無効化し、新規サービスアカウントを作成するようにします。

サービスアカウント無効化は下記コマンドを実行することで対応可能となります。

```
gcloud iam service-accounts disable [プロジェクト番号]-compute@developer.gserviceaccount.com
```

実行例

```
$ gcloud iam service-accounts disable 870556926684-compute@developer.gserviceaccount.com
Disabled service account [870556926684-compute@developer.gserviceaccount.com].
```

また新規サービスアカウント作成は下記コマンドで実行可能です

```
gcloud iam service-accounts create [サービスアカウント名] \
    --description="service account for mv instance" \
    --display-name="[サービスアカウント名]"
```

実行例

```
$ gcloud iam service-accounts create test-sa \
    --description="service account for mv instance" \
    --display-name="test-sa"
Created service account [test-sa].
```

実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283423/07a88b7c-7578-9718-de1e-4d174102097d.png)


## サービス アカウントの認証情報へのアクセスを制限する

先程作成したサービスアカウントを利用して作業をする場合、サービスアカウントキーを作成してコマンドを実行するパターンがあります。
しかしなりすましの可能性もあるため、サービスアカウントの認証制限が必要となります。

今回は `--impersonate-service-account` オプションを利用して認証を行います。
権限として `サービス アカウント トークン作成者（roles/iam.serviceAccountTokenCreator）` が必要となります。


権限付与後、下記コマンドを実行することで権限拝借が可能となります。


```
gcloud config set auth/impersonate_service_account [サービスアカウント名]
```

実行例

```
$ gcloud config set auth/impersonate_service_account test-sa@[プロジェクトID].iam.gserviceaccount.com
```

実行結果

```
$ gcloud config list
[accessibility]
screen_reader = True
[auth]
impersonate_service_account = test-sa@[プロジェクトID].iam.gserviceaccount.com
[component_manager]
disable_update_check = True
[compute]
gce_metadata_read_timeout_sec = 30
[core]
account = [ユーザアドレス]
disable_usage_reporting = True
project = [プロジェクトID]
[metrics]
environment = devshell
```

# まとめ

今回紹介した内容は一部でも導入することで、セキュリティレベルを向上することは可能です。
もちろん紹介しなかった3点の内容も実施すればさらなるセキュリティレベルの向上となります。
今回の内容は比較的簡単に実施でき、なおかつセキュリティも担保できるためぜひご活用ください。