ForsetiSecurityをデプロイしてみた話

ForsetiSecurityとは?

GoogleとSpotifyが共同開発中オープンソースのGCPリソースセキュリティ確保のためのツールです。

概要や思想はGoogle Cloud Platform Blogに記述がありますので、こちらを参考にすると良いでしょう。

Forsetiには上記ブログからそのまま引用すると、次のような機能があります。

Inventory : 既存の GCP リソースを可視化します。
Scanner : GCP リソース全体のアクセス制御ポリシーが適切かどうかをチェックします。
Enforcer : GCP リソースに対する問題のあるアクセスを取り除きます。
Explain : GCP リソースに対して誰がどのようなアクセス権限を持つかを分析します。

Enforcer, Explainに関しては現状ほとんど実装されていない状態なので、InventoryとScannerの機能を使ってポリシー違反を検知できるようにしたいと思います。

ForsetiSecurityをデプロイする

現状、ForsetiSecurityはDeployment Managerを使ってデプロイされているので、作業後綺麗に掃除するためにはDeployment Mangerの扱いを知っている必要があります。 また、今後バージョンアップ等で汚れていく可能性があるので、自社で管理している組織配下にForsetiSecurity用のプロジェクトを作成してデプロイすることをお勧めします。

Forsetiをデプロイするにあたり必要な権限

  • Resource Manager/Org Admin

つまり、上記権限を持っていない組織に対してはScanできないということになりますが、弊社環境で複数組織での確認は取れていませんので悪しからず。

通知を受け取るために必要なもの

  • SendGridアカウント

必要な情報

  • SendGrid API Key
  • Forsetiからのメールを受け取るメールアドレス
  • Super Admin email address

forseti-security サービスアカウント作成

PROJECT_ID=<YOUR PROJECT ID>
gcloud config set project ${PROJECT_ID}
SANAME=forseti-security
gcloud iam --project ${PROJECT_ID} service-accounts create ${SANAME} \
--display-name "Service account for Forceti Security."

確認

gcloud iam --project ${PROJECT_ID} service-accounts list

forseti-security サービスアカウントに必要な権限を付与

付与できる権限の一覧取得

gcloud iam --project ${PROJECT_ID} list-grantable-roles //cloudresourcemanager.googleapis.com/projects/${PROJECT_ID}

現状のIAMポリシーファイルを取得

gcloud projects get-iam-policy ${PROJECT_ID} --format json > iam.json

IAMポリシーを変更

出力されたポリシーファイルを修正したのち

gcloud projects set-iam-policy ${PROJECT_ID} iam-inventory.json

APIを有効化

# Admin SDK API
gcloud beta --project ${PROJECT_ID} service-management enable admin.googleapis.com
# Cloud Resource Manager API
gcloud beta --project ${PROJECT_ID} service-management enable appengine.googleapis.com
# Cloud SQL Admin API
gcloud beta --project ${PROJECT_ID} service-management enable cloudresourcemanager.googleapis.com
# Cloud SQL API
gcloud beta --project ${PROJECT_ID} service-management enable sqladmin.googleapis.com
# Compute Engine API
gcloud beta --project ${PROJECT_ID} service-management enable compute.googleapis.com
# Deployment Manager API
gcloud beta --project ${PROJECT_ID} service-management enable deploymentmanager.googleapis.com
# Identity and Access Management (IAM) API
gcloud beta --project ${PROJECT_ID} service-management enable iam.googleapis.com

forseti-securityダウンロード

FORSETI_ROOT=<your working dir>
cd ${FORSETI_ROOT}
git clone -b v1.1.8 --single-branch https://github.com/GoogleCloudPlatform/forseti-security

セットアップウィザード起動

cd ${FORSETI_ROOT}
cd forseti-security/scripts/gcp_setup
python setup_forseti.py --no-cloudshell

このスクリプトを実行すると、Forsetiに必要なリソースが対象プロジェクトにデプロイされます。

スクリプトは対話形式で実行され、途中で通知先のメールアドレス、組織のSuperAdmin権限を持ったユーザのメールアドレス等着替えれますので、適宜対応してください。

デプロイが完了すると、実行環境のVMから1時間おきにinventory,scanner,notifierが実行されるようになります。

デフォルトでは次の題名がついたメールが届くようになっていますので、これらの送信元からのメールはフィルタして整理しておくと良いでしょう。

  • Inventory Snapshot Complete
  • Firewall Rules Scan Complete
  • Policy Scan Complete

コンフィグおよびルールの変更

