この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、みかみです。
人は間違える生き物です。 BigQuery や GCS バケットなど、大切なデータが置いてあるサービスに誰でもアクセスできるような設定がされていたら一大事! リスクはできる限り抑えたいものです。 _(:3」∠)_
やりたいこと
- 一般公開されている Google Cloud プロジェクト内のリソースを自動検出したい
- 一般公開リソースがあったらメールで通知したい
Cloud Asset Inventory とは
Google Cloud のプロジェクトやフォルダ、組織に紐づくリソースやポリシー、ランタイム情報などのメタデータを検索、分析できるサービスです。 アセットデータをエクスポートした場合などにはデータ保存先の GCS や BigQuery のストレージ料金がかかりますが、基本的には無料で利用できます。
- Cloud Asset Inventory | Cloud Asset Inventory ドキュメント
- Cloud Asset Inventory の概要 | Cloud Asset Inventory ドキュメント
前提
Google Cloud SDK(gcloud
コマンド)の実行環境は準備済みであるものとします。
本エントリでは、Cloud Shell を使用ました。
事前準備
ちゃんと検出できるか確認するために、一般公開された BigQuery データセットを準備しておきます。
データセットの権限設定から、allUsers
に「データ閲覧者」ロールを追加しました。
Pub/Sub トピックを作成
Cloud Shell から以下のコマンドを実行して、Pub/Sub トピックを作成します。 Cloud Scheduler からこの Pub/Sub トピックを経由して、Cloud Functions 関数を実行する予定です。
gcloud pubsub topics create check_public_access
管理コンソールから、トピックが作成されたことを確認しました。
Cloud Functions 関数を作成
Cloud Asset Inventory から一般公開されたリソースを取得する、Clooud Functions 関数を作成します。
以下の Python コードを main.py
というファイル名で保存しました。
from google.cloud import asset_v1
import os
def check_public_access_resources(event, context):
GCP_PROJECT = os.getenv('GCP_PROJECT', None)
scope = f'projects/{GCP_PROJECT}'
query = 'policy:(allAuthenticatedUsers OR allUsers)'
client = asset_v1.AssetServiceClient()
response = client.search_all_iam_policies(
request={"scope": scope, "query": query}
)
for policy in response:
print(f'Open to the public!! resource: {policy.resource}')
bindings = policy.policy.bindings
for item in bindings:
print(f'{item.role} is attached.')
break
合わせて、以下の requirements.txt
も、同じディレクトリに保存しました。
google-cloud-asset>=3.9.0
以下の gcloud
コマンドで、main.py
と requirements.txt
を Cloud Functions にデプロイします。
gcloud functions deploy check_public_access_resources \
--region asia-northeast1 \
--runtime python37 \
--trigger-resource check_public_access \
--trigger-event google.pubsub.topic.publish
管理コンソールからも、Cloud Functions 関数が無事デプロイできたことが確認できました。
Cloud Scheduler から Cloud Functions を実行
先ほどデプロイした Cloud Functions をスケジュール実行するために、Cloud Scheduler ジョブを作成します。
Cloud Shell から以下のコマンドを実行します。
gcloud scheduler jobs create pubsub check_public_access \
--schedule="*/5 * * * *" \
--topic=check_public_access \
--message-body="{}" \
--time-zone="Asia/Tokyo"
5分ごとに Cloud Functions を実行するジョブが作成できました。
そのまま5分待ちます..._(:3」∠)_
5分後、ジョブが正常に実行されたようなので、Cloud Functions のログを確認してみると...
bigquery.googleapis.com/(省略)/datasets/test_public
が roles/bigquery.dataViewer
ロールで一般公開されてしまっている旨、期待通りログ出力されました。
アラート通知を追加
せっかく Cloud Functions が5分おきにチェックしてくれていても、ログ出力するだけでは人が認識&対応するまでに時間がかかってしまう可能性があります。
一般公開されたリソースが見つかったら、通知してくれる仕組みも作っておきます。
通知用の別の Cloud Functions を作成して検出結果を Pub/Sub 経由で渡して通知、など、通知方法の実装はいろいろ考えられますが、今回はお手軽に Cloud Monitoring のアラートポリシーを作成して、指定したメールアドレス宛にアラートメールを送信してみます。
ログに特定の文字列が出力されていたらアラートを送信する、ログベースのアラートを作成します。 なお、ログベースのアラートは、2022/05/31 現在まだプレビューなので、ご使用の際にはご留意ください。
まずは Cloud Shell から以下のコマンドを実行して、アラート通知先のチャンネルを作成します。
gcloud alpha monitoring channels create \
--display-name="channel secd mail to me" \
--description="send mail to me" \
--type=email \
--channel-labels=email_address=xxxx@classmethod.jp
※メールアドレスは一部伏字に変更しています。
以下のポリシー定義を、policy_check_public_access.json
というファイル名で保存します。
{
"displayName": "Check public access resources.",
"documentation": {
"content": "一般公開されているリソースが見つかりました!至急確認してください!!",
"mimeType": "text/markdown"
},
"conditions": [
{
"displayName": "Check public access resources.",
"conditionMatchedLog": {
"filter": "resource.type=\"cloud_function\" resource.labels.function_name=\"check_public_access_resources\" resource.labels.region=\"asia-northeast1\" severity\u003e=DEFAULT \"Open to the public!!\""
}
}
],
"alertStrategy": {
"notificationRateLimit": {
"period": "300s"
}
},
"combiner": "OR",
"enabled": true,
"notificationChannels": [
"projects/cm-da-mikami-yuki-258308/notificationChannels/1663xxxxxxxxxxxx8583"
]
}
※一部伏字に変更しています。
以下のコマンドで、保存した定義ファイルを指定して、アラートポリシーを作成しました。
gcloud alpha monitoring policies create \
--policy-from-file="policy_check_public_access.json"
Cloud Functions が実行されるのを待って、メールを確認してみると...
設定した通り、アラートメールが受信できました。
データセットが一般公開されてるなんて一大事!すぐに対応せねばっ!!(( ;゚Д゚))
まとめ(所感)
Security Command Center などのマネージドサービスや、サードパーティーツールの導入など、脅威検知の仕組みはいろいろ考えられますが、監視対象が少ない場合には、Cloud Asset Inventory を利用したスクラッチも選択肢になるのではないかと思います。
今回は検出のみでしたが、間違って設定したポリシーの自動修正など、要件に合わせて自由に実装できるかと。
リスクとコストのトレードオフは、いつでも辛いところです。。_(:3」∠)_