💽

【GCP】GCSバケットのオブジェクトのアクセスログの取り方

2021/02/19に公開

GCSバケットにセキュアなデータを保存してる場合、だれがそのデータに作成し、更新し、取得し、削除したかというログは絶対にとっておきたいですよね。
この記事では、GCSバケットのオブジェクトのアクセスログを取得する方法をまとめました。

結論

解説

GCSのアクセスログを残す方法は2つ

  • 監査ログを有効にする
  • 使用状況ログを有効にする

この2つがGCSへのアクセスログを残す方法です。
Googleも「監査ログを有効にする」をおすすめしていますし、僕もそっちのがいいと思いますし、ほとんどの場合は「監査ログを有効にする」で事足りると思います。
どちらも有効にすることも可能です。
https://cloud.google.com/storage/docs/access-logs?hl=ja

監査ログと使用状況ログはどう違う?

  • どちらもアクセス元IPアドレス、アクセス対象のオブジェクト、アクセス日時などはわかる
  • 監査ログは認証したユーザーが誰かわかる
  • 監査ログはどのAPIが呼び出されたのかがわかる
  • 監査ログはCloudLoggingから見れるが、使用状況ログはGCSバケットに1時間ごとのログがcsv形式で出力されるので見辛い
    • BQにエクスポートしてから確認するなどしないとまともにログが見れない

監査ログと使用状況ログはどっちを使えばいい?

基本は監査ログを使うとして、以下のような場合に当てはまる時などは使用状況ログを使う必要があります

  • オブジェクトが誰でもアクセスできるように公開されている
  • オブジェクトのライフサイクル管理機能による変更のログが必要
  • レイテンシの情報や、個々の HTTP リクエストのリクエスト サイズとレスポンス サイズ、URL の完全パスとクエリ パラメータをログに記録したい場合
    • 監査ログと使用状況ログの内容の差分はあとで紹介します

公式ドキュメントにより詳しくのっています

監査ログの使い方

監査ログを有効にする

監査ログを有効にする方法はいくつかありますが、ここではGCPコンソールから有効にする方法を紹介します
その他の方法については、以下のドキュメントを参考にしてください
https://cloud.google.com/logging/docs/audit/configure-data-access?hl=ja#config-console

  1. GCPコンソールから、IAM と管理 -> 監査ログ
  2. Google Cloud Storage を選択して、管理読み取り データ読み取り データ書き込みにチェックをして保存します

デフォルトの監査構成がすでに有効になってる場合は、そのままで大丈夫です

監査ログを見てみる

  • 1, roles/logging.privateLogViewerまたはroles/ownerのロールを持ったユーザーでCloudLoggingのページへアクセスします
  • 2, リソースから、GCSバケットを選択します
  • 3, ログ名から、Cloud Auditdata_accessを選択します
  • 4, クエリを実行を選択します
  • 5, ログがある場合は以下のようなログが表示されます

使用状況ログの使い方

使用状況ログを有効にする

使用状況ログを有効にする方法はいくつかありますが、ここではterraformで行う方法を紹介します。
ここで使うコードのサンプルは以下のリポジトリにあります。

他の方法については公式ドキュメントを参考にしてくださし

まずは、ログを保存するためのバケットを作成します

 resource "google_storage_bucket" "my_bucket_access_log" {
  name     = "my_bucket_access_log"
  location = var.gcp_regions["tokyo"]

  # アクセス制御をUniformモードにする
  uniform_bucket_level_access = true

  # このオプションをtrueにしておくと、バケット内にデータが残っていても削除してくれる
  # 本番運用時はtrueにしない方がおそらくいいが、これはサンプルのためtrueにしておく
  force_destroy = true
}

作成したバケットに他のバケットからオブジェクトを書き込むための権限を付与します

resource "google_storage_bucket_iam_policy" "my_bucket_access_log" {
  bucket      = google_storage_bucket.my_bucket_access_log.name
  policy_data = data.google_iam_policy.my_bucket_access_log.policy_data
}

data "google_iam_policy" "my_bucket_access_log" {
  # プロジェクトオーナーはログのバケットにアクセスできるようにしておく
  binding {
    role = "roles/storage.admin"

    members = [
      "projectOwner:GCPプロジェクトID",
    ]
  }

  binding {
    # 使用状況ログを書き込むための権限を付与する
    # https://cloud.google.com/storage/docs/access-logs#delivery
    role = "roles/storage.legacyBucketWriter"

    members = [
      "group:cloud-storage-analytics@google.com",
    ]
  }
}

そして、ログを残したいバケットを作成します。
使用状況ログを有効にするためのオプションを付与するのを忘れずに!