デプロイが完了した段階でデフォルトのルールが適用された状態でinventory,scanner,notifierが実行されますが、デフォルトの状態ではサンプルコンフィグのような状態なので実行していてもあまり意味がありません。少し変更して実行してみましょう。

コンフィグ、ルールはGCSのBucketに保存されており、forseti実行時にダウンロードして実行しています。

コンフィグ、ルールを更新するためローカルにコンフィグとルールを取得、修正してGCSにアップロードします。

cd ${FORSETI_ROOT}
FORSETI_BUCKET=`gsutil ls`

mkdir custom

gsutil cp ${FORSETI_BUCKET}configs/forseti_conf.yaml custom/
gsutil -m cp -r ${FORSETI_BUCKET}rules custom/

# 編集

gsutil cp custom/forseti_conf.yaml ${FORSETI_BUCKET}configs/forseti_conf.yaml
gsutil -m cp -r custom/rules ${FORSETI_BUCKET}

ちなみに、このステップは初めからコンフィグとルールのテンプレートを望みの通り書き換えている人には不要です。

コンフィグとルールの修正例

コンフィグに関しては特に修正する箇所はないので、そのままで良いと思います。

ただし、セットアップウィザードで誤った情報を入力してしまった場合、通知先email addressなどを変更したい場合に有益かもしれません。

forseti_conf.yaml

これらの値を変更すれば送信元のSendGridの情報や通知先を変更することができます。

  • email_recipient
  • email_sender
  • sendgrid_api_key

また、デフォルトではnotifierでemailが送信される違反は無いので、他の項目のパイプラインにも次のような情報を入力してemail通知を受け取れるようにします。

            - name: email_violations_pipeline
              configuration:
                sendgrid_api_key: SG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                sender: forseti-notify@localhost.domain
                recipient: morinaga@grasys.io

残念ながら、Notifierのslack通知はまだ機能しないようです。

bigquery_rules.yaml

BigQueryのルールを定義するファイルです。

デフォルトではScan対象のresource_idsがサンプルのものとなっていますので、対象がスキャンされません。 これを自社組織/対象プロジェクトIDに変更します。 複数必要な場合は複数記述しましょう。

$ diff custom/rules/bigquery_rules.yaml forseti-security/rules/bigquery_rules.yaml
27c27
<           - grasys.io/<TARGET PROJECT ID>
---
>           - YOUR_ORG_ID / YOUR_PROJECT_ID
38c38
<           - grasys.io/<TARGET PROJECT ID>
---
>           - YOUR_ORG_ID / YOUR_PROJECT_ID
49,50c49
<           - grasys.io/<TARGET PROJECT ID>
<
---
>           - YOUR_ORG_ID / YOUR_PROJECT_ID

iam_rules.yaml

IAMのルールを定義するファイルです。

デフォルトではドメインがサンプルのものとなっていますので、全ての組織で違反が発生するはずです。 これを自社ドメインに書き換えることにより、自社以外のドメインユーザが組織の管理者やプロジェクトオーナーになっていないかを検査できます。 また、サービスアカウントのみ権限が持てるルールも不要なので削除します。

$ diff custom/rules/iam_rules.yaml forseti-security/rules/iam_rules.yaml
28,29c28,29
<           - user:*@grasys.io
<           - group:*@grasys.io
---
>           - user:*@YOURDOMAIN
>           - group:*@YOURDOMAIN
31a32,44
>   - name: Allow only service accounts to have access
>     mode: whitelist
>     resource:
>       - type: organization
>         applies_to: self_and_children
>         resource_ids:
>           - '*'
>     inherit_from_parents: true
>     bindings:
>       - role: roles/*
>         members:
>           - serviceAccount:*@*.gserviceaccount.com
>
43c56
<           - user:*@grasys.io
---
>           - user:*@YOURDOMAIN

その他ルールに関してはドキュメントを参考に変更してみてください。

対応状況

ForsetiSecurityは絶賛開発中の模様で、まだ実装されていない機能がありますのでこちらで確認ください。

まとめ

とりあえずForsetiSecurityの構築はできましたが、ScannerとNotifierの今後の対応に期待!

使えそうなのはIAM, Firewall, BigQuery ACLあたりですね。

Notifierがちゃんと知らせてくれないですが、スキャンした結果はGCS上に残っています。しばらくはGCSに入ったデータを見つつルールを書いていく感じになると思います。

ルールに関してはこれから色々弄っていきますので、進捗あれば次回にでも〜