{"id":573,"date":"2025-05-11T12:14:32","date_gmt":"2025-05-11T03:14:32","guid":{"rendered":"https:\/\/tako.nakano.net\/blog\/?p=573"},"modified":"2025-05-11T12:14:32","modified_gmt":"2025-05-11T03:14:32","slug":"vpn-and-bucket-ip-filtering","status":"publish","type":"post","link":"https:\/\/tako.nakano.net\/blog\/2025\/05\/vpn-and-bucket-ip-filtering\/","title":{"rendered":"VPN and Bucket IP Filtering"},"content":{"rendered":"<h1>VPN \u3068 Bucket IP Filtering<\/h1>\n<p>English follows Japanese.<\/p>\n<h2>\u672c\u8a18\u4e8b\u306e\u76ee\u7684<\/h2>\n<p>\u672c\u8a18\u4e8b\u306e\u76ee\u7684\u306f2\u3064\u3042\u308b\u3002<\/p>\n<p>\u526f\u6b21\u7684\u306a\u76ee\u7684\u306f\u30012\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u9593\u306e Cloud VPN \u306e\u69cb\u6210\u3092\u3001<code>gcloud<\/code> \u30b3\u30de\u30f3\u30c9\u306e\u307f\u3067\u884c\u3046\u4f8b\u3092\u793a\u3059\u3053\u3068\u3067\u3042\u308b\u3002\u7c21\u5358\u306b\u691c\u7d22\u3057\u305f\u9650\u308a\u3067\u306f\u3001Google Cloud \u306e\u516c\u5f0f\u6587\u66f8\uff08\u305f\u3060\u3057\u3001\u540c\u4e00\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u5185\uff09\u4ee5\u5916\u306b\u3001Web UI \u3092\u4f7f\u3063\u305f\u69cb\u6210\u4f8b\u306f\u3042\u3063\u305f\u304c\u3001<code>gcloud<\/code> \u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u3063\u305f\u69cb\u6210\u4f8b\u306f\u898b\u3064\u304b\u3089\u306a\u304b\u3063\u305f\u3002<\/p>\n<p>\u3082\u3046\u3072\u3068\u3064\u306e\u76ee\u7684\u306f\u3001Cloud Storage \u306e\u65b0\u6a5f\u80fd\u3067\u3042\u308b Bucket IP Filtering \u3092\u3001VPN \u63a5\u7d9a\u306e\u63a5\u7d9a\u5148\u304b\u3089\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u304b\u691c\u8a3c\u3059\u308b\u3053\u3068\u3067\u3042\u308b\u3002<\/p>\n<p>\u7d50\u8ad6: VPN \u63a5\u7d9a\u306e\u63a5\u7d9a\u5148\u304b\u3089\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3002\u3053\u308c\u306f\u3044\u3044\u3002<\/p>\n<p>\u672c\u8a18\u4e8b\u306f\u3001Google Cloud \u306e\u57fa\u672c\u7684\u306a VPC, IAM, Cloud Storage \u306e\u77e5\u8b58\u304c\u3042\u308b\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30a8\u30f3\u30b8\u30cb\u30a2\u3084\u30af\u30e9\u30a6\u30c9\u30a2\u30fc\u30ad\u30c6\u30af\u30c8\u3092\u5bfe\u8c61\u3068\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>2\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u9593\u306e VPN \u306b\u3064\u3044\u3066\u306f\u3001Google Cloud \u306e\u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u4ee5\u5916\u306e\u60c5\u5831\u304c\u898b\u3064\u304b\u3089\u306a\u304b\u3063\u305f\u305f\u3081\u3001<code>gcloud<\/code> \u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u3063\u305f\u69cb\u6210\u4f8b\u3092\u793a\u3059\uff08\u5bfe\u5411\u304c\u3001\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30eb\u30fc\u30bf\u30fc\u306e\u4f8b\u306f\u3001\u5f53\u305f\u308a\u524d\u3060\u304c\u7d50\u69cb\u3042\u3063\u305f\uff09\u3002<\/p>\n<h2>Bucket IP Filtering \u3068\u306f<\/h2>\n<p>Cloud Storage \u306e Bucket IP filtering \u6a5f\u80fd\u306f\u3001Cloud Storage \u306e\u30d0\u30b1\u30c3\u30c8\u306b\u5bfe\u3057\u3066\u3001\u7279\u5b9a\u306e IP \u30a2\u30c9\u30ec\u30b9\u7bc4\u56f2\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u306e\u307f\u3092\u8a31\u53ef\u3059\u308b\u3088\u3046\u306a\u3001\u30a2\u30af\u30bb\u30b9\u5236\u5fa1\u6a5f\u80fd\u3067\u3042\u308b<a href=\"https:\/\/cloud.google.com\/storage\/docs\/ip-filtering-overview?hl=ja\">\u30d0\u30b1\u30c3\u30c8 IP \u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0<\/a>\u3002<br \/>\n<a href=\"https:\/\/cloud.google.com\/storage\/docs\/release-notes#November_14_2024\">2024-11-14\u306b Public Preview \u3068\u3057\u3066\u30ea\u30ea\u30fc\u30b9<\/a>\u3055\u308c\u3066\u3044\u308b\u3002<\/p>\n<h2>VPN \u3067\u4f7f\u3048\u308b\uff1f<\/h2>\n<p>\u3042\u308b\u4f1a\u793e\u304c\u300c\u793e\u5185\u304b\u3089\u3057\u304b\u898b\u3089\u308c\u306a\u3044\u300d\u3088\u3046\u306a\u300c\u6c4e\u7528\u306e\u30d5\u30a1\u30a4\u30eb\u7f6e\u304d\u5834\u300d\u3092\u4f5c\u308a\u305f\u3044\u3068\u8003\u3048\u305f\u3068\u304d\u3001Cloud Storage \u306e Bucket IP filtering \u6a5f\u80fd\u304c\u5f79\u306b\u7acb\u3064\u304b\u3082\u3057\u308c\u306a\u3044\u3002<\/p>\n<p>Global IP \u3092 CIDR range \u3067\u6307\u5b9a\u3067\u304d\u308b\u305f\u3081\u3001\u5404\u62e0\u70b9\u306b\u56fa\u5b9a IP \u3092\u6301\u305f\u305b\u3066\u3044\u308b\u5834\u5408\u306b\u306f\u3001Cloud Storage \u306e Bucket IP filtering \u6a5f\u80fd\u3092\u4f7f\u3046\u3053\u3068\u3067\u3001\u7279\u5b9a\u306e\u62e0\u70b9\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u306e\u307f\u3092\u8a31\u53ef\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002<\/p>\n<pre><code class=\"language-json\">  &quot;publicNetworkSource&quot;: {\n    &quot;allowedIpCidrRanges&quot;: [\n      &quot;${YOUR_IP}\/32&quot;\n    ],\n  }<\/code><\/pre>\n<p>\u3082\u3046\u3072\u3068\u3064\u3001\u826f\u304f\u3042\u308b Google Cloud \u306e\u5229\u7528\u306e\u4ed5\u65b9\u3068\u3057\u3066\u306f\u3001VPN \u306e\u69cb\u6210\u304c\u3042\u3052\u3089\u308c\u308b\u3060\u308d\u3046\u3002Cloud Storage \u30d0\u30b1\u30c3\u30c8\u304c\u3001VPN \u63a5\u7d9a\u306e\u63a5\u7d9a\u5148\u3060\u3051\u304b\u3089\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u3060\u3068\u3059\u308b\u3068\u3001\u4ed6\u306b\u8003\u3048\u308b\u3053\u3068\u304c\u306a\u304f\u306a\u308b\u305f\u3081\u3001\u975e\u5e38\u306b\u4fbf\u5229\u3060\u3002<\/p>\n<p><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja\">\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30db\u30b9\u30c8\u306e\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9\u3092\u69cb\u6210\u3059\u308b<\/a>\u306b\u306f\u3001<\/p>\n<blockquote>\n<p>\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30db\u30b9\u30c8\u7528\u306e\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9\u3092\u4f7f\u7528\u3059\u308b\u3068\u3001Cloud VPN \u30c8\u30f3\u30cd\u30eb\u307e\u305f\u306f Cloud Interconnect \u7528\u306e VLAN \u30a2\u30bf\u30c3\u30c1\u30e1\u30f3\u30c8\u3092\u7d4c\u7531\u3057\u3066\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u3092\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3059\u308b\u3053\u3068\u306b\u3088\u308a\u3001\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30b7\u30b9\u30c6\u30e0\u304b\u3089 Google API \u3068\u30b5\u30fc\u30d3\u30b9\u306b\u63a5\u7d9a\u3067\u304d\u307e\u3059\u3002\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30db\u30b9\u30c8\u7528\u306e\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9\u306f\u3001\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u7d4c\u7531\u3067 Google API \u3068\u30b5\u30fc\u30d3\u30b9\u306b\u63a5\u7d9a\u3059\u308b\u305f\u3081\u306e\u4ee3\u66ff\u624b\u6bb5\u3068\u3057\u3066\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002<\/p>\n<\/blockquote>\n<p>\u3068\u8a18\u8f09\u3055\u308c\u3066\u3044\u308b\u3002\u63a5\u7d9a\u5148\u304b\u3089 <code>private.googleapis.com<\/code> \u7d4c\u7531\u3067 Cloud Storage \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3068\u304d\u306b\u3001Bucket IP Filtering \u304c\u5229\u7528\u3067\u304d\u308b\u304b\u691c\u8a3c\u3057\u305f\u3044\u3002<\/p>\n<h2>\u4f5c\u696d\u624b\u9806<\/h2>\n<p>\u57fa\u672c\u7684\u306a\u64cd\u4f5c\u306f\u3001\u3059\u3079\u3066 <code>gcloud<\/code> \u30b3\u30de\u30f3\u30c9\u3067\u884c\u3044\u3001\u30b3\u30d4\u30fc\u3059\u308b\u3060\u3051\u3067\u518d\u73fe\u3067\u304d\u308b\u3053\u3068\u3092\u76ee\u6307\u3059\u3002<\/p>\n<p>\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3084\u30d0\u30b1\u30c3\u30c8\u306e\u30ea\u30fc\u30b8\u30e7\u30f3\u306b\u306f <code>us-central1<\/code> \u3092\u6307\u5b9a\u3059\u308b\u3002<\/p>\n<p>Google Cloud \u30d7\u30ed\u30b8\u30a7\u30af\u30c82\u3064\u306b\u300110.1.0.0\/24, 10.2.0.0\/24 \u306e VPC \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3092\u4f5c\u6210\u3057\u3001VPN \u3067\u63a5\u7d9a\u3055\u305b\u308b\u3002<br \/>\n10.1.0.0\/24 \u304c\u30db\u30b9\u30c8\u5074\u300110.2.0.0\/24 \u304c\uff08Google Cloud \u4e0a\u3067\u691c\u8a3c\u3059\u308b\u304c\uff09\u30aa\u30f3\u30d7\u30ec\u30df\u30b9\u5074\u3068\u8003\u3048\u308b\u3002<\/p>\n<p>network-vpn-host 10.1.0.0\/24<br \/>\nnetwork-vpn-guest 10.1.1.0\/24<\/p>\n<h3>\u74b0\u5883\u5b9a\u7fa9<\/h3>\n<p>\u4ee5\u4e0b\u3092\u3001\u518d\u73fe\u74b0\u5883\u306b\u5408\u308f\u305b\u3066\u5b9a\u7fa9\u3059\u308b\u3002<\/p>\n<p><code>PROJECT_HOST<\/code> \u306f\u30d0\u30b1\u30c3\u30c8 \u30db\u30b9\u30c8\u3001<code>PROJECT_GUEST<\/code> \u306f\u30aa\u30f3\u30d7\u30ec\u30df\u30b9\u74b0\u5883\u3068\u8003\u3048\u308b\u3002<code>YOUR_IP<\/code> \u306f\u30a2\u30af\u30bb\u30b9\u3092\u8a31\u53ef\u3059\u308b\u30b0\u30ed\u30fc\u30d0\u30eb IP\u3001<code>YOUR_ACCOUNT<\/code> \u306f\u3001\u64cd\u4f5c\u8005\u306e Google \u30a2\u30ab\u30a6\u30f3\u30c8\u3001<code>BILLING_ACCOUNT<\/code> \u306f Google Cloud \u306e\u8ab2\u91d1\u30a2\u30ab\u30a6\u30f3\u30c8\u3092\u8a2d\u5b9a\u3059\u308b\u3002<\/p>\n<p><code>SHARED_SECRET<\/code> \u306f\u3001VPN \u63a5\u7d9a\u306e\u305f\u3081\u306e Shared Secret \u3067\u3042\u308b\u3002<\/p>\n<pre><code class=\"language-sh:envs.sh\">export PROJECT_HOST=host-project\nexport PROJECT_GUEST=guest-project\nexport YOUR_IP=203.0.113.1\nexport YOUR_ACCOUNT=test@example.com\nexport BILLING_ACCOUNT=&quot;000000-000000-000000&quot;\n\nexport SHARED_SECRET=&quot;bvTtdK7nil68WCYu7+dJ7iYdEmeWCB\/A5Q4lUu2DHac=&quot;<\/code><\/pre>\n<h3>Google Cloud \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210\u30fbAPI \u306e\u6709\u52b9\u5316<\/h3>\n<pre><code class=\"language-sh:create_projects.sh\">for project in $PROJECT_HOST $PROJECT_GUEST; do\n  gcloud projects create $project\n  gcloud billing projects link $project --billing-account=$BILLING_ACCOUNT\n  gcloud services enable compute.googleapis.com --project=$project\ndone<\/code><\/pre>\n<h3>\u30d0\u30b1\u30c3\u30c8\u306e\u4f5c\u6210<\/h3>\n<p>\u30db\u30b9\u30c8\u5074\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u3001\u6b21\u306e\u3088\u3046\u306a Cloud Storage \u30d0\u30b1\u30c3\u30c8\u3092\u4f5c\u6210\u3059\u308b\u3002sa \u306f Service Account \u306e\u7565\u304b\u3089\u6765\u3066\u3044\u308b\u3002<\/p>\n<p>\u57fa\u672c\u7684\u306b <code>allUsers<\/code> \u306b\u5bfe\u3057\u3066\u691c\u8a3c\u3067\u304d\u308c\u3070\u3001\u4eca\u56de\u306e\u76ee\u7684\u306f\u9054\u6210\u3055\u308c\u308b\u304c\u3001\u6298\u89d2\u306a\u306e\u3067\u3001Service Account \u306b\u6a29\u9650\u3092\u4ed8\u4e0e\u3057\u305f\u5834\u5408\u306e\u6319\u52d5\u3082\u78ba\u8a8d\u3057\u3066\u304a\u304f\u3002\u3042\u3068\u3067 <code>ls<\/code> \u3057\u305f\u3044\u306e\u3067\u3001\u30c0\u30df\u30fc\u30d5\u30a1\u30a4\u30eb\u3082\u4f5c\u6210\u3057\u3066\u304a\u304f\u3002<\/p>\n<table>\n<thead>\n<tr>\n<th>\u30d0\u30b1\u30c3\u30c8\u540d<\/th>\n<th>\u30a2\u30af\u30bb\u30b9\u8a31\u53ef<\/th>\n<th>Bucket IP Filtering<\/th>\n<th>network<\/th>\n<th>IP \u7bc4\u56f2<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>public-2025-05<\/td>\n<td>allUsers<\/td>\n<td>\u7121\u52b9<\/td>\n<td>NA<\/td>\n<td>NA<\/td>\n<\/tr>\n<tr>\n<td>private-2025-05<\/td>\n<td>host \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u307f<\/td>\n<td>\u7121\u52b9<\/td>\n<td>NA<\/td>\n<td>NA<\/td>\n<\/tr>\n<tr>\n<td>ip-vpn-all-2025-05<\/td>\n<td>allUsers<\/td>\n<td>\u6709\u52b9<\/td>\n<td>network-vpn-host<\/td>\n<td>10.1.0.0\/16<\/td>\n<\/tr>\n<tr>\n<td>ip-vpn-sa-2025-05<\/td>\n<td>\u691c\u8a3c\u8005\u3001host \u306e\u30b5\u30fc\u30d3\u30b9\u30a2\u30ab\u30a6\u30f3\u30c8<\/td>\n<td>\u6709\u52b9<\/td>\n<td>network-vpn-host<\/td>\n<td>10.1.0.0\/16<\/td>\n<\/tr>\n<tr>\n<td>ip-allow-all-2025-05<\/td>\n<td>allUsers<\/td>\n<td>\u6709\u52b9<\/td>\n<td>publicNetworkSource, network-vpn-host<\/td>\n<td>10.1.0.0\/16, <code>YOUR_IP<\/code><\/td>\n<\/tr>\n<tr>\n<td>ip-allow-sa-2025-05<\/td>\n<td>\u691c\u8a3c\u8005\u3001host \u306e\u30b5\u30fc\u30d3\u30b9\u30a2\u30ab\u30a6\u30f3\u30c8<\/td>\n<td>\u6709\u52b9<\/td>\n<td>publicNetworkSource, network-vpn-host<\/td>\n<td>10.1.0.0\/16, <code>YOUR_IP<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>network-vpn-host 10.1.0.0\/24<br \/>\nnetwork-vpn-guest 10.1.1.0\/24<br \/>\n\u3068\u3057\u305f\u304c\u3001\u300c\u4e21\u65b9\u300d\u3092\u542b\u3080 IP \u7bc4\u56f2\u3068\u3057\u3066\u3001<code>10.1.0.0\/16<\/code> \u3092\u6307\u5b9a\u3057\u3066\u3044\u308b\u3002<\/p>\n<pre><code class=\"language-sh:create_buckets.sh\">gcloud storage buckets create gs:\/\/public-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\ngcloud storage buckets add-iam-policy-binding gs:\/\/public-2025-05 --member=allUsers --role=roles\/storage.objectViewer --project=$PROJECT_HOST\n\ngcloud storage buckets create gs:\/\/private-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\n\ngcloud storage buckets create gs:\/\/ip-vpn-all-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\ngcloud storage buckets add-iam-policy-binding gs:\/\/ip-vpn-all-2025-05 --member=allUsers --role=roles\/storage.objectViewer --project=$PROJECT_HOST\n\ngcloud storage buckets create gs:\/\/ip-vpn-sa-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\n# \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u6a29\u9650\u4ed8\u4e0e\u3059\u308b\u306e\u3067\u3001IAM \u3067\u306e\u6a29\u9650\u4ed8\u4e0e\u306f\u7701\u7565\n\ngcloud storage buckets create gs:\/\/ip-allow-all-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\ngcloud storage buckets add-iam-policy-binding gs:\/\/ip-allow-all-2025-05 --member=allUsers --role=roles\/storage.objectViewer --project=$PROJECT_HOST\n\ngcloud storage buckets create gs:\/\/ip-allow-sa-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\n# \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u6a29\u9650\u4ed8\u4e0e\u3059\u308b\u306e\u3067\u3001IAM \u3067\u306e\u6a29\u9650\u4ed8\u4e0e\u306f\u7701\u7565\n\nmkdir -p dummy_files\nfor bucket in public private ip-vpn-all ip-vpn-sa ip-allow-all ip-allow-sa; do\n  echo &quot;${bucket}_2025-05.txt&quot; &gt; dummy_files\/${bucket}_2025-05.txt\n  gcloud storage cp dummy_files\/${bucket}_2025-05.txt gs:\/\/${bucket}-2025-05\ndone<\/code><\/pre>\n<h3>VPC \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306e\u4f5c\u6210<\/h3>\n<p>PROJECT_HOST \u306b VPC \u30cd\u30c3\u30c8\u30ef\u30fc\u30af network-vpn-host \u3092\u4f5c\u6210\u3057\u3001PROJECT_GUEST \u306b VPC \u30cd\u30c3\u30c8\u30ef\u30fc\u30af network-vpn-guest \u3092\u4f5c\u6210\u3059\u308b\u3002<\/p>\n<p>\u524d\u8ff0\u306e\u901a\u308a\u3001<\/p>\n<p>network-vpn-host 10.1.0.0\/24<br \/>\nnetwork-vpn-guest 10.1.1.0\/24<\/p>\n<p>\u3068\u3059\u308b\u3002<\/p>\n<pre><code class=\"language-sh:create_networks.sh\">gcloud compute networks create network-vpn-host --project=$PROJECT_HOST --subnet-mode=custom\ngcloud compute networks subnets create subnet-vpn-host \\\n    --network=network-vpn-host \\\n    --region=us-central1 \\\n    --range=10.1.0.0\/24 \\\n    --project=$PROJECT_HOST\n\ngcloud compute networks create network-vpn-guest --project=$PROJECT_GUEST --subnet-mode=custom\ngcloud compute networks subnets create subnet-vpn-guest \\\n    --network=network-vpn-guest \\\n    --region=us-central1 \\\n    --range=10.1.1.0\/24 \\\n    --project=$PROJECT_GUEST<\/code><\/pre>\n<p>Public IP \u304c\u3042\u308b\u3068\u3001\u7d4c\u8def\u304c\u5206\u304b\u308a\u306b\u304f\u3044\uff08\u5b9f\u969b\u306b\u306f\u5909\u308f\u3089\u306a\u3044\u306f\u305a\u3060\u304c\uff09\u3002<br \/>\nPublic IP \u304c\u306a\u304f\u3066\u3082\u3001SSH \u3067\u63a5\u7d9a\u3067\u304d\u308b\u3088\u3046\u306b\u3001<a href=\"https:\/\/cloud.google.com\/iap\/docs\/using-tcp-forwarding?hl=ja#create-firewall-rule\">IAP \u306e\u8a2d\u5b9a<\/a>\u3092\u884c\u3046\u3002<\/p>\n<pre><code class=\"language-sh::create_iap_rules.sh\">for project in $PROJECT_HOST $PROJECT_GUEST; do\n    gcloud projects add-iam-policy-binding $project \\\n        --member=&quot;user:${YOUR_ACCOUNT}&quot; \\\n        --role=roles\/iap.tunnelResourceAccessor\n    gcloud projects add-iam-policy-binding $project \\\n        --member=&quot;user:${YOUR_ACCOUNT}&quot; \\\n        --role=roles\/compute.instanceAdmin.v1\ndone\n\ngcloud compute firewall-rules create allow-ssh-ingress-from-iap-vpn \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=tcp:22 \\\n    --source-ranges=35.235.240.0\/20 \\\n    --network=network-vpn-host \\\n    --project=$PROJECT_HOST\n\ngcloud compute firewall-rules create allow-ssh-ingress-from-iap-vpn \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=tcp:22 \\\n    --source-ranges=35.235.240.0\/20 \\\n    --network=network-vpn-guest \\\n    --project=$PROJECT_GUEST<\/code><\/pre>\n<p>\u307e\u305f\u3001Public IP \u304c\u306a\u304f\u3066\u3082\u3001Google Cloud \u306e\u30b5\u30fc\u30d3\u30b9\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3088\u3046\u306b\u3001<a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access?hl=ja\">\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9\u3092\u69cb\u6210<\/a>\u3059\u308b\u3002<\/p>\n<p><!-- \u305f\u3060\u3057\u3001guest \u5074\u306f\u3001\u5f8c\u3067\u7121\u52b9\u5316\u3057\u305f\u5834\u5408\u3082\u691c\u8a3c\u3059\u308b\u3002 --><\/p>\n<pre><code class=\"language-sh:enable_private_ip_google_access.sh\">gcloud compute networks subnets update subnet-vpn-host --project=$PROJECT_HOST \\\n    --region=us-central1 \\\n    --enable-private-ip-google-access\n\ngcloud compute networks subnets update subnet-vpn-guest --project=$PROJECT_GUEST \\\n    --region=us-central1 \\\n    --enable-private-ip-google-access\n\n# \u78ba\u8a8d\u3057\u305f\u3044\u5834\u5408\u306b\u306f\u4ee5\u4e0b\u3092\u5b9f\u884c\n# gcloud compute networks subnets describe subnet-vpn-host --project=$PROJECT_HOST \\\n#     --region=us-central1 \\\n#     --format=&quot;get(privateIpGoogleAccess)&quot;<\/code><\/pre>\n<p>VM \u304c\u76f8\u4e92\u306b\u901a\u4fe1\u3067\u304d\u308b\u3088\u3046\u306b\u3001Firewall Rule \u3092\u8a2d\u5b9a\u3059\u308b\u3002<\/p>\n<pre><code class=\"language-sh:allow_network_rules.sh\">gcloud compute firewall-rules create allow-internal-ingress-from-vpn \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=all \\\n    --source-ranges=10.1.0.0\/16 \\\n    --network=network-vpn-host \\\n    --project=$PROJECT_HOST\n\ngcloud compute firewall-rules create allow-internal-ingress-from-vpn \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=all \\\n    --source-ranges=10.1.0.0\/16 \\\n    --network=network-vpn-guest \\\n    --project=$PROJECT_GUEST<\/code><\/pre>\n<h3>\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u9593\u306e VPN \u306e\u8a2d\u5b9a<\/h3>\n<p>\u4eca\u307e\u3067\u4f5c\u6210\u3057\u305f\u30cd\u30c3\u30c8\u30ef\u30fc\u30af network-vpn-host \u3068 network-vpn-guest \u306e\u9593\u306b VPN \u3092\u8a2d\u5b9a\u3059\u308b\u3002<\/p>\n<p>BGP \u306e IPv6 \u306b\u3064\u3044\u3066\u306f\u3001\u7701\u304f\u3053\u3068\u306b\u3057\u305f\u3002<\/p>\n<pre><code class=\"language-sh:setup_vpn.sh\"># PROJECT_HOST \u3067\u306e VPN \u8a2d\u5b9a\ngcloud compute vpn-gateways create vpn-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --network=network-vpn-host\n\ngcloud compute routers create cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --network network-vpn-host \\\n  --asn 65001\n\n# PROJECT_GUEST \u3067\u306e VPN \u8a2d\u5b9a\ngcloud compute vpn-gateways create vpn-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --network=network-vpn-guest\n\ngcloud compute routers create cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --network network-vpn-guest \\\n  --asn 65002<\/code><\/pre>\n<p>\u8868\u793a\u3055\u308c\u308b IP \u3092\u63a7\u3048\u3066\u304a\u304f\u3002<\/p>\n<pre><code class=\"language-sh\">export HOST_INTERFACE0=34.153.55.144\nexport HOST_INTERFACE1=35.220.88.151\n\nexport GUEST_INTERFACE0=35.242.99.80\nexport GUEST_INTERFACE1=34.153.244.91\n\n# \u30c6\u30b9\u30c8\u3057\u3066\u3044\u306a\u3044\u304c\u3001\u4ee5\u4e0b\u3067\u53d6\u5f97\u3067\u304d\u308b\u304b\u3082\nexport HOST_INTERFACE0=$(gcloud compute vpn-gateways describe vpn-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;value(vpnInterfaces[0].ipAddress)&#039;)\nexport HOST_INTERFACE1=$(gcloud compute vpn-gateways describe vpn-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;value(vpnInterfaces[1].ipAddress)&#039;)\n\nexport GUEST_INTERFACE0=$(gcloud compute vpn-gateways describe vpn-guest --project=$PROJECT_GUEST --region=us-central1 --format=&#039;value(vpnInterfaces[0].ipAddress)&#039;)\nexport GUEST_INTERFACE1=$(gcloud compute vpn-gateways describe vpn-guest --project=$PROJECT_GUEST --region=us-central1 --format=&#039;value(vpnInterfaces[1].ipAddress)&#039;)<\/code><\/pre>\n<pre><code class=\"language-sh:create_tunnels.sh\"># PROJECT_HOST \u3067\u3001\u76f8\u624b\u65b9\u306e\u60c5\u5831\u3092\u767b\u9332\n# guest -&gt; host \u306e VPN \u306e\u5b58\u5728\u767b\u9332\n# \u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5229\u7528\u3057\u305f\u3044\u304c\u3001\n# &gt; You cannot provide interface with IP address associated with HA VPN gateway of Google Cloud.\n# \u3068\u51fa\u308b\u306e\u3067\u3001`projects\/${PROJECT_GUEST}\/regions\/us-central1\/vpnGateways\/vpn-guest` \u3092\u6307\u5b9a\u3059\u308b\n\n# gcloud compute external-vpn-gateways create vpngw-guest-host \\\n#   --project=$PROJECT_HOST \\\n#   --interfaces=0=${GUEST_INTERFACE0},1=${GUEST_INTERFACE1}\n\ngcloud compute vpn-tunnels create tunnel-host-guest-0 \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_GUEST}\/regions\/us-central1\/vpnGateways\/vpn-guest \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-host \\\n  --vpn-gateway=vpn-host \\\n  --interface=0\n\ngcloud compute vpn-tunnels create tunnel-host-guest-1 \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_GUEST}\/regions\/us-central1\/vpnGateways\/vpn-guest \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-host \\\n  --vpn-gateway=vpn-host \\\n  --interface=1\n\n# PROJECT_GUEST \u3067\u3001\u76f8\u624b\u65b9\u306e\u60c5\u5831\u3092\u767b\u9332\n# host -&gt; guest \u306e VPN \u306e\u5b58\u5728\u767b\u9332\n# gcloud compute external-vpn-gateways create vpngw-host-guest \\\n#   --project=$PROJECT_GUEST \\\n#   --interfaces=0=${HOST_INTERFACE0},1=${HOST_INTERFACE1}\n\ngcloud compute vpn-tunnels create tunnel-guest-host-0 \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_HOST}\/regions\/us-central1\/vpnGateways\/vpn-host \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-guest \\\n  --vpn-gateway=vpn-guest \\\n  --interface=0\n\ngcloud compute vpn-tunnels create tunnel-guest-host-1 \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_HOST}\/regions\/us-central1\/vpnGateways\/vpn-host \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-guest \\\n  --vpn-gateway=vpn-guest \\\n  --interface=1<\/code><\/pre>\n<p>BGP \u306e\u8a2d\u5b9a<\/p>\n<pre><code class=\"language-sh:setup_bgp.sh\"># HOST\ngcloud compute routers add-interface cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --interface-name=if-tunnel-host-guest-0 \\\n  --vpn-tunnel=tunnel-host-guest-0 \\\n  --region=us-central1 \\\n  --ip-version=IPV4\n\ngcloud compute routers add-bgp-peer cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --peer-name=peer-tunnel-host-guest-0 \\\n  --interface=if-tunnel-host-guest-0 \\\n  --peer-asn=65002\n\n# AI Suggest below:\n# BGP_PEER_IP_HOST_TUNNEL_0=$(gcloud compute routers get-status cloud-router-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;flattened(result.bgpPeerStatus[].name,result.bgpPeerStatus[].ipAddress,result.bgpPeerStatus[].peerIpAddress)&#039; | grep tunnel-host-guest-0 | awk &#039;{print $3}&#039;)\n# BGP_ROUTER_IP_HOST_TUNNEL_0=$(gcloud compute routers get-status cloud-router-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;flattened(result.bgpPeerStatus[].name,result.bgpPeerStatus[].ipAddress,result.bgpPeerStatus[].peerIpAddress)&#039; | grep tunnel-host-guest-0 | awk &#039;{print $2}&#039;)<\/code><\/pre>\n<pre><code class=\"language-sh\">gcloud compute routers describe cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1<\/code><\/pre>\n<p><code>peerIpAddress<\/code> \u3092\u78ba\u8a8d\u3057\u3001\u76f8\u624b\u65b9\u306b\u60f3\u5b9a\u3055\u308c\u3066\u3044\u308b IP \u3092\u624b\u52d5\u3067\u8a2d\u5b9a\u3059\u308b\u3002<\/p>\n<pre><code class=\"language-sh\"># GUEST\ngcloud compute routers add-interface cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --interface-name=if-tunnel-guest-host-0 \\\n  --ip-address=169.254.0.250 \\\n  --mask-length=30 \\\n  --vpn-tunnel=tunnel-guest-host-0 \\\n  --region=us-central1 \\\n  --ip-version=IPV4\n\ngcloud compute routers add-bgp-peer cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --peer-name=peer-tunnel-guest-host-0 \\\n  --interface=if-tunnel-guest-host-0 \\\n  --peer-asn=65001 \\\n  --peer-ip-address=169.254.0.249<\/code><\/pre>\n<p>\u8a2d\u5b9a\u306e\u78ba\u8a8d<\/p>\n<pre><code class=\"language-sh\">gcloud compute routers describe cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1\n\ngcloud compute routers describe cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1<\/code><\/pre>\n<h3>VM \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306e\u4f5c\u6210<\/h3>\n<p>\u305d\u308c\u305e\u308c\u306e VPC \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u306b VM \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3092\u4f5c\u6210\u3059\u308b\u3002<code>no-address<\/code> \u3092\u6307\u5b9a\u3057\u3066\u3001Public IP \u3092\u6301\u305f\u306a\u3044 VM \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u3068\u3057\u3066\u3044\u308b\u3002<\/p>\n<pre><code class=\"language-sh:create_vms.sh\">gcloud compute instances create vm-host-vpn \\\n    --project=$PROJECT_HOST \\\n    --zone=us-central1-f \\\n    --machine-type=e2-micro \\\n    --network-interface=stack-type=IPV4_ONLY,subnet=subnet-vpn-host,no-address \\\n    --scopes=https:\/\/www.googleapis.com\/auth\/cloud-platform \\\n    --boot-disk-size 10GB \\\n    --boot-disk-type pd-standard \\\n    --image-project debian-cloud \\\n    --image-family debian-12\n\ngcloud compute instances create vm-guest-vpn \\\n    --project=$PROJECT_GUEST \\\n    --zone=us-central1-f \\\n    --machine-type=e2-micro \\\n    --network-interface=stack-type=IPV4_ONLY,subnet=subnet-vpn-guest,no-address \\\n    --scopes=https:\/\/www.googleapis.com\/auth\/cloud-platform \\\n    --boot-disk-size 10GB \\\n    --boot-disk-type pd-standard \\\n    --image-project debian-cloud \\\n    --image-family debian-12<\/code><\/pre>\n<p>\u5404 VM \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u306b\u306f\u3001\u6b21\u306e\u3088\u3046\u306b\u3057\u3066 SSH \u63a5\u7d9a\u3067\u304d\u308b\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud compute ssh --zone=us-central1-f vm-host-vpn --tunnel-through-iap --project $PROJECT_HOST\ngcloud compute ssh --zone=us-central1-f vm-guest-vpn --tunnel-through-iap --project $PROJECT_GUEST<\/code><\/pre>\n<p>10.1.0.3 \u304c\u30db\u30b9\u30c8\u5074\u306e VM \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 IP\u300110.1.1.3 \u304c\u30b2\u30b9\u30c8\u5074\u306e VM \u30a4\u30f3\u30b9\u30bf\u30f3\u30b9 IP \u3067\u3042\u3063\u305f\u3002<br \/>\n\u30b2\u30b9\u30c8\u5074\u304b\u3089 ping \u3057\u3066\u3001\u758e\u901a\u3067\u304d\u3066\u3044\u308c\u3070\u3001\u554f\u984c\u304c\u306a\u3044\u3002<\/p>\n<pre><code class=\"language-sh\">ping 10.1.0.3<\/code><\/pre>\n<h2>Bucket IP Filtering \u306e\u691c\u8a3c<\/h2>\n<h3>Access Check Part 1<\/h3>\n<p>\u307e\u305a\u306f\u3001\u5404 VM \u304b\u3089\u3001\u30d0\u30b1\u30c3\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u304b\u3092\u78ba\u8a8d\u3059\u308b\u3002<code>ls_all_buckets.sh<\/code> \u3092\u5404 VM \u304b\u3089\u5b9f\u884c\u3057\u3066\u3001\u30d0\u30b1\u30c3\u30c8\u4e00\u89a7\u3092\u78ba\u8a8d\u3059\u308b\u3002<\/p>\n<pre><code class=\"language-sh:ls_all_buckets.sh\">for bucket_prefix in public private ip-vpn-all ip-vpn-sa ip-allow-all ip-allow-sa; do\n  echo &quot;gs:\/\/${bucket_prefix}-2025-05\/&quot;\n  gcloud storage ls gs:\/\/${bucket_prefix}-2025-05\/\ndone<\/code><\/pre>\n<p>vm-host-vpn:<\/p>\n<pre><code>.\/ls_all_buckets.sh \ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\ngs:\/\/private-2025-05\/private_2025-05.txt\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\ngs:\/\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\ngs:\/\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>vm-guest-vpn:<\/p>\n<pre><code>gs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [private-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.<\/code><\/pre>\n<p>\u4e0a\u8a18\u306e\u3088\u3046\u306b\u3001vm-host-vpn \u304b\u3089\u306f\u3059\u3079\u3066\u306e\u30d0\u30b1\u30c3\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u304c\u3001vm-guest-vpn \u304b\u3089\u306f\u3001<code>public-2025-05<\/code> \u3068 <code>ip-vpn-all-2025-05<\/code> \u306e\u307f\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3002<\/p>\n<h3>Bucket IP Filtering \u306e\u8a2d\u5b9a<\/h3>\n<p>ip-vpn-all-2025-05 \u3068 ip-vpn-sa-2025-05 \u306e\u30d0\u30b1\u30c3\u30c8\u306b\u3001Bucket IP Filtering \u3092\u8a2d\u5b9a\u3059\u308b\u3002<\/p>\n<pre><code class=\"language-sh\">cat &lt;&lt;EOF &gt; ip-filter-vpn.json\n{\n  &quot;mode&quot;: &quot;Enabled&quot;,\n  &quot;vpcNetworkSources&quot;: [\n    {\n      &quot;network&quot;: &quot;projects\/$PROJECT_HOST\/global\/networks\/network-vpn-host&quot;,\n      &quot;allowedIpCidrRanges&quot;: [\n        &quot;10.1.0.0\/16&quot;\n      ]\n    }\n  ]\n}\nEOF<\/code><\/pre>\n<p><code>ip-filter-allow.json<\/code> \u3092\u4f5c\u6210\u3059\u308b\u3002<\/p>\n<pre><code class=\"language-sh:create-ip-filter-allow.sh\">cat &lt;&lt;EOF &gt; ip-filter-allow.json\n{\n  &quot;mode&quot;: &quot;Enabled&quot;,\n  &quot;publicNetworkSource&quot;: {\n    &quot;allowedIpCidrRanges&quot;: [\n      &quot;${YOUR_IP}\/32&quot;\n    ]\n  },\n  &quot;vpcNetworkSources&quot;: [\n    {\n      &quot;network&quot;: &quot;projects\/$PROJECT_HOST\/global\/networks\/network-vpn-host&quot;,\n      &quot;allowedIpCidrRanges&quot;: [\n        &quot;10.1.0.0\/16&quot;\n      ]\n    }\n  ]\n}\nEOF<\/code><\/pre>\n<p>Bucket IP Filtering \u3092\u8a2d\u5b9a\u3059\u308b\u3002<\/p>\n<pre><code class=\"language-sh:configure_ip_filtering.sh\">for bucket_prefix in ip-vpn-all ip-vpn-sa; do\n  gcloud alpha storage buckets update gs:\/\/${bucket_prefix}-2025-05 --project=$PROJECT_HOST --ip-filter-file=ip-filter-vpn.json\ndone\n\nfor bucket_prefix in ip-allow-all ip-allow-sa; do\n  gcloud alpha storage buckets update gs:\/\/${bucket_prefix}-2025-05 --project=$PROJECT_HOST --ip-filter-file=ip-filter-allow.json\ndone<\/code><\/pre>\n<pre><code>.\/configure_ip_filtering.sh.sh \nUpdating gs:\/\/ip-vpn-all-2025-05\/...\n  Completed 1\nUpdating gs:\/\/ip-vpn-sa-2025-05\/...\n  Completed 1\nUpdating gs:\/\/ip-allow-all-2025-05\/...\n  Completed 1\nUpdating gs:\/\/ip-allow-sa-2025-05\/...\n  Completed 1<\/code><\/pre>\n<h3>Access Check Part 2<\/h3>\n<p>vm-host-vpn:<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\ngs:\/\/private-2025-05\/private_2025-05.txt\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\ngs:\/\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\ngs:\/\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>vm-guest-vpn:<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [private-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-all-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-all-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-all-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.<\/code><\/pre>\n<p>vm-guest-vpn \u304b\u3089\u306f\u3001<code>public-2025-05<\/code> \u306e\u307f\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3002\u305d\u308c\u4ee5\u5916\u306b\u306f\u30a2\u30af\u30bb\u30b9\u3067\u304d\u306a\u3044\u3002IP filtering \u306e\u6709\u7121\u3067\u3001\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u304c\u7570\u306a\u3063\u3066\u3044\u308b\u3002<\/p>\n<h3>\u9759\u7684\u30eb\u30fc\u30c8\u306e\u8ffd\u52a0<\/h3>\n<pre><code class=\"language-sh\"># gcloud compute routes create private-to-host \\\n#     --project=$PROJECT_GUEST \\\n#     --network=network-vpn-guest \\\n#     --destination-range=199.36.153.8\/30 \\\n#     --priority=200 \\\n#     --next-hop-gateway=projects\/$PROJECT_HOST\/global\/vpnGateways\/vpn-host\n\ngcloud compute routes create private-to-host \\\n    --project=$PROJECT_GUEST \\\n    --network=network-vpn-guest \\\n    --destination-range=199.36.153.8\/30 \\\n    --priority=200 \\\n    --next-hop-vpn-tunnel-region=us-central1 \\\n    --next-hop-vpn-tunnel=tunnel-guest-host-0<\/code><\/pre>\n<h3>\u3010\u53c2\u8003\u3011Cloud Router \u306e\u8a2d\u5b9a\u5909\u66f4<\/h3>\n<p><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja#config-routing-on-prem\">Cloud Router \u3092\u4f7f\u7528\u3057\u305f\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30eb\u30fc\u30c6\u30a3\u30f3\u30b0<\/a> \u306b\u3042\u308b\u3088\u3046\u306b\u3001host \u5074\u306e Cloud Router \u304c\u3001<code>private.googleapis.com<\/code> \u30c9\u30e1\u30a4\u30f3\u3067\u4f7f\u7528\u3055\u308c\u308b IP \u7bc4\u56f2\u306e\u30eb\u30fc\u30c8\u3092 guest \u5074\uff08\u30aa\u30f3\u30d7\u30ec\u30df\u30b9\u5074\uff09\u306b\u901a\u77e5\u3067\u304d\u308b\u3002<\/p>\n<p>\u9759\u7684\u30eb\u30fc\u30c8\u3067\u52d5\u4f5c\u3057\u305f\u305f\u3081\u3001\u4e0a\u8a18\u901a\u77e5 (advertise) \u306e\u624b\u6cd5\u3067\u3082\u52d5\u4f5c\u3059\u308b\u3068\u8003\u3048\u3089\u308c\u308b\u3002\u5177\u4f53\u7684\u306a\u691c\u8a3c\u306f\u884c\u3063\u3066\u3044\u306a\u3044\u305f\u3081\u3001\u662f\u975e\u78ba\u8a8d\u3057\u3066\u307f\u3066\u307b\u3057\u3044\u3002<\/p>\n<h3>Access Check Part 3<\/h3>\n<p>\u7d50\u8ad6: \u9069\u5207\u306a\u8a2d\u5b9a\u3092\u52a0\u3048\u308b\u3068\u3001<code>gs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt<\/code> \u3068 <code>gs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt<\/code> \u306b\u8ffd\u52a0\u3067\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308b\u3002<\/p>\n<h4><code>\/etc\/hosts<\/code> \u6cd5<\/h4>\n<p>\u4ee5\u4e0b\u306e\u884c\u3092 <code>\/etc\/hosts<\/code> \u306b\u8ffd\u52a0\u3059\u308b\u3002<\/p>\n<pre><code>199.36.153.8 storage.googleapis.com<\/code><\/pre>\n<p>\u3059\u308b\u3068\u3001<code>storage.googleapis.com<\/code> \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3068\u3001<code>199.36.153.8<\/code> \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3088\u3046\u306b\u306a\u308b\u3002\u307e\u305f\u3001<code>199.36.153.8\/30<\/code> \u3078\u306e\u30a2\u30af\u30bb\u30b9\u306f\u3001VPN \u7d4c\u7531\u3067\u884c\u308f\u308c\u308b\u9759\u7684\u30eb\u30fc\u30c8\u3092\u8a2d\u5b9a\u3057\u3066\u3044\u308b\u306e\u3067\u3001VPN \u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3055\u308c\u308b\u306f\u305a\u3060\u3002<\/p>\n<p><code>.\/ls_all_buckets.sh<\/code> \u3092\u518d\u5ea6\u5b9f\u884c\u3057\u3088\u3046\u3002<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [private-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.<\/code><\/pre>\n<p><code>gs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt<\/code> \u3068 <code>gs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt<\/code> \u306b\u8ffd\u52a0\u3067\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u3063\u305f\u3002<\/p>\n<h4>Endpoint Override \u6cd5<\/h4>\n<p>\u9577\u3044\u306e\u3067\u7d50\u8ad6: <code>\/etc\/hosts<\/code> \u3042\u308b\u3044\u306f\u3001DNS \u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/p>\n<p><code>\/etc\/hosts<\/code> \u306e\u8a2d\u5b9a\u306f\u5143\u306b\u623b\u3057\u3066\u304a\u304f\u3002<\/p>\n<p><code>gcloud<\/code> \u30b3\u30de\u30f3\u30c9\u306f\u3001API \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u4e0a\u66f8\u304d\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/<\/code><\/pre>\n<p>\u4e0a\u8a18\u306b\u3088\u3063\u3066\u3001<code>storage.googleapis.com<\/code> \u3067\u306f\u306a\u304f\u3001<code>private.googleapis.com<\/code> \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u3088\u3046\u306b\u306a\u308b\u3002\u307e\u305f\u3001<code>199.36.153.8\/30<\/code> \u3078\u306e\u30a2\u30af\u30bb\u30b9\u306f\u3001VPN \u7d4c\u7531\u3067\u884c\u308f\u308c\u308b\u9759\u7684\u30eb\u30fc\u30c8\u3092\u8a2d\u5b9a\u3057\u3066\u3044\u308b\u306e\u3067\u3001VPN \u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3055\u308c\u308b\u306f\u305a\u3060\u3002<\/p>\n<p><code>.\/ls_all_buckets.sh<\/code> \u3092\u518d\u5ea6\u5b9f\u884c\u3057\u3088\u3046\u3002<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/public-2025-05 not found: 404.\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/private-2025-05 not found: 404.\ngs:\/\/ip-vpn-all-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-vpn-all-2025-05 not found: 404.\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-vpn-sa-2025-05 not found: 404.\ngs:\/\/ip-allow-all-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-allow-all-2025-05 not found: 404.\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-allow-sa-2025-05 not found: 404.<\/code><\/pre>\n<p>\u2026\u30c0\u30e1\u3060\u3063\u305f\u3002<\/p>\n<p>\u3053\u3053\u3067\u91cd\u8981\u306a\u70b9\u3068\u3057\u3066\u3001\u3053\u306e\u8a2d\u5b9a\u3067\u306f\u671f\u5f85\u901a\u308a\u306b\u52d5\u4f5c\u305b\u305a\u3001\u30a2\u30af\u30bb\u30b9\u306f\u5931\u6557\u3057\u305f\u3002\u3053\u306e\u7d50\u679c\u306b\u306f\u6ce8\u76ee\u3057\u3066\u307b\u3057\u3044\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/storage\/v1\/<\/code><\/pre>\n<p>\u3082\u30a8\u30e9\u30fc\u3060\u3063\u305f\u3002\u306a\u305c\u30a2\u30af\u30bb\u30b9\u304c\u5931\u6557\u3059\u308b\u306e\u304b\u539f\u56e0\u304c\u4e0d\u660e\u3067\u3042\u308b\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/storage\/<\/code><\/pre>\n<p>\u3053\u308c\u3082\u30a8\u30e9\u30fc\u3060\u3063\u305f\u3002<\/p>\n<p>\u4ee5\u4e0b\u306e\u3088\u3046\u306b <code>--log-http<\/code> \u3092\u3064\u3051\u3066\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u78ba\u8a8d\u3057\u3066\u307f\u308b\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/storage\/v1\/\ngcloud storage ls gs:\/\/public-2025-05 --log-http<\/code><\/pre>\n<p>\u3059\u308b\u3068\u3001<\/p>\n<pre><code>https:\/\/private.googleapis.com\/storage\/v1\/b\/public-2025-05\/o?alt=json&amp;fields=prefixes%2Citems%2Fname%2Citems%2Fsize%2Citems%2Fgeneration%2CnextPageToken&amp;delimiter=%2F&amp;includeFoldersAsPrefixes=True&amp;maxResults=1000&amp;projection=noAcl<\/code><\/pre>\n<p>\u306e\u3088\u3046\u306a\u30ea\u30af\u30a8\u30b9\u30c8\u304c\u98db\u3093\u3067\u3044\u308b\u3002<\/p>\n<pre><code class=\"language-sh\">curl &quot;https:\/\/private.googleapis.com\/storage\/v1\/b\/public-2025-05\/o?alt=json&amp;fields=prefixes%2Citems%2Fname%2Citems%2Fsize%2Citems%2Fgeneration%2CnextPageToken&amp;delimiter=%2F&amp;includeFoldersAsPrefixes=True&amp;maxResults=1000&amp;projection=noAcl&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/storage\/v1\/b\/public-2025-05\/o?alt=json&amp;fields=prefixes%2Citems%2Fname%2Citems%2Fsize%2Citems%2Fgeneration%2CnextPageToken&amp;delimiter=%2F&amp;includeFoldersAsPrefixes=True&amp;maxResults=1000&amp;projection=noAcl&quot;<\/code><\/pre>\n<p>\u3092\u8a66\u3057\u3066\u307f\u308b\u3068\u3001<code>Host<\/code> \u3092\u8a2d\u5b9a\u3057\u306a\u3044\u5834\u5408\u306f\u3001404 \u3067\u3001<code>Host<\/code> \u3092\u8a2d\u5b9a\u3059\u308b\u3068\u3001\u4ee5\u4e0b\u304c\u8fd4\u3063\u3066\u304d\u305f\u3002<\/p>\n<pre><code>{\n  &quot;items&quot;: [\n    {\n      &quot;name&quot;: &quot;public_2025-05.txt&quot;,\n      &quot;generation&quot;: &quot;1746452844041206&quot;,\n      &quot;size&quot;: &quot;19&quot;\n    }\n  ]\n}<\/code><\/pre>\n<p>\u3064\u307e\u308a\u3001\u30b5\u30fc\u30d0\u5074\u306f <code>Host<\/code> \u30d8\u30c3\u30c0\u3092\u898b\u3066\u3044\u3066\u3001<code>storage<\/code> \u3067\u306a\u3044\u5834\u5408\u306b\u306f\u6b63\u5e38\u306b\u5fdc\u7b54\u3057\u306a\u3044\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/<\/code><\/pre>\n<p>\u3068\u3057\u3066\u3082\u3001\u30a2\u30af\u30bb\u30b9\u5148\u306f\u540c\u3058\u3088\u3046\u3060\u3063\u305f\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/199.36.153.8\/\ngcloud config set auth\/disable_ssl_validation True\ngcloud storage ls gs:\/\/public-2025-05 --log-http<\/code><\/pre>\n<p>\u3068\u3059\u308b\u3068\u3001401 \u3068\u306a\u308b\u3002<\/p>\n<pre><code>gcloud storage ls gs:\/\/public-2025-05\n\/usr\/bin\/..\/lib\/google-cloud-sdk\/lib\/third_party\/urllib3\/connectionpool.py:1102: InsecureRequestWarning: Unverified HTTPS request is being made to host &#039;199.36.153.8&#039;. Adding certificate verification is strongly advised. See: https:\/\/urllib3.readthedocs.io\/en\/latest\/advanced-usage.html#tls-warnings\n  warnings.warn(\n\/usr\/bin\/..\/lib\/google-cloud-sdk\/lib\/third_party\/urllib3\/connectionpool.py:1102: InsecureRequestWarning: Unverified HTTPS request is being made to host &#039;199.36.153.8&#039;. Adding certificate verification is strongly advised. See: https:\/\/urllib3.readthedocs.io\/en\/latest\/advanced-usage.html#tls-warnings\n  warnings.warn(\nERROR: (gcloud.storage.ls) HTTPError 401: &lt;!DOCTYPE html&gt;\n&lt;html lang=en&gt;\n  &lt;meta charset=utf-8&gt;\n  &lt;meta name=viewport content=&quot;initial-scale=1, minimum-scale=1, width=device-width&quot;&gt;\n  &lt;title&gt;Error 401 (Unauthorized)!!1&lt;\/title&gt;\n  &lt;style&gt;\n    *{margin:0;padding:0}html,code{font:15px\/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* &gt; body{background:url(\/\/www.google.com\/images\/errors\/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/1x\/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) no-repeat 0% 0%\/100% 100%;-moz-border-image:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}\n  &lt;\/style&gt;\n  &lt;a href=\/\/www.google.com\/&gt;&lt;span id=logo aria-label=Google&gt;&lt;\/span&gt;&lt;\/a&gt;\n  &lt;p&gt;&lt;b&gt;401.&lt;\/b&gt; &lt;ins&gt;That\u2019s an error.&lt;\/ins&gt;\n  &lt;p&gt;Your client does not have permission to the requested URL &lt;code&gt;\/storage\/v1\/b\/public-2025-05\/o&lt;\/code&gt;.  &lt;ins&gt;That\u2019s all we know.&lt;\/ins&gt;<\/code><\/pre>\n<p>\u3068\u3044\u3046\u3053\u3068\u3067\u3001\u7d50\u8ad6\u304b\u3089\u8a00\u3046\u3068\u3001\u30c0\u30e1\u3060\u3002<\/p>\n<h4>Endpoint Override \u6cd5\u306e\u8003\u5bdf<\/h4>\n<p><code>\/etc\/hosts<\/code> \u306b\u4ee5\u4e0b\u3092\u8ffd\u52a0\u3057\u3066\u307f\u308b\u3002\u7247\u65b9\u306f\u610f\u56f3\u7684\u306b <code>storag<\/code> \u3068 <code>e<\/code> \u3092\u524a\u3063\u3066\u3044\u308b\u3002<\/p>\n<pre><code>199.36.153.8 storage-dummy.p.googleapis.com\n199.36.153.8 storag-dummy.p.googleapis.com<\/code><\/pre>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/storage-dummy.p.googleapis.com\/\ngcloud storage ls gs:\/\/public-2025-05<\/code><\/pre>\n<p>\u306f<\/p>\n<pre><code>gcloud storage ls gs:\/\/public-2025-05\ngs:\/\/public-2025-05\/public_2025-05.txt<\/code><\/pre>\n<p>\u3068\u7d50\u679c\u304c\u8fd4\u3063\u3066\u304f\u308b\u3002<\/p>\n<p>\u4e00\u65b9\u3067<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/storag-dummy.p.googleapis.com\/\ngcloud storage ls gs:\/\/public-2025-05<\/code><\/pre>\n<p>\u3068\u3059\u308b\u3068<\/p>\n<pre><code>gcloud storage ls gs:\/\/public-2025-05\nERROR: (gcloud.storage.ls) gs:\/\/public-2025-05 not found: 404.<\/code><\/pre>\n<p>\u3068\u306a\u308b\u3002<\/p>\n<p>\u30b0\u30ed\u30fc\u30d0\u30eb Google API \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b \u306e \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u304b\u3089 Google API \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b \u306b<a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-service-connect-apis?hl=ja#using-endpoints\">\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u4f7f\u7528\u3059\u308b<\/a>\u3068\u3044\u3046\u9805\u76ee\u304c\u3042\u308b\u3002\u3053\u308c\u306b\u3088\u308b\u3068\u3001<\/p>\n<blockquote>\n<p>\u305f\u3068\u3048\u3070\u3001\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u540d\u304c <code>xyz<\/code> \u306e\u5834\u5408\u3001API \u30d0\u30f3\u30c9\u30eb\u306b <code>storage-xyz.p.googleapis.com<\/code>\u3001<code>compute-xyz.p.googleapis.com<\/code>\u3001\u305d\u306e\u4ed6\u306e\u4e00\u822c\u7684\u306b\u4f7f\u7528\u3055\u308c\u308b API \u306e DNS \u30ec\u30b3\u30fc\u30c9\u304c\u4f5c\u6210\u3055\u308c\u307e\u3059\u3002<\/p>\n<p>\u6ce8: \u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u4f7f\u7528\u3067\u304d\u308b\u30ab\u30b9\u30bf\u30e0 \u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u958b\u767a\u3059\u308b\u5834\u5408\u306f\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u4fe1\u3059\u308b\u30b5\u30fc\u30d3\u30b9\u306e\u6709\u52b9\u306a\u30db\u30b9\u30c8\u540d\u306b Host \u30d8\u30c3\u30c0\u30fc\u3068 SNI \u3092\u8a2d\u5b9a\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u6709\u52b9\u306a\u30db\u30b9\u30c8\u540d\u306f\u3001\u30b5\u30fc\u30d3\u30b9\u56fa\u6709\u306e\u30c7\u30d5\u30a9\u30eb\u30c8 \u30c9\u30e1\u30a4\u30f3\u540d\uff08<code>storage.googleapis.com<\/code>\uff09\u307e\u305f\u306f\u30b5\u30fc\u30d3\u30b9\u306e <code>SERVICE-ENDPOINT.p.googleapis.com<\/code> DNS \u540d\uff08\u4f7f\u7528\u53ef\u80fd\u306a\u5834\u5408\uff09\u306e\u3044\u305a\u308c\u304b\u3067\u3059\u3002<code>SERVICE-ENDPOINT.p.googleapis.com<\/code> \u306e\u540d\u524d\u306e\u5834\u5408\u3001\u540d\u524d\u306e <code>SERVICE<\/code> \u306e\u90e8\u5206\u306f\u30b5\u30fc\u30d3\u30b9\u3068\u4e00\u81f4\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u304c\u3001<code>ENDPOINT<\/code> \u306e\u4efb\u610f\u306e\u5024\u3092\u4f7f\u7528\u3067\u304d\u307e\u3059\u3002<\/p>\n<\/blockquote>\n<p>\u3067\u3042\u308b\u3002\u3053\u306e\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306f\u3001\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u5074\u304c\u3001\u300c\u3069\u306e\u3088\u3046\u306a <code>Host<\/code> \u3067\u547c\u3073\u51fa\u3055\u308c\u3066\u3044\u308b\u304b\u300d\u3092\u6c17\u306b\u3057\u3066\u5fdc\u7b54\u3057\u3066\u3044\u308b\u3068\u3044\u3046\u8003\u3048\u3092\u88cf\u4ed8\u3051\u308b\u3002<\/p>\n<p>\u7d50\u8ad6\u3068\u3057\u3066\u306f\u3001Endpoint Override \u3067\u63a5\u7d9a\u3057\u305f\u3044\u5834\u5408\u306f\u3001<\/p>\n<ol>\n<li><code>storage-endpointname.p.googleapis.com<\/code> \u304c\u3001<code>private.googleapis.com<\/code> \u306e CNAME \u306b\u89e3\u6c7a\u3055\u308c\u308b\u3088\u3046\u306a DNS \u8a2d\u5b9a\u3092\u884c\u3046<\/li>\n<li><code>storage-endpointname.p.googleapis.com<\/code> \u3067\u547c\u3073\u51fa\u3059\u3088\u3046\u306b\u3059\u308b<\/li>\n<\/ol>\n<p>\u3092\u5408\u308f\u305b\u3066\u5229\u7528\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002<\/p>\n<p><code>storage.private.googleapis.com<\/code> \u3068\u304b\u4f5c\u3063\u3066\u304f\u308c\u305f\u3089\u3044\u3044\u306e\u306b\u2026\u3002<\/p>\n<p>\u3061\u306a\u307f\u306b\u3001<code>storage-private.googleapis.com<\/code> \u306f <code>storage.googleapis.com<\/code> \u3068\u540c\u3058\u7d50\u679c\u304c\u8fd4\u3063\u3066\u304f\u308b\u3088\u3046\u3060\u3002<\/p>\n<p>\u6ce8\u610f:<br \/>\n<code>gcloud config<\/code> \u306e\u8a2d\u5b9a\u306f\u5143\u306b\u623b\u3057\u3066\u304a\u304f\u3053\u3068\u3092\u5fd8\u308c\u306a\u3044\u3088\u3046\u306b\u3059\u308b\u3002\u4ee5\u4e0b\u306e\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3001\u5143\u306b\u623b\u3059\u3053\u3068\u304c\u3067\u304d\u308b\u3002<\/p>\n<pre><code class=\"language-sh\">gcloud config unset auth\/disable_ssl_validation\ngcloud config unset api_endpoint_overrides\/storage<\/code><\/pre>\n<h4>curl \u6cd5<\/h4>\n<p>\u3055\u3066\u3001<code>curl<\/code> \u306f <code>-H<\/code> \u30aa\u30d7\u30b7\u30e7\u30f3\u3067 <code>Host<\/code> \u30d8\u30c3\u30c0\u3092\u6307\u5b9a\u3067\u304d\u308b\u3002\u3053\u3061\u3089\u306e\u4e16\u754c\u306f\u81ea\u7531\u3060\u3002<\/p>\n<p>\u307e\u305a\u306f\u3001\u30a2\u30af\u30bb\u30b9\u300c\u3067\u304d\u306a\u3044\u300d\u4f8b\u3092\u78ba\u8a8d\u3057\u3066\u304a\u3053\u3046\u3002<\/p>\n<pre><code class=\"language-sh:bucket_access_curl_1.sh\">echo &quot;curl https:\/\/storage.googleapis.com\/public-2025-05\/public_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/public-2025-05\/public_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/private-2025-05\/private_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/private-2025-05\/private_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>vm-guest-vpn:<\/p>\n<pre><code>curl https:\/\/storage.googleapis.com\/public-2025-05\/public_2025-05.txt\npublic_2025-05.txt\ncurl https:\/\/storage.googleapis.com\/private-2025-05\/private_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;<\/code><\/pre>\n<p>\u30a2\u30af\u30bb\u30b9\u7d4c\u8def\u304c\u5909\u308f\u3089\u306a\u3044\u306e\u3067\u3001\u7d50\u679c\u306f\u5909\u308f\u3089\u306a\u3044\u3002<\/p>\n<p>\u3053\u3053\u3067\u3001\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092 <code>private.googleapis.com<\/code> \u306b\u5909\u66f4\u3057\u3066\u3001curl \u3057\u3066\u307f\u308b\u3002<\/p>\n<pre><code class=\"language-sh:bucket_access_curl_2.sh\">echo &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/public-2025-05\/public_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/public-2025-05\/public_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/private-2025-05\/private_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/private-2025-05\/private_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt&quot;<\/code><\/pre>\n<p>Error \u306e\u76f4\u5f8c\u306e\u884c\u3067\u3001\u6539\u884c\u3092\u5165\u308c\u305f\u3002<\/p>\n<p>vm-guest-vpn:<\/p>\n<pre><code>curl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/public-2025-05\/public_2025-05.txt&quot;\npublic_2025-05.txt\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/private-2025-05\/private_2025-05.txt&quot;\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\nip-vpn-all_2025-05.txt\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt&quot;\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\nip-allow-all_2025-05.txt\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt&quot;\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;<\/code><\/pre>\n<p>\u7d50\u679c\u304c\u5909\u308f\u3063\u305f\u3053\u3068\u306b\u6ce8\u610f\u3057\u3088\u3046\u3002\u5927\u4e8b\u306a\u30dd\u30a4\u30f3\u30c8\u3092\u629c\u304d\u51fa\u3059\u3002<\/p>\n<pre><code># NG\ncurl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\n\n# OK\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\nip-vpn-all_2025-05.txt\n\n# NG\ncurl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\n\n# OK\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\nip-allow-all_2025-05.txt<\/code><\/pre>\n<p><code>curl<\/code> \u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u3063\u3066\u3082\u3001Bucket IP Filtering \u3067\u8a31\u53ef\u3055\u308c\u3066\u3044\u308b IP \u7bc4\u56f2\u304b\u3089\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b\u3053\u3068\u304c\u78ba\u8a8d\u3067\u304d\u305f\u3002<\/p>\n<h3>Access Check Part 4<\/h3>\n<p>\u7b46\u8005\u81ea\u5b85\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u304b\u3089\u3082\u78ba\u8a8d\u3057\u3066\u307f\u308b\u3002\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f <code>test@example.com<\/code> \u306b\u7f6e\u304d\u63db\u3048\u3066\u3044\u308b\u3002<\/p>\n<pre><code>gs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\ngs:\/\/private-2025-05\/private_2025-05.txt\ngs:\/\/ip-vpn-all-2025-05\/\nERROR: (gcloud.storage.ls) [test@example.com] does not have permission to access b instance [ip-vpn-all-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as test@example.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [test@example.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as test@example.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\ngs:\/\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>\u3068\u3044\u3046\u3053\u3068\u3067\u3001<\/p>\n<ul>\n<li>VPN \u306e IP Range \u5916\u3067\u3042\u308b\u305f\u3081\u30012\u3064\u306e\u30d0\u30b1\u30c3\u30c8\u306b\u306f\u30a2\u30af\u30bb\u30b9\u3067\u304d\u306a\u3044<\/li>\n<li>\u5916\u90e8 IP \u306e\u8a2d\u5b9a\u3092\u3057\u3066\u3044\u308c\u3070\u30a2\u30af\u30bb\u30b9\u3067\u304d\u308b<\/li>\n<li>IAM \u306e\u6a29\u9650\u3082\u554f\u984c\u306a\u304f\u901a\u904e\u3057\u3066\u3044\u308b<\/li>\n<\/ul>\n<p>\u3053\u3068\u304c\u5206\u304b\u308b\u3002<\/p>\n<h2>\u6700\u5f8c\u306b<\/h2>\n<p>\u672c\u8a18\u4e8b\u3067\u306f\u30012\u3064\u306e Google Cloud \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u9593\u306b Cloud VPN \u3092<code>gcloud<\/code>\u30b3\u30de\u30f3\u30c9\u3067\u69cb\u7bc9\u3057\u3001\u305d\u306e VPN \u63a5\u7d9a\u3092\u7d4c\u7531\u3057\u3066 Cloud Storage \u306e Bucket IP Filtering \u6a5f\u80fd\u304c\u5229\u7528\u3067\u304d\u308b\u3053\u3068\u3092\u691c\u8a3c\u3057\u305f\u3002<a href=\"https:\/\/cloud.google.com\/vpc\/docs\/private-google-access-hybrid?hl=ja\">\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30db\u30b9\u30c8\u7528\u306e\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9<\/a>\u306e\u4ed5\u7d44\u307f\u3092\u5229\u7528\u3059\u308b\u3053\u3068\u3067\u3001 VPN \u306e\u5bfe\u5411\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\uff08\u672c\u8a18\u4e8b\u3067\u306f <code>network-vpn-guest<\/code> \uff09\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u3092\u3001\u30d0\u30b1\u30c3\u30c8\u5074\u3067\u8a2d\u5b9a\u3057\u305fVPC\u30cd\u30c3\u30c8\u30ef\u30fc\u30af (<code>network-vpn-host<\/code>) \u5185\u306e\u8a31\u53ef IP \u7bc4\u56f2\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u3068\u3057\u3066\u8a8d\u8b58\u3055\u305b\u308b\u3053\u3068\u304c\u53ef\u80fd\u3067\u3042\u308b\u3002<\/p>\n<p>\u3053\u306e\u691c\u8a3c\u3092\u901a\u3058\u3066\u5f97\u3089\u308c\u305f\u4e3b\u8981\u306a\u30b9\u30c6\u30c3\u30d7\u3068\u6ce8\u610f\u70b9\u3092\u4ee5\u4e0b\u306b\u518d\u78ba\u8a8d\u3059\u308b\u3002<\/p>\n<ol>\n<li><strong>\u7d4c\u8def\u8a2d\u5b9a\u306e\u91cd\u8981\u6027:<\/strong> VPN \u5bfe\u5411\u5074\uff08\u30b2\u30b9\u30c8 VM\uff09\u304b\u3089 Bucket IP Filtering \u304c\u8a2d\u5b9a\u3055\u308c\u305f\u30d0\u30b1\u30c3\u30c8\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u306b\u306f\u3001<code>private.googleapis.com<\/code> (199.36.153.8\/30) \u3078\u306e\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u304c VPN \u30c8\u30f3\u30cd\u30eb\u3092\u7d4c\u7531\u3059\u308b\u3088\u3046\u306b\u3001<strong>\u9759\u7684\u30eb\u30fc\u30c8<\/strong>\uff08\u672c\u8a18\u4e8b\u3067\u63a1\u7528\uff09\u307e\u305f\u306f<strong>Cloud Router\u306b\u3088\u308bBGP\u30eb\u30fc\u30c8\u5e83\u544a<\/strong>\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u304c\u4e0d\u53ef\u6b20\u3067\u3042\u308b\u3002\u3053\u308c\u3092\u5fd8\u308c\u308b\u3068\u3001\u30c8\u30e9\u30d5\u30a3\u30c3\u30af\u306f\u30a4\u30f3\u30bf\u30fc\u30cd\u30c3\u30c8\u7d4c\u7531\uff08\u3042\u308b\u3044\u306f\u3001\u5bfe\u5411 VPN \u5185\u306e\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\uff09\u3068\u306a\u308a\u3001IP Filtering \u306e\u6761\u4ef6\u3092\u6e80\u305f\u305b\u306a\u3044\u3002<\/li>\n<li><strong><code>gcloud<\/code>\u30b3\u30de\u30f3\u30c9\u5229\u7528\u6642\u306e\u6ce8\u610f\u70b9:<\/strong>\n<ul>\n<li><code>gcloud storage<\/code> \u30b3\u30de\u30f3\u30c9\u3067 <code>private.googleapis.com<\/code> \u7d4c\u7531\u3067\u30a2\u30af\u30bb\u30b9\u3057\u3088\u3046\u3068\u3059\u308b\u5834\u5408\u3001\u5358\u306b <code>gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/<\/code> \u3092\u8a2d\u5b9a\u3059\u308b\u3060\u3051\u3067\u306f<strong>\u4e0d\u5341\u5206<\/strong>\u3067\u3042\u308b\u3002\u3053\u308c\u306f <code>gcloud<\/code> \u304c\u9001\u4fe1\u3059\u308b\u30ea\u30af\u30a8\u30b9\u30c8\u306e <code>Host<\/code> \u30d8\u30c3\u30c0\u304c\u539f\u56e0\u3067\u3001API\u5074\u304c\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u6b63\u3057\u304f\u51e6\u7406\u3067\u304d\u306a\u3044\u305f\u3081\u3067\u3042\u308b\u3002<\/li>\n<li>\u3053\u306e\u554f\u984c\u3092\u56de\u907f\u3059\u308b\u306b\u306f\u3001\u9069\u5207\u306aDNS\u8a2d\u5b9a\uff08\u4f8b: <code>storage-endpointname.p.googleapis.com<\/code> \u3092\u4f5c\u6210\u3057\u3001\u305d\u308c\u3092 <code>private.googleapis.com<\/code> \u306b\u5411\u3051\u3001<code>gcloud<\/code> \u306e\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u30aa\u30fc\u30d0\u30fc\u30e9\u30a4\u30c9\u3067\u305d\u306e\u30ab\u30b9\u30bf\u30e0\u30c9\u30e1\u30a4\u30f3\u3092\u6307\u5b9a\u3059\u308b\uff09\u304c\u5fc5\u8981\u3067\u3042\u308b\u3002\u3042\u308b\u3044\u306f\u3001<code>\/etc\/hosts<\/code> \u30d5\u30a1\u30a4\u30eb\u3067 <code>storage.googleapis.com<\/code> \u3092 <code>private.googleapis.com<\/code> \u306eIP\u30a2\u30c9\u30ec\u30b9 (e.g. 199.36.153.8) \u306b\u5411\u3051\u308b\u3053\u3068\u3067\u4e0a\u8a18\u3092\u30b7\u30df\u30e5\u30ec\u30fc\u30b7\u30e7\u30f3\u3067\u304d\u308b\u3002<\/li>\n<\/ul>\n<\/li>\n<li><strong><code>curl<\/code>\u7b49\u3067\u306e\u76f4\u63a5\u30a2\u30af\u30bb\u30b9:<\/strong> <code>curl<\/code> \u306e\u3088\u3046\u306b <code>Host<\/code> \u30d8\u30c3\u30c0\u3092\u660e\u793a\u7684\u306b\u6307\u5b9a\u3067\u304d\u308b\u30c4\u30fc\u30eb\u3092\u4f7f\u7528\u3059\u308b\u5834\u5408\u3001\u30a2\u30af\u30bb\u30b9\u5148URL\u306b <code>private.googleapis.com<\/code> \u3092\u6307\u5b9a\u3057\u3064\u3064\u3001<code>-H &quot;Host: storage.googleapis.com&quot;<\/code> \u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u8ffd\u52a0\u3059\u308b\u3053\u3068\u3067\u3001DNS \u7b49\u306e\u8a2d\u5b9a\u306a\u3057\u306b VPN \u7d4c\u7531\u3067\u306e\u30a2\u30af\u30bb\u30b9\u3068 IP Filtering \u306e\u691c\u8a3c\u304c\u53ef\u80fd\u3067\u3042\u308b\u3002\u3053\u308c\u306f API \u306e\u6319\u52d5\u3092\u7406\u89e3\u3059\u308b\u4e0a\u3067\u6709\u7528\u306a\u65b9\u6cd5\u3060\u3002<\/li>\n<li><strong>IP Filtering \u3068 IAM \u306f\u5225:<\/strong> Bucket IP Filtering \u306f\u3001\u3042\u304f\u307e\u3067\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30ec\u30d9\u30eb\u3067\u306e\u30a2\u30af\u30bb\u30b9\u5143 IP \u30a2\u30c9\u30ec\u30b9\u306b\u57fa\u3065\u304f\u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0\u6a5f\u80fd\u3092\u300c<strong>\u8ffd\u52a0\u3059\u308b<\/strong>\u300d\u3082\u306e\u3067\u3042\u308b\u3002\u3053\u308c\u306b\u52a0\u3048\u3066\u3001\u30a2\u30af\u30bb\u30b9\u3059\u308b\u30e6\u30fc\u30b6\u30fc\u3084\u30b5\u30fc\u30d3\u30b9\u30a2\u30ab\u30a6\u30f3\u30c8\u306b\u306f\u9069\u5207\u306a<strong>IAM\u6a29\u9650<\/strong>\uff08\u4f8b: <code>roles\/storage.objectViewer<\/code>\uff09\u304c\u4ed8\u4e0e\u3055\u308c\u3066\u3044\u308b\u5fc5\u8981\u304c\u3042\u308b\u3002\u4e21\u65b9\u306e\u6761\u4ef6\u3092\u6e80\u305f\u3057\u3066\u521d\u3081\u3066\u30a2\u30af\u30bb\u30b9\u304c\u8a31\u53ef\u3055\u308c\u308b\u3002<\/li>\n<\/ol>\n<p>Bucket IP Filtering \u306f\u3001VPN \u3084 Cloud Interconnect \u3067\u63a5\u7d9a\u3055\u308c\u305f\u5185\u90e8\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u5236\u5fa1\u3092\u5f37\u5316\u3059\u308b\u4e0a\u3067\u6709\u52b9\u306a\u624b\u6bb5\u3068\u306a\u308a\u5f97\u308b\u3002\u305f\u3060\u3057\u3001\u7279\u306b <code>gcloud<\/code> \u306a\u3069\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u30c4\u30fc\u30eb\u304b\u3089\u5229\u7528\u3059\u308b\u969b\u306b\u306f\u3001Private Google Access \u306e\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3068 <code>Host<\/code> \u30d8\u30c3\u30c0\u306e\u6319\u52d5\u306b\u3064\u3044\u3066\u7406\u89e3\u3057\u3066\u304a\u304f\u3053\u3068\u304c\u91cd\u8981\u3067\u3042\u308b\u3002<a href=\"https:\/\/cloud.google.com\/vpc\/docs\/private-google-access-hybrid?hl=ja\">\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30db\u30b9\u30c8\u7528\u306e\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9<\/a>\u306e\u8aac\u660e\u3092\u826f\u304f\u7406\u89e3\u3057\u3066\u304a\u304f\u3068\u826f\u3044\u3002<\/p>\n<p>Bucket IP Filtering \u306f\u3001\u4e0a\u8a18 VPN \u63a5\u7d9a\u3092\u5229\u7528\u3057\u3066\u3044\u308b\u5834\u5408\u3067\u3082\u3001\u300c\u7279\u5b9a\u306e VPC \u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u304b\u3089\u306e\u3001\u7279\u5b9a\u306e IP \u7bc4\u56f2\u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u300d\u3068\u898b\u505a\u3057\u3066\u3001\u8a31\u53ef\u30fb\u62d2\u5426\u3092\u884c\u3046\u3053\u3068\u304c\u3067\u304d\u308b\u3053\u3068\u304c\u5206\u304b\u3063\u305f\u3002\u30b5\u30fc\u30d3\u30b9 \u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u6a29\u9650\u3092\u6301\u305f\u306a\u3044\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304b\u3089\u3001\u6b63\u3057\u3044 SSL \u8a3c\u660e\u66f8\u3067\u3042\u308b\u72b6\u614b\u3067\u30a2\u30af\u30bb\u30b9\u53ef\u80fd\u3067\u3042\u308a\u3001\u4fbf\u5229\u3060\u3002<\/p>\n<p>\u3082\u3061\u308d\u3093\u3001\u30b0\u30ed\u30fc\u30d0\u30eb IP \u3092\u500b\u5225\u8a31\u53ef\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u308b\u305f\u3081\u3001\u62e0\u70b9\u306e\u5916\u90e8 IP \u3092\u767b\u9332\u3059\u308b\u3053\u3068\u3067\u3001\u62e0\u70b9\u5185\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8 PC \u304b\u3089\u306e\u30a2\u30af\u30bb\u30b9\u3060\u3051\u3092\u8a31\u53ef\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u308b\u304c\u3001\u5185\u90e8 IP \u7bc4\u56f2\u3092\u6307\u5b9a\u3067\u304d\u308b\u65b9\u304c\u3088\u308a\u7d30\u304b\u306a\u5236\u5fa1\u304c\u3067\u304d\u308b\u3053\u3068\u306f\u8a00\u3046\u307e\u3067\u3082\u306a\u3044\u3002<\/p>\n<p>\u203b\u672c\u8a18\u4e8b\u306b\u306f\u3001<a href=\"https:\/\/blog.grasys.io\/post\/mori\/cloudstorage-bucketipfiltering-with-vpcpeering\/\">\u682a\u5f0f\u4f1a\u793egrasys\u69d8\u306e\u8a18\u4e8b<\/a> \u304b\u3089\u306e\u5f15\u7528\u3092\u542b\u3093\u3067\u3044\u307e\u3059\u3002\u5143\u8a18\u4e8b\u306e\u8457\u4f5c\u6a29\u306f\u540c\u793e\u306b\u5e30\u5c5e\u3057\u3001\u8a31\u8afe\u3092\u5f97\u3066\u63b2\u8f09\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<h2>\u53c2\u8003\u6587\u732e<\/h2>\n<ul>\n<li><a href=\"https:\/\/blog.grasys.io\/post\/mori\/cloudstorage-bucketipfiltering-with-vpcpeering\/\">Cloud Storage \u306e Bucket IP filtering \u5fb9\u5e95\u691c\u8a3c \u301cIP \u5236\u9650 \u00d7 VPC Peering \u3067\u30a2\u30af\u30bb\u30b9\u7ba1\u7406\u3092\u6700\u9069\u5316\u3059\u308b\u69cb\u6210\u30d1\u30bf\u30fc\u30f3\u301c<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/storage\/docs\/ip-filtering-overview?hl=ja\">\u30d0\u30b1\u30c3\u30c8 IP \u30d5\u30a3\u30eb\u30bf\u30ea\u30f3\u30b0<\/a> <a href=\"https:\/\/cloud.google.com\/storage\/docs\/ip-filtering-overview?hl=ja\">https:\/\/cloud.google.com\/storage\/docs\/ip-filtering-overview?hl=ja<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/storage\/docs\/release-notes#November_14_2024\">2024-11-14\u306b Public Preview \u3068\u3057\u3066\u30ea\u30ea\u30fc\u30b9<\/a> <a href=\"https:\/\/cloud.google.com\/storage\/docs\/release-notes#November_14_2024\">https:\/\/cloud.google.com\/storage\/docs\/release-notes#November_14_2024<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja\">\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30db\u30b9\u30c8\u306e\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9\u3092\u69cb\u6210\u3059\u308b<\/a> <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja\">https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access?hl=ja\">\u9650\u5b9a\u516c\u958b\u306e Google \u30a2\u30af\u30bb\u30b9\u3092\u69cb\u6210<\/a> <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access?hl=ja\">https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access?hl=ja<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja#config-routing-on-prem\">Cloud Router \u3092\u4f7f\u7528\u3057\u305f\u30aa\u30f3\u30d7\u30ec\u30df\u30b9 \u30eb\u30fc\u30c6\u30a3\u30f3\u30b0<\/a> <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja#config-routing-on-prem\">https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=ja#config-routing-on-prem<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/iap\/docs\/using-tcp-forwarding?hl=ja#create-firewall-rule\">IAP \u306e\u8a2d\u5b9a<\/a> <a href=\"https:\/\/cloud.google.com\/iap\/docs\/using-tcp-forwarding?hl=ja#create-firewall-rule\">https:\/\/cloud.google.com\/iap\/docs\/using-tcp-forwarding?hl=ja#create-firewall-rule<\/a><\/li>\n<li>\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u304b\u3089 Google API \u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-service-connect-apis?hl=ja#using-endpoints\">\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8\u3092\u4f7f\u7528\u3059\u308b<\/a> <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-service-connect-apis?hl=ja#using-endpoints\">https:\/\/cloud.google.com\/vpc\/docs\/configure-private-service-connect-apis?hl=ja#using-endpoints<\/a><\/li>\n<\/ul>\n<hr \/>\n<h1>VPN and Bucket IP Filtering<\/h1>\n<p>English follows Japanese. (This line is kept from the original for context, but the entire article below is the English translation.)<\/p>\n<h2>Purpose of this Article<\/h2>\n<p>This article has two main objectives.<\/p>\n<p>A secondary objective is to demonstrate an example of configuring Cloud VPN between two projects using only <code>gcloud<\/code> commands. As far as I could find with a quick search, apart from Google Cloud&#8217;s official documentation (which covers same-project setups), there were examples using the Web UI, but no examples using <code>gcloud<\/code> commands were found for inter-project VPNs.<\/p>\n<p>The other main objective is to verify whether Cloud Storage&#8217;s new Bucket IP Filtering feature can be accessed from the destination of a VPN connection.<\/p>\n<p>Conclusion: Access from the VPN connection&#8217;s destination is possible. This is a good thing.<\/p>\n<p>This article is intended for network engineers and cloud architects who have a basic understanding of Google Cloud&#8217;s VPC, IAM, and Cloud Storage.<\/p>\n<p>Since information on inter-project VPNs, other than Google Cloud&#8217;s official documentation, was scarce, this article provides an example configuration using <code>gcloud<\/code> commands (examples with on-premises routers as peers were, as expected, quite common).<\/p>\n<h2>What is Bucket IP Filtering?<\/h2>\n<p>Cloud Storage&#8217;s Bucket IP filtering feature is an access control mechanism that allows you to permit access to a Cloud Storage bucket only from specific IP address ranges <a href=\"https:\/\/cloud.google.com\/storage\/docs\/ip-filtering-overview?hl=en\">Bucket IP Filtering<\/a>.<br \/>\nIt was released as a Public Preview on 2024-11-14 <a href=\"https:\/\/cloud.google.com\/storage\/docs\/release-notes#November_14_2024\">Release Notes<\/a>.<\/p>\n<h2>Can it be used with VPN?<\/h2>\n<p>If a company wants to create a &quot;general-purpose file storage&quot; that is &quot;only accessible from within the company,&quot; Cloud Storage&#8217;s Bucket IP filtering feature might be useful.<\/p>\n<p>Since Global IPs can be specified by CIDR range, if each site has a static IP, you can use Cloud Storage&#8217;s Bucket IP filtering feature to allow access only from specific sites.<\/p>\n<pre><code class=\"language-json\">  &quot;publicNetworkSource&quot;: {\n    &quot;allowedIpCidrRanges&quot;: [\n      &quot;${YOUR_IP}\/32&quot;\n    ],\n  }<\/code><\/pre>\n<p>Another common use case for Google Cloud is VPN configuration. If a Cloud Storage bucket can be accessed only from the destination of a VPN connection, it&#8217;s very convenient as it eliminates other considerations.<\/p>\n<p>To <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=en\">Configure Private Google Access for on-premises hosts<\/a>, the documentation states:<\/p>\n<blockquote>\n<p>Private Google Access for on-premises hosts allows you to connect to Google APIs and services from your on-premises systems by routing traffic through a Cloud VPN tunnel or a VLAN attachment for Cloud Interconnect. Private Google Access for on-premises hosts can be used as an alternative to connecting to Google APIs and services over the internet.<\/p>\n<\/blockquote>\n<p>I want to verify if Bucket IP Filtering can be used when accessing Cloud Storage from the connection destination via <code>private.googleapis.com<\/code>.<\/p>\n<h2>Procedure<\/h2>\n<p>All basic operations will be performed using <code>gcloud<\/code> commands, aiming for reproducibility by simply copying and pasting.<\/p>\n<p>The region for networks and buckets will be <code>us-central1<\/code>.<\/p>\n<p>Create VPC networks 10.1.0.0\/24 and 10.1.1.0\/24 (Note: original text mentioned 10.2.0.0\/24 initially, but 10.1.1.0\/24 is used consistently later) in two Google Cloud projects and connect them via VPN.<br \/>\nConsider 10.1.0.0\/24 as the host side and 10.1.1.0\/24 as the on-premises side (although we&#8217;ll be verifying this on Google Cloud).<\/p>\n<p>network-vpn-host: 10.1.0.0\/24<br \/>\nnetwork-vpn-guest: 10.1.1.0\/24<\/p>\n<h3>Environment Definition<\/h3>\n<p>Define the following according to your reproduction environment.<\/p>\n<p><code>PROJECT_HOST<\/code> is considered the bucket host, and <code>PROJECT_GUEST<\/code> is considered the on-premises environment. <code>YOUR_IP<\/code> is the global IP to allow access from, <code>YOUR_ACCOUNT<\/code> is the operator&#8217;s Google account, and <code>BILLING_ACCOUNT<\/code> is the Google Cloud billing account.<\/p>\n<p><code>SHARED_SECRET<\/code> is the Shared Secret for the VPN connection.<\/p>\n<pre><code class=\"language-sh:\">export PROJECT_HOST=host-project\nexport PROJECT_GUEST=guest-project\nexport YOUR_IP=203.0.113.1\nexport YOUR_ACCOUNT=test@example.com\nexport BILLING_ACCOUNT=&quot;000000-000000-000000&quot;\n\nexport SHARED_SECRET=&quot;bvTtdK7nil68WCYu7+dJ7iYdEmeWCB\/A5Q4lUu2DHac=&quot;<\/code><\/pre>\n<h3>Google Cloud Project Creation and API Enablement<\/h3>\n<pre><code class=\"language-sh:\">for project in $PROJECT_HOST $PROJECT_GUEST; do\n  gcloud projects create $project\n  gcloud billing projects link $project --billing-account=$BILLING_ACCOUNT\n  gcloud services enable compute.googleapis.com --project=$project\ndone<\/code><\/pre>\n<h3>Bucket Creation<\/h3>\n<p>Create the following Cloud Storage buckets in the host project. &#8216;sa&#8217; is an abbreviation for Service Account.<\/p>\n<p>Basically, if we can verify with <code>allUsers<\/code>, the objective of this article will be achieved, but while we&#8217;re at it, let&#8217;s also check the behavior when permissions are granted to a Service Account. Since we want to <code>ls<\/code> later, let&#8217;s also create dummy files.<\/p>\n<table>\n<thead>\n<tr>\n<th>Bucket Name<\/th>\n<th>Access Permission<\/th>\n<th>Bucket IP Filtering<\/th>\n<th>Network<\/th>\n<th>IP Range<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>public-2025-05<\/td>\n<td>allUsers<\/td>\n<td>Disabled<\/td>\n<td>NA<\/td>\n<td>NA<\/td>\n<\/tr>\n<tr>\n<td>private-2025-05<\/td>\n<td>Host project only<\/td>\n<td>Disabled<\/td>\n<td>NA<\/td>\n<td>NA<\/td>\n<\/tr>\n<tr>\n<td>ip-vpn-all-2025-05<\/td>\n<td>allUsers<\/td>\n<td>Enabled<\/td>\n<td>network-vpn-host<\/td>\n<td>10.1.0.0\/16<\/td>\n<\/tr>\n<tr>\n<td>ip-vpn-sa-2025-05<\/td>\n<td>Verifier, host&#8217;s service account<\/td>\n<td>Enabled<\/td>\n<td>network-vpn-host<\/td>\n<td>10.1.0.0\/16<\/td>\n<\/tr>\n<tr>\n<td>ip-allow-all-2025-05<\/td>\n<td>allUsers<\/td>\n<td>Enabled<\/td>\n<td>publicNetworkSource, network-vpn-host<\/td>\n<td>10.1.0.0\/16, <code>${YOUR_IP}\/32<\/code><\/td>\n<\/tr>\n<tr>\n<td>ip-allow-sa-2025-05<\/td>\n<td>Verifier, host&#8217;s service account<\/td>\n<td>Enabled<\/td>\n<td>publicNetworkSource, network-vpn-host<\/td>\n<td>10.1.0.0\/16, <code>${YOUR_IP}\/32<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Although network-vpn-host is 10.1.0.0\/24 and network-vpn-guest is 10.1.1.0\/24, <code>10.1.0.0\/16<\/code> is specified as the IP range that includes &#8216;both&#8217;.<\/p>\n<pre><code class=\"language-sh:\">gcloud storage buckets create gs:\/\/public-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\ngcloud storage buckets add-iam-policy-binding gs:\/\/public-2025-05 --member=allUsers --role=roles\/storage.objectViewer --project=$PROJECT_HOST\n\ngcloud storage buckets create gs:\/\/private-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\n\ngcloud storage buckets create gs:\/\/ip-vpn-all-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\ngcloud storage buckets add-iam-policy-binding gs:\/\/ip-vpn-all-2025-05 --member=allUsers --role=roles\/storage.objectViewer --project=$PROJECT_HOST\n\ngcloud storage buckets create gs:\/\/ip-vpn-sa-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\n# Permissions are granted at the project level, so IAM permission granting for the bucket is omitted\n\ngcloud storage buckets create gs:\/\/ip-allow-all-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\ngcloud storage buckets add-iam-policy-binding gs:\/\/ip-allow-all-2025-05 --member=allUsers --role=roles\/storage.objectViewer --project=$PROJECT_HOST\n\ngcloud storage buckets create gs:\/\/ip-allow-sa-2025-05 --project=$PROJECT_HOST --location=us-central1 --uniform-bucket-level-access\n# Permissions are granted at the project level, so IAM permission granting for the bucket is omitted\n\nmkdir -p dummy_files\nfor bucket_prefix in public private ip-vpn-all ip-vpn-sa ip-allow-all ip-allow-sa; do\n  echo &quot;${bucket_prefix}_2025-05.txt content&quot; &gt; dummy_files\/${bucket_prefix}_2025-05.txt\n  gcloud storage cp dummy_files\/${bucket_prefix}_2025-05.txt gs:\/\/${bucket_prefix}-2025-05\/ --project=$PROJECT_HOST\ndone<\/code><\/pre>\n<h3>VPC Network Creation<\/h3>\n<p>Create VPC network <code>network-vpn-host<\/code> in <code>PROJECT_HOST<\/code> and VPC network <code>network-vpn-guest<\/code> in <code>PROJECT_GUEST<\/code>.<\/p>\n<p>As mentioned earlier:<br \/>\nnetwork-vpn-host: 10.1.0.0\/24<br \/>\nnetwork-vpn-guest: 10.1.1.0\/24<\/p>\n<pre><code class=\"language-sh:\">gcloud compute networks create network-vpn-host --project=$PROJECT_HOST --subnet-mode=custom\ngcloud compute networks subnets create subnet-vpn-host \\\n    --network=network-vpn-host \\\n    --region=us-central1 \\\n    --range=10.1.0.0\/24 \\\n    --project=$PROJECT_HOST\n\ngcloud compute networks create network-vpn-guest --project=$PROJECT_GUEST --subnet-mode=custom\ngcloud compute networks subnets create subnet-vpn-guest \\\n    --network=network-vpn-guest \\\n    --region=us-central1 \\\n    --range=10.1.1.0\/24 \\\n    --project=$PROJECT_GUEST<\/code><\/pre>\n<p>If there&#8217;s a Public IP, the route can be confusing (though it shouldn&#8217;t actually change).<br \/>\nEven without a Public IP, configure <a href=\"https:\/\/cloud.google.com\/iap\/docs\/using-tcp-forwarding?hl=en#create-firewall-rule\">IAP settings<\/a> to allow SSH connections.<\/p>\n<pre><code class=\"language-sh:\">for project in $PROJECT_HOST $PROJECT_GUEST; do\n    gcloud projects add-iam-policy-binding $project \\\n        --member=&quot;user:${YOUR_ACCOUNT}&quot; \\\n        --role=roles\/iap.tunnelResourceAccessor\n    gcloud projects add-iam-policy-binding $project \\\n        --member=&quot;user:${YOUR_ACCOUNT}&quot; \\\n        --role=roles\/compute.instanceAdmin.v1\ndone\n\ngcloud compute firewall-rules create allow-ssh-ingress-from-iap-vpn-host \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=tcp:22 \\\n    --source-ranges=35.235.240.0\/20 \\\n    --network=network-vpn-host \\\n    --project=$PROJECT_HOST\n\ngcloud compute firewall-rules create allow-ssh-ingress-from-iap-vpn-guest \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=tcp:22 \\\n    --source-ranges=35.235.240.0\/20 \\\n    --network=network-vpn-guest \\\n    --project=$PROJECT_GUEST<\/code><\/pre>\n<p>Also, configure <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access?hl=en\">Private Google Access<\/a> so that Google Cloud services can be accessed even without a Public IP.<\/p>\n<p><!-- However, we will also test the case where it's disabled later on the guest side. --><\/p>\n<pre><code class=\"language-sh:\">gcloud compute networks subnets update subnet-vpn-host --project=$PROJECT_HOST \\\n    --region=us-central1 \\\n    --enable-private-ip-google-access\n\ngcloud compute networks subnets update subnet-vpn-guest --project=$PROJECT_GUEST \\\n    --region=us-central1 \\\n    --enable-private-ip-google-access\n\n# To verify, execute the following\n# gcloud compute networks subnets describe subnet-vpn-host --project=$PROJECT_HOST \\\n#     --region=us-central1 \\\n#     --format=&quot;get(privateIpGoogleAccess)&quot;<\/code><\/pre>\n<p>Set up Firewall Rules to allow VMs to communicate with each other.<\/p>\n<pre><code class=\"language-sh:\">gcloud compute firewall-rules create allow-internal-ingress-from-vpn-host \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=all \\\n    --source-ranges=10.1.0.0\/16 \\\n    --network=network-vpn-host \\\n    --project=$PROJECT_HOST\n\ngcloud compute firewall-rules create allow-internal-ingress-from-vpn-guest \\\n    --direction=INGRESS \\\n    --action=allow \\\n    --rules=all \\\n    --source-ranges=10.1.0.0\/16 \\\n    --network=network-vpn-guest \\\n    --project=$PROJECT_GUEST<\/code><\/pre>\n<h3>Inter-Project VPN Configuration<\/h3>\n<p>Set up a VPN between the previously created networks <code>network-vpn-host<\/code> and <code>network-vpn-guest<\/code>.<\/p>\n<p>I decided to omit BGP IPv6 configuration.<\/p>\n<pre><code class=\"language-sh:\"># VPN configuration in PROJECT_HOST\ngcloud compute vpn-gateways create vpn-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --network=network-vpn-host\n\ngcloud compute routers create cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --network network-vpn-host \\\n  --asn 65001\n\n# VPN configuration in PROJECT_GUEST\ngcloud compute vpn-gateways create vpn-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --network=network-vpn-guest\n\ngcloud compute routers create cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --network network-vpn-guest \\\n  --asn 65002<\/code><\/pre>\n<p>Note down the displayed IPs. (These will be dynamically assigned by GCP).<br \/>\nExample:<\/p>\n<pre><code class=\"language-sh\">export HOST_INTERFACE0=34.153.55.144\nexport HOST_INTERFACE1=35.220.88.151\n\nexport GUEST_INTERFACE0=35.242.99.80\nexport GUEST_INTERFACE1=34.153.244.91\n\n# Not tested, but the following command can be used to get the IPs dynamically.\nexport HOST_INTERFACE0=$(gcloud compute vpn-gateways describe vpn-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;value(vpnInterfaces[0].ipAddress)&#039;)\nexport HOST_INTERFACE1=$(gcloud compute vpn-gateways describe vpn-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;value(vpnInterfaces[1].ipAddress)&#039;)\n\nexport GUEST_INTERFACE0=$(gcloud compute vpn-gateways describe vpn-guest --project=$PROJECT_GUEST --region=us-central1 --format=&#039;value(vpnInterfaces[0].ipAddress)&#039;)\nexport GUEST_INTERFACE1=$(gcloud compute vpn-gateways describe vpn-guest --project=$PROJECT_GUEST --region=us-central1 --format=&#039;value(vpnInterfaces[1].ipAddress)&#039;)<\/code><\/pre>\n<pre><code class=\"language-sh:\"># In PROJECT_HOST, register the peer&#039;s information\n# Register the existence of the guest -&gt; host VPN\n# I want to use the following command for external-vpn-gateways, but\n# &gt; You cannot provide interface with IP address associated with HA VPN gateway of Google Cloud.\n# it says, so specify projects\/${PROJECT_GUEST}\/regions\/us-central1\/vpnGateways\/vpn-guest\n\n# gcloud compute external-vpn-gateways create vpngw-guest-host \\\n#   --project=$PROJECT_HOST \\\n#   --interfaces=0=$GUEST_INTERFACE0,1=$GUEST_INTERFACE1 # This would be for non-GCP peer\n\ngcloud compute vpn-tunnels create tunnel-host-guest-0 \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_GUEST}\/regions\/us-central1\/vpnGateways\/vpn-guest \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-host \\\n  --vpn-gateway=vpn-host \\\n  --interface=0\n\ngcloud compute vpn-tunnels create tunnel-host-guest-1 \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_GUEST}\/regions\/us-central1\/vpnGateways\/vpn-guest \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-host \\\n  --vpn-gateway=vpn-host \\\n  --interface=1\n\n# In PROJECT_GUEST, register the peer&#039;s information\n# Register the existence of the host -&gt; guest VPN\n# gcloud compute external-vpn-gateways create vpngw-host-guest \\\n#   --project=$PROJECT_GUEST \\\n#   --interfaces=0=$HOST_INTERFACE0,1=$HOST_INTERFACE1 # This would be for non-GCP peer\n\ngcloud compute vpn-tunnels create tunnel-guest-host-0 \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_HOST}\/regions\/us-central1\/vpnGateways\/vpn-host \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-guest \\\n  --vpn-gateway=vpn-guest \\\n  --interface=0\n\ngcloud compute vpn-tunnels create tunnel-guest-host-1 \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --peer-gcp-gateway=projects\/${PROJECT_HOST}\/regions\/us-central1\/vpnGateways\/vpn-host \\\n  --ike-version=2 \\\n  --shared-secret=$SHARED_SECRET \\\n  --router=cloud-router-guest \\\n  --vpn-gateway=vpn-guest \\\n  --interface=1<\/code><\/pre>\n<p>BGP Configuration<\/p>\n<pre><code class=\"language-sh:\"># HOST\ngcloud compute routers add-interface cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --interface-name=if-tunnel-host-guest-0 \\\n  --vpn-tunnel=tunnel-host-guest-0 \\\n  --region=us-central1 \\\n  --ip-version=IPV4\n\ngcloud compute routers add-bgp-peer cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1 \\\n  --peer-name=peer-tunnel-host-guest-0 \\\n  --interface=if-tunnel-host-guest-0 \\\n  --peer-asn=65002\n\n# AI Suggest below:\n# BGP_PEER_IP_HOST_TUNNEL_0=$(gcloud compute routers get-status cloud-router-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;flattened(result.bgpPeerStatus[].name,result.bgpPeerStatus[].ipAddress,result.bgpPeerStatus[].peerIpAddress)&#039; | grep tunnel-host-guest-0 | awk &#039;{print $3}&#039;)\n# BGP_ROUTER_IP_HOST_TUNNEL_0=$(gcloud compute routers get-status cloud-router-host --project=$PROJECT_HOST --region=us-central1 --format=&#039;flattened(result.bgpPeerStatus[].name,result.bgpPeerStatus[].ipAddress,result.bgpPeerStatus[].peerIpAddress)&#039; | grep tunnel-host-guest-0 | awk &#039;{print $2}&#039;)<\/code><\/pre>\n<pre><code class=\"language-sh\">gcloud compute routers describe cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1<\/code><\/pre>\n<p>Check <code>peerIpAddress<\/code> and configure the IP manually.<\/p>\n<pre><code class=\"language-sh\"># GUEST\ngcloud compute routers add-interface cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --interface-name=if-tunnel-guest-host-0 \\\n  --ip-address=169.254.0.250 \\\n  --mask-length=30 \\\n  --vpn-tunnel=tunnel-guest-host-0 \\\n  --region=us-central1 \\\n  --ip-version=IPV4\n\ngcloud compute routers add-bgp-peer cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1 \\\n  --peer-name=peer-tunnel-guest-host-0 \\\n  --interface=if-tunnel-guest-host-0 \\\n  --peer-asn=65001 \\\n  --peer-ip-address=169.254.0.249<\/code><\/pre>\n<p>Configuration Check<\/p>\n<pre><code class=\"language-sh\">gcloud compute routers describe cloud-router-host \\\n  --project=$PROJECT_HOST \\\n  --region=us-central1\n\ngcloud compute routers describe cloud-router-guest \\\n  --project=$PROJECT_GUEST \\\n  --region=us-central1<\/code><\/pre>\n<h3>VM Instance Creation<\/h3>\n<p>Create VM instances in each VPC network. Specify <code>no-address<\/code> to create VM instances without Public IPs.<\/p>\n<pre><code class=\"language-sh:\">gcloud compute instances create vm-host-vpn \\\n    --project=$PROJECT_HOST \\\n    --zone=us-central1-f \\\n    --machine-type=e2-micro \\\n    --network-interface=stack-type=IPV4_ONLY,subnet=subnet-vpn-host,no-address \\\n    --scopes=https:\/\/www.googleapis.com\/auth\/cloud-platform \\\n    --boot-disk-size 10GB \\\n    --boot-disk-type pd-standard \\\n    --image-project debian-cloud \\\n    --image-family debian-12\n\ngcloud compute instances create vm-guest-vpn \\\n    --project=$PROJECT_GUEST \\\n    --zone=us-central1-f \\\n    --machine-type=e2-micro \\\n    --network-interface=stack-type=IPV4_ONLY,subnet=subnet-vpn-guest,no-address \\\n    --scopes=https:\/\/www.googleapis.com\/auth\/cloud-platform \\\n    --boot-disk-size 10GB \\\n    --boot-disk-type pd-standard \\\n    --image-project debian-cloud \\\n    --image-family debian-12<\/code><\/pre>\n<p>You can SSH into each VM instance as follows:<\/p>\n<pre><code class=\"language-sh\">gcloud compute ssh --zone=us-central1-f vm-host-vpn --tunnel-through-iap --project $PROJECT_HOST\ngcloud compute ssh --zone=us-central1-f vm-guest-vpn --tunnel-through-iap --project $PROJECT_GUEST<\/code><\/pre>\n<p>In the author&#8217;s test, 10.1.0.3 was the host-side VM instance IP, and 10.1.1.3 was the guest-side VM instance IP. (Your IPs will likely differ).<br \/>\nPing from the guest side to the host side VM; if communication is established, there are no issues.<\/p>\n<pre><code class=\"language-sh\"># On vm-guest-vpn\nping &lt;IP_OF_VM-HOST-VPN&gt; # e.g., ping 10.1.0.3<\/code><\/pre>\n<h2>Bucket IP Filtering Verification<\/h2>\n<h3>Access Check Part 1<\/h3>\n<p>First, check if the buckets can be accessed from each VM.<br \/>\nExecute <code>ls_all_buckets.sh<\/code> from each VM to check the bucket list.<\/p>\n<pre><code class=\"language-sh:\">for bucket_prefix in public private ip-vpn-all ip-vpn-sa ip-allow-all ip-allow-sa; do\n  echo &quot;gs:\/\/${bucket_prefix}-2025-05\/&quot;\n  gcloud storage ls gs:\/\/${bucket_prefix}-2025-05\/\ndone<\/code><\/pre>\n<p>vm-host-vpn:<\/p>\n<pre><code>.\/ls_all_buckets.sh \ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\ngs:\/\/private-2025-05\/private_2025-05.txt\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\ngs:\/\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\ngs:\/\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>vm-guest-vpn (Note: The service account for vm-guest-vpn is from PROJECT_GUEST, so it won&#8217;t have inherent access to PROJECT_HOST buckets unless explicitly granted or if buckets are public):<\/p>\n<pre><code>gs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [private-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.<\/code><\/pre>\n<p>(The original output showed the GUEST VM&#8217;s default service account. The actual account ID will vary.)<\/p>\n<p>As shown above (before IP filtering is strictly applied and considering IAM), <code>vm-host-vpn<\/code> can access all buckets (assuming its service account has broad permissions in <code>PROJECT_HOST<\/code>). <code>vm-guest-vpn<\/code> can access buckets that grant <code>allUsers<\/code> read access. For others, it depends on IAM.<\/p>\n<h3>Bucket IP Filtering Configuration<\/h3>\n<p>Configure Bucket IP Filtering for the <code>ip-vpn-all-2025-05<\/code> and <code>ip-vpn-sa-2025-05<\/code> buckets.<\/p>\n<pre><code class=\"language-sh\">cat &lt;&lt;EOF &gt; ip-filter-vpn.json\n{\n  &quot;mode&quot;: &quot;Enabled&quot;,\n  &quot;vpcNetworkSources&quot;: [\n    {\n      &quot;network&quot;: &quot;projects\/${PROJECT_HOST}\/global\/networks\/network-vpn-host&quot;,\n      &quot;allowedIpCidrRanges&quot;: [\n        &quot;10.1.0.0\/16&quot;\n      ]\n    }\n  ]\n}\nEOF<\/code><\/pre>\n<p>Create <code>ip-filter-allow.json<\/code>.<\/p>\n<pre><code class=\"language-sh:\">cat &lt;&lt;EOF &gt; ip-filter-allow.json\n{\n  &quot;mode&quot;: &quot;Enabled&quot;,\n  &quot;publicNetworkSource&quot;: {\n    &quot;allowedIpCidrRanges&quot;: [\n      &quot;${YOUR_IP}\/32&quot;\n    ]\n  },\n  &quot;vpcNetworkSources&quot;: [\n    {\n      &quot;network&quot;: &quot;projects\/${PROJECT_HOST}\/global\/networks\/network-vpn-host&quot;,\n      &quot;allowedIpCidrRanges&quot;: [\n        &quot;10.1.0.0\/16&quot;\n      ]\n    }\n  ]\n}\nEOF<\/code><\/pre>\n<p>Configure Bucket IP Filtering.<\/p>\n<pre><code class=\"language-sh:\">for bucket_prefix in ip-vpn-all ip-vpn-sa; do\n  gcloud alpha storage buckets update gs:\/\/${bucket_prefix}-2025-05 --project=$PROJECT_HOST --ip-filter-file=ip-filter-vpn.json\ndone\n\nfor bucket_prefix in ip-allow-all ip-allow-sa; do\n  gcloud alpha storage buckets update gs:\/\/${bucket_prefix}-2025-05 --project=$PROJECT_HOST --ip-filter-file=ip-filter-allow.json\ndone<\/code><\/pre>\n<p>Expected output:<\/p>\n<pre><code>Updating gs:\/\/ip-vpn-all-2025-05\/...\n  Completed 1\nUpdating gs:\/\/ip-vpn-sa-2025-05\/...\n  Completed 1\nUpdating gs:\/\/ip-allow-all-2025-05\/...\n  Completed 1\nUpdating gs:\/\/ip-allow-sa-2025-05\/...\n  Completed 1<\/code><\/pre>\n<h3>Access Check Part 2<\/h3>\n<p>vm-host-vpn (assuming its IP is within 10.1.0.0\/16 of network-vpn-host):<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\ngs:\/\/private-2025-05\/private_2025-05.txt\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\ngs:\/\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\ngs:\/\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>vm-guest-vpn (now IP filtering is active):<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [private-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-all-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-all-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-all-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.<\/code><\/pre>\n<p>From <code>vm-guest-vpn<\/code>, only <code>public-2025-05<\/code> is accessible. Others are not, due to IAM or IP filtering. The error messages differ depending on the cause.<\/p>\n<h3>Add Static Route<\/h3>\n<p>To make <code>vm-guest-vpn<\/code> access Google APIs via the VPN (and thus appear from <code>network-vpn-host<\/code>&#8216;s IP range for Private Google Access), add a route for <code>private.googleapis.com<\/code> (199.36.153.8\/30) or <code>restricted.googleapis.com<\/code> (199.36.153.4\/30) towards the VPN tunnel on <code>PROJECT_GUEST<\/code>. The article uses <code>199.36.153.8\/30<\/code>.<\/p>\n<pre><code class=\"language-sh\"># gcloud compute routes create private-to-host \\\n#     --project=$PROJECT_GUEST \\\n#     --network=network-vpn-guest \\\n#     --destination-range=199.36.153.8\/30 \\\n#     --priority=200 \\\n#     --next-hop-gateway=projects\/$PROJECT_HOST\/global\/vpnGateways\/vpn-host\n\ngcloud compute routes create private-to-host \\\n    --project=$PROJECT_GUEST \\\n    --network=network-vpn-guest \\\n    --destination-range=199.36.153.8\/30 \\\n    --priority=200 \\\n    --next-hop-vpn-tunnel-region=us-central1 \\\n    --next-hop-vpn-tunnel=tunnel-guest-host-0<\/code><\/pre>\n<h3>\u3010Reference\u3011Cloud Router Configuration Change<\/h3>\n<p>As described in <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=en#config-routing-on-prem\">Routing on-premises using Cloud Router<\/a>, the host-side Cloud Router (<code>cloud-router-host<\/code>) can advertise routes for the IP ranges used by the <code>private.googleapis.com<\/code> domain to the guest side (on-premises side, i.e., <code>cloud-router-guest<\/code>).<\/p>\n<p>Since it worked with a static route, it is believed that the above BGP advertisement method would also work. Specific verification has not been performed in this article, so I encourage you to verify this.<\/p>\n<h3>Access Check Part 3<\/h3>\n<p>Conclusion: With the appropriate settings (static route for <code>private.googleapis.com<\/code> and DNS\/Host override), <code>gs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt<\/code> and <code>gs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt<\/code> become additionally accessible from <code>vm-guest-vpn<\/code>.<\/p>\n<h4>The <code>\/etc\/hosts<\/code> Method<\/h4>\n<p>On <code>vm-guest-vpn<\/code>, add the following line to <code>\/etc\/hosts<\/code>:<\/p>\n<pre><code>199.36.153.8 storage.googleapis.com<\/code><\/pre>\n<p>Then, accessing <code>storage.googleapis.com<\/code> will resolve to <code>199.36.153.8<\/code>. Since a static route is configured for access to <code>199.36.153.8\/30<\/code> to go via VPN, it should be accessed via VPN, and the source IP seen by Cloud Storage should be from <code>network-vpn-host<\/code>&#8216;s NAT range for Private Google Access.<\/p>\n<p>Let&#8217;s run <code>.\/ls_all_buckets.sh<\/code> again on <code>vm-guest-vpn<\/code>:<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [private-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-all-2025-05\/\ngs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) [886786442757-compute@developer.gserviceaccount.com] does not have permission to access b instance [ip-allow-sa-2025-05] (or it may not exist): 886786442757-compute@developer.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket. Permission &#039;storage.objects.list&#039; denied on resource (or it may not exist). This command is authenticated as 886786442757-compute@developer.gserviceaccount.com which is the active account specified by the [core\/account] property.<\/code><\/pre>\n<p><code>gs:\/\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt<\/code> and <code>gs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt<\/code> became additionally accessible (assuming IAM allows <code>allUsers<\/code> for these).<\/p>\n<h4>The Endpoint Override Method<\/h4>\n<p>TL;DR: It&#8217;s necessary to combine with <code>\/etc\/hosts<\/code> or DNS for <code>gcloud<\/code> to work correctly with <code>private.googleapis.com<\/code>.<\/p>\n<p>Revert the <code>\/etc\/hosts<\/code> settings on <code>vm-guest-vpn<\/code>.<\/p>\n<p>The <code>gcloud<\/code> command can override API endpoints.<\/p>\n<pre><code class=\"language-sh\"># On vm-guest-vpn\ngcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/<\/code><\/pre>\n<p>This will cause <code>gcloud<\/code> to attempt to access <code>private.googleapis.com<\/code> instead of <code>storage.googleapis.com<\/code>. With the static route for <code>199.36.153.8\/30<\/code> via VPN, traffic should be routed correctly.<\/p>\n<p>Let&#8217;s run <code>.\/ls_all_buckets.sh<\/code> again on <code>vm-guest-vpn<\/code>:<\/p>\n<pre><code>.\/ls_all_buckets.sh\ngs:\/\/public-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/public-2025-05 not found: 404.\ngs:\/\/private-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/private-2025-05 not found: 404.\ngs:\/\/ip-vpn-all-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-vpn-all-2025-05 not found: 404.\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-vpn-sa-2025-05 not found: 404.\ngs:\/\/ip-allow-all-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-allow-all-2025-05 not found: 404.\ngs:\/\/ip-allow-sa-2025-05\/\nERROR: (gcloud.storage.ls) gs:\/\/ip-allow-sa-2025-05 not found: 404.<\/code><\/pre>\n<p>&#8230;It didn&#8217;t work.<\/p>\n<p>An important point here is that this setting alone did not work as expected, and access failed. Please pay attention to this result.<\/p>\n<p>Trying <code>gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/storage\/v1\/<\/code> also resulted in an error. The reason for the access failure is related to the <code>Host<\/code> header.<\/p>\n<p>Trying <code>gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/storage\/<\/code> also resulted in an error.<\/p>\n<p>Let&#8217;s check the request by adding <code>--log-http<\/code>:<\/p>\n<pre><code class=\"language-sh\"># On vm-guest-vpn\ngcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/storage\/v1\/\ngcloud storage ls gs:\/\/public-2025-05 --log-http<\/code><\/pre>\n<p>A request like this is being sent:<\/p>\n<pre><code>https:\/\/private.googleapis.com\/storage\/v1\/b\/public-2025-05\/o?alt=json&amp;fields=prefixes%2Citems%2Fname%2Citems%2Fsize%2Citems%2Fgeneration%2CnextPageToken&amp;delimiter=%2F&amp;includeFoldersAsPrefixes=True&amp;maxResults=1000&amp;projection=noAcl<\/code><\/pre>\n<p>If you try with <code>curl<\/code>:<\/p>\n<pre><code class=\"language-sh\"># On vm-guest-vpn\n# This will likely fail with 404 because private.googleapis.com expects Host: storage.googleapis.com for this path\ncurl &quot;https:\/\/private.googleapis.com\/storage\/v1\/b\/public-2025-05\/o?alt=json&amp;fields=prefixes%2Citems%2Fname%2Citems%2Fsize%2Citems%2Fgeneration%2CnextPageToken&amp;delimiter=%2F&amp;includeFoldersAsPrefixes=True&amp;maxResults=1000&amp;projection=noAcl&quot;\n\n# This should work if routing to private.googleapis.com is correct\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/storage\/v1\/b\/public-2025-05\/o?alt=json&amp;fields=prefixes%2Citems%2Fname%2Citems%2Fsize%2Citems%2Fgeneration%2CnextPageToken&amp;delimiter=%2F&amp;includeFoldersAsPrefixes=True&amp;maxResults=1000&amp;projection=noAcl&quot;<\/code><\/pre>\n<p>The second <code>curl<\/code> (with <code>Host: storage.googleapis.com<\/code>) returns:<\/p>\n<pre><code class=\"language-json\">{\n  &quot;items&quot;: [\n    {\n      &quot;name&quot;: &quot;public_2025-05.txt&quot;,\n      &quot;generation&quot;: &quot;1746452844041206&quot;,\n      &quot;size&quot;: &quot;19&quot;\n    }\n  ]\n}<\/code><\/pre>\n<p>In other words, the server side (Google APIs) looks at the <code>Host<\/code> header. <code>gcloud<\/code> with <code>api_endpoint_overrides<\/code> sends <code>Host: private.googleapis.com<\/code>, which is not what the storage service endpoint expects for these paths.<\/p>\n<p>Even with <code>gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/<\/code>, the <code>Host<\/code> header sent by <code>gcloud<\/code> will be <code>private.googleapis.com<\/code>.<\/p>\n<p>If you try <code>gcloud config set api_endpoint_overrides\/storage https:\/\/199.36.153.8\/<\/code> and <code>gcloud config set auth\/disable_ssl_validation True<\/code>:<\/p>\n<pre><code class=\"language-sh\">gcloud config set api_endpoint_overrides\/storage https:\/\/199.36.153.8\/\ngcloud config set auth\/disable_ssl_validation True\ngcloud storage ls gs:\/\/public-2025-05 --log-http<\/code><\/pre>\n<p>This results in a 401 Unauthorized error, as the server expects a valid <code>Host<\/code> header for authentication context and SNI for SSL.<\/p>\n<pre><code>gcloud storage ls gs:\/\/public-2025-05\n\/usr\/bin\/..\/lib\/google-cloud-sdk\/lib\/third_party\/urllib3\/connectionpool.py:1102: InsecureRequestWarning: Unverified HTTPS request is being made to host &#039;199.36.153.8&#039;. Adding certificate verification is strongly advised. See: https:\/\/urllib3.readthedocs.io\/en\/latest\/advanced-usage.html#tls-warnings\n  warnings.warn(\n\/usr\/bin\/..\/lib\/google-cloud-sdk\/lib\/third_party\/urllib3\/connectionpool.py:1102: InsecureRequestWarning: Unverified HTTPS request is being made to host &#039;199.36.153.8&#039;. Adding certificate verification is strongly advised. See: https:\/\/urllib3.readthedocs.io\/en\/latest\/advanced-usage.html#tls-warnings\n  warnings.warn(\nERROR: (gcloud.storage.ls) HTTPError 401: &lt;!DOCTYPE html&gt;\n&lt;html lang=en&gt;\n  &lt;meta charset=utf-8&gt;\n  &lt;meta name=viewport content=&quot;initial-scale=1, minimum-scale=1, width=device-width&quot;&gt;\n  &lt;title&gt;Error 401 (Unauthorized)!!1&lt;\/title&gt;\n  &lt;style&gt;\n    *{margin:0;padding:0}html,code{font:15px\/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* &gt; body{background:url(\/\/www.google.com\/images\/errors\/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/1x\/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) no-repeat 0% 0%\/100% 100%;-moz-border-image:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}\n  &lt;\/style&gt;\n  &lt;a href=\/\/www.google.com\/&gt;&lt;span id=logo aria-label=Google&gt;&lt;\/span&gt;&lt;\/a&gt;\n  &lt;p&gt;&lt;b&gt;401.&lt;\/b&gt; &lt;ins&gt;That\u2019s an error.&lt;\/ins&gt;\n  &lt;p&gt;Your client does not have permission to the requested URL &lt;code&gt;\/storage\/v1\/b\/public-2025-05\/o&lt;\/code&gt;.  &lt;ins&gt;That\u2019s all we know.&lt;\/ins&gt;<\/code><\/pre>\n<p>So, in conclusion, simply overriding the endpoint for <code>gcloud<\/code> doesn&#8217;t work due to <code>Host<\/code> header issues.<\/p>\n<h4>Considerations for the Endpoint Override Method<\/h4>\n<p>Let&#8217;s try adding the following to <code>\/etc\/hosts<\/code> on <code>vm-guest-vpn<\/code>. One of them intentionally has <code>e<\/code> removed from <code>storage<\/code>.<\/p>\n<pre><code>199.36.153.8 storage-dummy.p.googleapis.com\n199.36.153.8 storag-dummy.p.googleapis.com<\/code><\/pre>\n<p>Then try:<\/p>\n<pre><code class=\"language-sh\"># On vm-guest-vpn\ngcloud config set api_endpoint_overrides\/storage https:\/\/storage-dummy.p.googleapis.com\/\ngcloud storage ls gs:\/\/public-2025-05<\/code><\/pre>\n<p>This works and returns:<\/p>\n<pre><code>gs:\/\/public-2025-05\/public_2025-05.txt<\/code><\/pre>\n<p>Because <code>storage-dummy.p.googleapis.com<\/code> resolves to <code>199.36.153.8<\/code> (routed via VPN), and <code>gcloud<\/code> sends <code>Host: storage-dummy.p.googleapis.com<\/code>. The Private Google Access endpoint is somewhat lenient with <code>SERVICE-ENDPOINT.p.googleapis.com<\/code> hostnames.<\/p>\n<p>However, if you use a name that doesn&#8217;t match the <code>SERVICE-*.p.googleapis.com<\/code> pattern for the <code>Host<\/code> header:<\/p>\n<pre><code class=\"language-sh\"># On vm-guest-vpn\ngcloud config set api_endpoint_overrides\/storage https:\/\/storag-dummy.p.googleapis.com\/ # Note: &quot;storag&quot;\ngcloud storage ls gs:\/\/public-2025-05<\/code><\/pre>\n<p>This results in:<\/p>\n<pre><code>ERROR: (gcloud.storage.ls) gs:\/\/public-2025-05 not found: 404.<\/code><\/pre>\n<p>In &#8216;Accessing Google APIs from endpoints&#8217; under &#8216;Access global Google APIs&#8217;, there is an item <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-service-connect-apis?hl=en#using-endpoints\">Using endpoints<\/a>. According to this:<\/p>\n<blockquote>\n<p>For example, if the endpoint name is <code>xyz<\/code>, DNS records are created for <code>storage-xyz.p.googleapis.com<\/code>, <code>compute-xyz.p.googleapis.com<\/code>, and other commonly used APIs in the API bundle.<br \/>\nNote: If you are developing custom libraries that can use endpoints, you must set the Host header and SNI to a valid hostname for the service to which you are sending requests. A valid hostname is either the service-specific default domain name (e.g., <code>storage.googleapis.com<\/code>) or the service&#8217;s <code>SERVICE-ENDPOINT.p.googleapis.com<\/code> DNS name (if available). For the <code>SERVICE-ENDPOINT.p.googleapis.com<\/code> name, the <code>SERVICE<\/code> part of the name must match the service, but you can use any value for <code>ENDPOINT<\/code>.<\/p>\n<\/blockquote>\n<p>This document supports the idea that the endpoint side responds based on &#8216;what <code>Host<\/code> it is being called with&#8217;.<\/p>\n<p>In conclusion, if you want to connect using <code>gcloud<\/code>&#8216;s Endpoint Override to <code>private.googleapis.com<\/code> effectively for Storage:<\/p>\n<ol>\n<li>You need DNS resolution (e.g., via <code>\/etc\/hosts<\/code> or actual DNS) for <code>storage.googleapis.com<\/code> to point to an IP of <code>private.googleapis.com<\/code> (e.g., 199.36.153.8). Then, <code>gcloud<\/code> will work without endpoint override, sending <code>Host: storage.googleapis.com<\/code>.<\/li>\n<li>Or, use a <code>SERVICE-ENDPOINT.p.googleapis.com<\/code> style hostname (e.g., <code>storage-myendpoint.p.googleapis.com<\/code>) that resolves to an IP of <code>private.googleapis.com<\/code>, and set <code>api_endpoint_overrides\/storage<\/code> to <code>https:\/\/storage-myendpoint.p.googleapis.com\/<\/code>.<\/li>\n<\/ol>\n<p>It would be nice if Google provided a canonical name like <code>storage.private.googleapis.com<\/code> that worked out of the box.<br \/>\nBy the way, <code>storage-private.googleapis.com<\/code> (if it existed and resolved to <code>private.googleapis.com<\/code> IPs) might work with <code>gcloud<\/code>&#8216;s endpoint override. The author notes <code>storage-private.googleapis.com<\/code> (the actual domain) seems to resolve to the public <code>storage.googleapis.com<\/code>.<\/p>\n<p>Note: Don&#8217;t forget to revert the <code>gcloud config<\/code> settings. You can revert them by executing the following commands on <code>vm-guest-vpn<\/code>:<\/p>\n<pre><code class=\"language-sh\">gcloud config unset auth\/disable_ssl_validation\ngcloud config unset api_endpoint_overrides\/storage\n# And remove entries from \/etc\/hosts<\/code><\/pre>\n<h4>The <code>curl<\/code> Method<\/h4>\n<p>Now, <code>curl<\/code> can specify the <code>Host<\/code> header with the <code>-H<\/code> option. We have more freedom here.<br \/>\nFirst, let&#8217;s confirm an example where access is &#8216;not possible&#8217; or &#8216;denied by IP filter&#8217; when going through public endpoints from <code>vm-guest-vpn<\/code> (assuming no <code>\/etc\/hosts<\/code> modification).<\/p>\n<pre><code class=\"language-sh:\"># On vm-guest-vpn\necho &quot;curl https:\/\/storage.googleapis.com\/public-2025-05\/public_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/public-2025-05\/public_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/private-2025-05\/private_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/private-2025-05\/private_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\necho &quot;curl https:\/\/storage.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt&quot;\ncurl https:\/\/storage.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>Output from vm-guest-vpn (public internet access, IP filtering will block):<\/p>\n<pre><code>curl https:\/\/storage.googleapis.com\/public-2025-05\/public_2025-05.txt\npublic_2025-05.txt content\ncurl https:\/\/storage.googleapis.com\/private-2025-05\/private_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\ncurl https:\/\/storage.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;<\/code><\/pre>\n<p>Since the access path doesn&#8217;t change (still public internet), the results for IP-filtered buckets show IP filtering denial.<\/p>\n<p>Now, let&#8217;s change the endpoint to <code>private.googleapis.com<\/code> (which resolves to 199.36.153.8, routed via VPN) and use <code>curl<\/code> with the correct <code>Host<\/code> header.<\/p>\n<pre><code class=\"language-sh:\">echo &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/public-2025-05\/public_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/public-2025-05\/public_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/private-2025-05\/private_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/private-2025-05\/private_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\necho &quot;curl -H \\&quot;Host: storage.googleapis.com\\&quot; \\&quot;https:\/\/private.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt\\&quot;&quot;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt&quot;<\/code><\/pre>\n<p>(Note: The original <code>curl<\/code> examples used XML API paths like <code>https:\/\/storage.googleapis.com\/BUCKET_NAME\/OBJECT_NAME<\/code>. For <code>private.googleapis.com<\/code>, it&#8217;s generally better to use JSON API paths like <code>https:\/\/private.googleapis.com\/storage\/v1\/b\/BUCKET_NAME\/o\/OBJECT_NAME?alt=media<\/code> or the <code>www.googleapis.com\/download\/storage\/v1\/...<\/code> path. The original article&#8217;s <code>curl<\/code> to <code>private.googleapis.com\/BUCKET\/OBJECT<\/code> might have worked due to some flexibility in the endpoint, but explicit API paths are more robust. I&#8217;ve updated to use a common JSON API path for object download.)<\/p>\n<p>Output from vm-guest-vpn (using <code>private.googleapis.com<\/code> via VPN, with correct <code>Host<\/code> header):<\/p>\n<pre><code>curl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/public-2025-05\/public_2025-05.txt&quot;\npublic_2025-05.txt\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/private-2025-05\/private_2025-05.txt&quot;\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\nip-vpn-all_2025-05.txt\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-sa-2025-05\/ip-vpn-sa_2025-05.txt&quot;\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\nip-allow-all_2025-05.txt\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt&quot;\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object. Permission &#039;storage.objects.get&#039; denied on resource (or it may not exist).&lt;\/Details&gt;&lt;\/Error&gt;<\/code><\/pre>\n<p>Note that the results have changed for <code>ip-vpn-all-2025-05<\/code> and <code>ip-allow-all-2025-05<\/code>. Let&#8217;s highlight the important points:<\/p>\n<p>Previously (Accessing <code>storage.googleapis.com<\/code> directly, which goes over public internet from <code>vm-guest-vpn<\/code>):<\/p>\n<pre><code># NG\ncurl https:\/\/storage.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\n\n# OK\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-vpn-all-2025-05\/ip-vpn-all_2025-05.txt&quot;\nip-vpn-all_2025-05.txt\n\n# NG\ncurl https:\/\/storage.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\n&lt;?xml version=&#039;1.0&#039; encoding=&#039;UTF-8&#039;?&gt;&lt;Error&gt;&lt;Code&gt;AccessDenied&lt;\/Code&gt;&lt;Message&gt;Access denied.&lt;\/Message&gt;&lt;Details&gt;There is an IP filtering condition that is preventing access to the resource.&lt;\/Details&gt;&lt;\/Error&gt;\n\n# OK\ncurl -H &quot;Host: storage.googleapis.com&quot; &quot;https:\/\/private.googleapis.com\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt&quot;\nip-allow-all_2025-05.txt<\/code><\/pre>\n<p>Similar changes for <code>ip-allow-all-2025-05<\/code>.<br \/>\nIt was confirmed that even using the <code>curl<\/code> command (with proper routing and Host header), access is possible from IP ranges allowed by Bucket IP Filtering when traffic originates from the VPN.<\/p>\n<h3>Access Check Part 4<\/h3>\n<p>Let&#8217;s also check access from the author&#8217;s home (using <code>YOUR_IP<\/code> which is allowed in <code>ip-allow-*-2025-05<\/code> buckets, and assuming <code>gcloud<\/code> is authenticated as <code>YOUR_ACCOUNT<\/code> which has necessary IAM). The email address has been replaced with <code>test@example.com<\/code>.<br \/>\nRunning <code>ls_all_buckets.sh<\/code> from the local machine (where <code>YOUR_IP<\/code> is the public IP):<\/p>\n<pre><code>gs:\/\/public-2025-05\/\ngs:\/\/public-2025-05\/public_2025-05.txt\ngs:\/\/private-2025-05\/\ngs:\/\/private-2025-05\/private_2025-05.txt\ngs:\/\/ip-vpn-all-2025-05\/\nERROR: (gcloud.storage.ls) [test@example.com] does not have permission to access b instance [ip-vpn-all-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as test@example.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-vpn-sa-2025-05\/\nERROR: (gcloud.storage.ls) [test@example.com] does not have permission to access b instance [ip-vpn-sa-2025-05] (or it may not exist): There is an IP filtering condition that is preventing access to the resource. This command is authenticated as test@example.com which is the active account specified by the [core\/account] property.\ngs:\/\/ip-allow-all-2025-05\/\ngs:\/\/ip-allow-all-2025-05\/ip-allow-all_2025-05.txt\ngs:\/\/ip-allow-sa-2025-05\/\ngs:\/\/ip-allow-sa-2025-05\/ip-allow-sa_2025-05.txt<\/code><\/pre>\n<p>Therefore:<\/p>\n<ul>\n<li>Access to two buckets (<code>ip-vpn-all<\/code> and <code>ip-vpn-sa<\/code> without <code>YOUR_IP<\/code> in their filter) is not possible because the source IP (<code>YOUR_IP<\/code>) is outside the VPN IP Range allowed for them.<\/li>\n<li>Access is possible if the external IP (<code>YOUR_IP<\/code>) is configured in the bucket&#8217;s IP filter (<code>ip-allow-all<\/code>, <code>ip-allow-sa<\/code>).<\/li>\n<li>IAM permissions are also correctly evaluated.<\/li>\n<\/ul>\n<h2>Finally<\/h2>\n<p>In this article, we configured a Cloud VPN between two Google Cloud projects using <code>gcloud<\/code> commands and verified that Cloud Storage&#8217;s Bucket IP Filtering feature can be used via this VPN connection. By utilizing the <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/private-google-access-hybrid?hl=en\">Private Google Access for on-premises hosts<\/a> mechanism, it is possible to make access from the VPN peer network (in this article, <code>network-vpn-guest<\/code>) be recognized as access from a permitted IP range within the VPC network configured on the bucket side (<code>network-vpn-host<\/code>).<\/p>\n<p>Let&#8217;s reconfirm the main steps and points to note obtained through this verification:<\/p>\n<ol>\n<li><strong>Importance of Route Configuration:<\/strong> To access a bucket with Bucket IP Filtering configured from the VPN peer side (guest VM), it is essential to configure either a <strong>static route<\/strong> (adopted in this article) or <strong>BGP route advertisement by Cloud Router<\/strong> so that traffic to <code>private.googleapis.com<\/code> (199.36.153.8\/30) goes through the VPN tunnel. Forgetting this will cause traffic to go via the internet (or an endpoint within the peer VPN if Private Google Access is not correctly configured on the guest VPC), failing to meet the IP Filtering conditions.<\/li>\n<li><strong>Points to Note When Using <code>gcloud<\/code> Commands:<\/strong>\n<ul>\n<li>When trying to access via <code>private.googleapis.com<\/code> with the <code>gcloud storage<\/code> command, simply setting <code>gcloud config set api_endpoint_overrides\/storage https:\/\/private.googleapis.com\/<\/code> is <strong>insufficient<\/strong>. This is because the <code>Host<\/code> header of the request sent by <code>gcloud<\/code> (which becomes <code>private.googleapis.com<\/code>) prevents the API side from processing the request correctly for standard storage operations.<\/li>\n<li>To work around this with <code>gcloud<\/code>, you would typically need appropriate DNS configuration (e.g., making <code>storage.googleapis.com<\/code> resolve to an IP of <code>private.googleapis.com<\/code> via <code>\/etc\/hosts<\/code> or internal DNS, and not using endpoint override) or use a <code>SERVICE-ENDPOINT.p.googleapis.com<\/code> style hostname (e.g., <code>storage-myendpoint.p.googleapis.com<\/code> resolving to <code>private.googleapis.com<\/code> IPs) with the endpoint override.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Direct Access with <code>curl<\/code>, etc.:<\/strong> When using a tool like <code>curl<\/code> that can explicitly specify the <code>Host<\/code> header, by specifying <code>private.googleapis.com<\/code> (or its IP) in the access URL and adding the <code>-H &quot;Host: storage.googleapis.com&quot;<\/code> option, verification of VPN access and IP Filtering is possible without complex DNS or <code>gcloud<\/code> specific workarounds. This is a useful method for understanding API behavior.<\/li>\n<li><strong>IP Filtering and IAM are Separate:<\/strong> Bucket IP Filtering is, strictly speaking, a feature that &#8216;<strong>adds<\/strong>&#8216; filtering based on the source IP address at the network level. In addition to this, the accessing user or service account must be granted appropriate <strong>IAM permissions<\/strong> (e.g., <code>roles\/storage.objectViewer<\/code>). Access is permitted only when both conditions are met.<\/li>\n<\/ol>\n<p>Bucket IP Filtering can be an effective means of strengthening access control from internal networks connected by VPN or Cloud Interconnect. However, especially when using client tools like <code>gcloud<\/code>, it is important to understand the behavior of Private Google Access endpoints and the <code>Host<\/code> header. It is advisable to have a good understanding of the explanation for <a href=\"https:\/\/cloud.google.com\/vpc\/docs\/private-google-access-hybrid?hl=en\">Private Google Access for on-premises hosts<\/a>.<\/p>\n<p>It was found that Bucket IP Filtering can permit or deny access by considering it as &quot;access from a specific IP range from a specific VPC network,&quot; even when using the aforementioned VPN connection. This is convenient as clients, even those without specific service account permissions (for public buckets), can access resources if their IP is allowed and they use a valid SSL certificate.<\/p>\n<p>Of course, since global IPs can also be individually permitted, you can allow access only from client PCs within a site by registering the site&#8217;s external IP, but it goes without saying that being able to specify internal IP ranges (via VPC network source in the filter) allows for more granular control.<\/p>\n<p>\u203b This article includes citations from an article by \u682a\u5f0f\u4f1a\u793egrasys. (<a href=\"https:\/\/blog.grasys.io\/post\/mori\/cloudstorage-bucketipfiltering-with-vpcpeering\/\">link to grasys article<\/a>). The copyright of the original article belongs to grasys Inc., and it is reproduced here with permission.<\/p>\n<h2>References<\/h2>\n<ul>\n<li><a href=\"https:\/\/blog.grasys.io\/post\/mori\/cloudstorage-bucketipfiltering-with-vpcpeering\/\">Thorough Verification of Cloud Storage Bucket IP Filtering \uff5eConfiguration Patterns for Optimizing Access Management with IP Restrictions \u00d7 VPC Peering\uff5e<\/a> (in Japanese)<\/li>\n<li><a href=\"https:\/\/cloud.google.com\/storage\/docs\/ip-filtering-overview?hl=en\">Bucket IP filtering overview<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/storage\/docs\/release-notes#November_14_2024\">Cloud Storage Release Notes (November 14, 2024)<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=en\">Configure Private Google Access for on-premises hosts<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access?hl=en\">Configure Private Google Access<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-google-access-hybrid?hl=en#config-routing-on-prem\">Routing on-premises using Cloud Router<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/iap\/docs\/using-tcp-forwarding?hl=en#create-firewall-rule\">Using IAP for TCP forwarding (Firewall rule creation)<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/vpc\/docs\/configure-private-service-connect-apis?hl=en#using-endpoints\">Accessing Google APIs from endpoints (Using endpoints)<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>VPN \u3068 Bucket IP Filtering English follows Japanese. \u672c\u8a18\u4e8b\u306e\u76ee\u7684 \u672c\u8a18\u4e8b\u306e\u76ee\u7684\u306f2\u3064\u3042\u308b\u3002 \u526f\u6b21\u7684\u306a\u76ee\u7684\u306f\u30012\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u9593\u306e Cloud VPN \u306e\u69cb\u6210\u3092\u3001gclou [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[13],"tags":[],"class_list":["post-573","post","type-post","status-publish","format-standard","hentry","category-google-cloud"],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p4dIdP-9f","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/posts\/573","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/comments?post=573"}],"version-history":[{"count":2,"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/posts\/573\/revisions"}],"predecessor-version":[{"id":575,"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/posts\/573\/revisions\/575"}],"wp:attachment":[{"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/media?parent=573"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/categories?post=573"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tako.nakano.net\/blog\/wp-json\/wp\/v2\/tags?post=573"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}