resource "google_storage_bucket" "my_bucket" {
  name     = "my_bucket"
  location = "asia-northeast1"

  # アクセス制御をUniformモードにする
  uniform_bucket_level_access = true

  # このオプションをtrueにしておくと、バケット内にデータが残っていても削除してくれる
  # 本番運用時はtrueにしない方がおそらくいいが、これはサンプルのためtrueにしておく
  force_destroy = true

  # 使用状況ログを有効にする
  # https://cloud.google.com/storage/docs/access-logs#delivery
  logging {
    log_bucket        = google_storage_bucket.my_bucket_access_log.name
    log_object_prefix = google_storage_bucket.my_bucket_access_log.name
  }
}

使用状況ログを見てみる

使用状況ログを保存するためのバケットをみると、中にログファイルがどんどん作成されていきます。
公式ドキュメントによると1時間ごとにログファイルが作成されるようです。(実際にはもっと作成されてるように見えます)

使用状況ログを分析用にBigQueryへエクスポートする

この記事では手順を割愛させてください。
こちらの公式ドキュメントを参考にすればできます。
https://cloud.google.com/storage/docs/access-logs#BigQuery

監査ログと使用状況ログのログ内容の違い

監査ログのサンプルはこちらです

{
  "protoPayload": {
    "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
    "status": {},
    "authenticationInfo": {
      "principalEmail": "認証されたユーザーのメールアドレス"
    },
    "requestMetadata": {
      "callerIp": "アクセス元",
      "callerSuppliedUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36,gzip(gfe)",
      "requestAttributes": {
        "time": "2021-02-18T08:16:13.621153112Z",
        "auth": {}
      },
      "destinationAttributes": {}
    },
    "serviceName": "storage.googleapis.com",
    "methodName": "storage.buckets.get",
    "authorizationInfo": [
      {
        "resource": "projects/_/buckets/private_bucket_project_owner_and_one_user_can_access",
        "permission": "storage.buckets.get",
        "granted": true,
        "resourceAttributes": {}
      }
    ],
    "resourceName": "projects/_/buckets/private_bucket_project_owner_and_one_user_can_access",
    "resourceLocation": {
      "currentLocations": [
        "asia-northeast1"
      ]
    }
  },
  "insertId": "8m6qpke4lphy",
  "resource": {
    "type": "gcs_bucket",
    "labels": {
      "project_id": "star-news-trial",
      "bucket_name": "private_bucket_project_owner_and_one_user_can_access",
      "location": "asia-northeast1"
    }
  },
  "timestamp": "2021-02-18T08:16:13.619441479Z",
  "severity": "INFO",
  "logName": "projects/star-news-trial/logs/cloudaudit.googleapis.com%2Fdata_access",
  "receiveTimestamp": "2021-02-18T08:16:13.920718955Z"
}

使用状況ログのサンプルはこちらです

"time_micros","c_ip","c_ip_type","c_ip_region","cs_method","cs_uri","sc_status","cs_bytes","sc_bytes","time_taken_micros","cs_host","cs_referer","cs_user_agent","s_request_id","cs_operation","cs_bucket","cs_object"
"1613635520134015","アクセス元IPアドレス","1","","GET","/storage/v1_internal/b/private_bucket_project_owner_and_one_user_can_access?key=AIzaSyCI-zsRP85UVOi0DjtiCwWBwQ1djDy741g","304","0","0","45000","clients6.google.com","","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36,gzip(gfe)","ABg5-UyrF15HWg4Mhbq8HMr6S73_pSHjm9qDPfgjp-MHIXNMM_0i_Yx9M3PBh0t-KLnApgk3ZSfQ0NQuY391wBrxEnlpLs3yUg","","private_bucket_project_owner_and_one_user_can_access",""
"1613635997737317","アクセス元IPアドレス","1","","GET","/storage/v1_internal/b/private_bucket_project_owner_and_one_user_can_access?key=AIzaSyCI-zsRP85UVOi0DjtiCwWBwQ1djDy741g","304","0","0","51000","clients6.google.com","","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36,gzip(gfe)","ABg5-UxFMZO8HZujx7wS2y8xnXTJk4qR-_E-WftbZfBt_WOH9vpKbNAdajM5cxWjpsxdjXY74xgJVleyxEX7C9MKhWk","","private_bucket_project_owner_and_one_user_can_access",""

ざっくりと要点をまとめると

  • 監査ログは認証済みユーザーに対するログなので、どのユーザーがアクセスしたかわかる
  • 使用状況ログはどのAPIによってアクセスされたかわかる
  • どちらもアクセス元IPや、どのオブジェクトにアクセスしたかはわかる

まとめ

  • GCSバケットのオブジェクトが非公開である場合
    • GCSの監査ログを有効にした方がよいです
  • GCSバケットのオブジェクトが公開である場合
    • 使用状況ログを使いましょう

Discussion