私有内部访问—将流量限制在内网中

作者:MeshCloud脉时云公有云架构师 陈满

概述:

通过 Private Service Connect,您可以使用 VPC 网络中的全局内部 IP 地址创建私有终端节点。 您可以使用自定义的域名(如
storage-pscendpoint.p.googleapis.com)将 DNS 名称分配给这些内部 IP 地址。 将请求发送到私有服务连接终端节点,而不是发送 API 请求到GCP 的公共服务终端节点(例如 storage.googleapis.com),该终端节点是您的 VPC 网络的私有和内部访问节点。

这些域名和 IP 地址位于项目的 VPC 网络以及使用 Cloud VPN 或 Cloud Interconnect 连接 (VLAN) 连接到它的任何本地网络的内部网络。

可以控制哪些流量流向哪个端点,并可以控制且证明流量保留在 Google Cloud 中。

架构图:

场景描述:

客户需要混合使用私有(互连)和Public googleapis 访问以进行云存储数据传输。 为了满足我们客户的要求,我们将部署由唯一的 /32 地址、BOTO 配置和 DNS 记录更新组成的 Private Service Connect。 虚拟机 1 将利用 PSC 进行云存储桶访问; 相反,VM2 将通过 NAT GW 使用公共 googleapis.com IP 范围。

实验室的所有方面都部署在 Google Cloud Platform 中,但同样的用例也适用于需要流量分离的混合云部署。

要求与限制:

  • 在没有外部 IP 地址的虚拟机 (VM) 实例的主NIC 必须位于启用了 Private Google Access 的子网中。
  • 具有外部 IP 地址的 VM 可以使用 Private Service Connect 端点访问 Google API 和服务,无论是否为其子网启用了 Private Google Access。 与 Private Service Connect 端点的连接保持 Google 的网络中。
  • 无法从Peering VPC 网络访问 Private Service Connect 终端节点,即不能跨VPC 访问Private Service Connect endpoint。

测试与实现环境

1、实现步骤

1、启用必须的API 服务

2、创建demo VPC,并创建ssh firewall 规则

3、创建Private Service Connect 连接点

4、创建测试GCS bucket ;

5、验证通过连接点的DNS 连接点

  • 验证默认的VM 访问的连接点
  • 验证Gsutil lookup 记录

2、部署验证过程

2.1、启用必须的API 服务

gcloud services enable compute.googleapis.com
gcloud services enable servicedirectory.googleapis.com
gcloud services enable dns.googleapis.com

2.2、创建demo VPC,并创建ssh firewall 规则

创建 VPC network:

gcloud compute networks create psc-demo --subnet-mode custom

创建Demo subnet,并创建防火墙规则:

# 创建Subnet 
gcloud compute networks subnets create pscdemo-subnet \
--network psc-demo \
--range 10.0.0.0/24 \
--region us-central1 \
--enable-private-ip-google-access    ## 启用Private Global Access

## 创建允许Cloud Shell 的IAP 访问防火墙规则:
gcloud compute firewall-rules create pscdemo-ssh \
    --network psc-demo --allow tcp:22 --source-ranges=35.235.240.0/20

创建 Cloud NAT 实例,用于VM 访问互联网与通过互联网验证访问:

## 创建用于Cloud  NAT  的Cloud Routers 
gcloud compute routers create crnat \
    --network psc-demo \
    --asn 65000 \
    --region us-central1

## 创建Cloud NAT instance:
gcloud compute routers nats create cloudnat \
    --router=crnat \
    --auto-allocate-nat-external-ips \
    --nat-all-subnet-ip-ranges \
    --enable-logging \
    --region us-central1

2.3、创建Private Service Connect 连接点

配置 Private Service Connect 终端节点 IP 时,您需要提供一个未在您的 VPC 中定义的唯一 IP 地址。(Choose an IP address for the Private Service Connect endpoint

创建Private Service Connect Endpoint IP 地址:

gcloud compute addresses create psc-ip \
    --global \
    --purpose=PRIVATE_SERVICE_CONNECT \
    --addresses=10.10.110.10 \
    --network=psc-demo

## 获取psc-ip 的地址:
pscendpointip=$(gcloud compute addresses list \
        --filter=name:psc-ip --format="value(address)")

echo $pscendpointip

创建转发规则以将端点连接到 Google API 和服务

gcloud compute forwarding-rules create pscendpoint \
    --global \
    --network=psc-demo \
    --address=psc-ip \
    --target-google-apis-bundle=all-apis

列出与查看PSC 信息:

gcloud compute forwarding-rules list  \
--filter target="(all-apis OR vpc-sc)" --global

## 查看PSC 信息
gcloud compute forwarding-rules describe \
    pscendpoint --global

IPAddress: 10.10.110.10
IPProtocol: TCP
creationTimestamp: '2022-11-03T06:41:39.597-07:00'
id: '6005232081134582780'
kind: compute#forwardingRule
labelFingerprint: 42WmSpB8rSM=
name: pscendpoint
network: https://www.googleapis.com/compute/v1/projects/yunion/global/networks/psc-demo
pscConnectionId: '32833899864944138'
selfLink: https://www.googleapis.com/compute/v1/projects/yunion/global/forwardingRules/pscendpoint
serviceDirectoryRegistrations:
- namespace: goog-psc-psc-demo-3117576489721270162
  serviceDirectoryRegion: us-central1
target: all-apis

注意:

  • 创建 Private Service Connect 终端节点时,Service Directory 会为使用该终端节点提供的 API 和服务生成 DNS 记录。
  • DNS 记录指向创建的 Private Service Connect 端点 IP 地址,格式如下:SERVICE-ENDPOINT.p.googleapis.com。如storage 服务:storage-pscendpoint.p.googleapis.com

2.4、创建测试GCS bucket ;

gsutil mb  -l us-central1 -b on gs://BUCKET_NAME
BUCKET_NAME: mybucket-DATE

2.5、验证通过连接点的DNS 连接点

  • 验证默认的VM 访问的连接点

创建一个psc-vm-1 验证:

# 创建实例 psc-vm-1 
gcloud compute instances create psc-instance-1 \
    --subnet psclab-subnet \
    --zone us-central1-a \
    --image=centos-7-v20210122 \
    --image-project=centos-cloud \
    --no-address \
    --metadata=startup-script=yum\ install\ tcpdump\ -y$'\n'yum\ install\ bind-utils\ -y$

通过Cloud Shell 连接实例,验证PSC 访问,

gcloud compute ssh --zone "us-central1-a" "psc-vm-1"

启用第二个 tab 通过tcpdump 抓取DNS 数据包:

## 抓取DNS 数据包
sudo tcpdump -vv -i eth0 port 53

# 第一个tab 下访问创建好的Bucket
gsutil -D ls gs://$BUCKET_NAME

获取到如下结果:

## gsutil 
INFO 1103 14:47:31.928911 ] Making http GET to https://**storage.googleapis.com/storage/v1**/b/mybucket-1101/o?alt=json&fields=prefixes%2CnextPageToken%2Citems%2Fname&delimiter=%2F&maxResults=1000&projection=noAcl&versions=False
INFO 1103 14:47:31.929425 ] Headers: {'accept': 'application/json',

## tcpdump 
metadata.google.internal.domain > centos-psc-vm.us-central1-a.c.yunion-test-286209.internal.37348: [udp sum ok] 6943 q: A? storage.googleapis.com. 16/0/0 
storage.googleapis.com. A 173.194.193.128, storage.googleapis.com. A 173.194.194.128, storage.googleapis.com. A 173.194.196.128, storage.googleapis.com. A 173.194.197.128, 
storage.googleapis.com. A 173.194.74.128, storage.googleapis.com. A 173.194.192.128, storage.googleapis.com. A 209.85.147.128, storage.googleapis.com. A 142.250.125.128, storage.googleapis.com. A 142.250.136.128, storage.googleapis.com. A 142.250.148.128, storage.googleapis.com. A 209.85.200.128, storage.googleapis.com. A 142.250.152.128, storage.googleapis.com. A 142.250.128.128, storage.googleapis.com. A142.251.6.128, storage.googleapis.com. A 108.177.112.128, storage.googleapis.com. A 74.125.124.128 (296)
14:50:19.449638 IP (tos 0x0, ttl 64, id 52177, offset 0, flags [DF], proto UDP (17), length 68)

## 解析DNS:
ping storages.googleapis.com
PING storages.googleapis.com (172.217.203.95)
  • 验证Gsutil lookup 记录,

现在将通过更新 psc-vm-1 上的 VM BOTO 文件来控制 gsutil 的行为方式。

查看默认的BOTO 文件:

[psc-vm-1 ~]$ more  /etc/boto.cfg

[GSUtil]
default_project_id  = [your project number]
default_api_version = 2

[GoogleCompute]
service_account = default

更新 /etc/boto.cfg:

[Credentials]
gs_host = storage-pscendpoint.p.googleapis.com
gs_host_header = storage.googleapis.com
gs_json_host = storage-pscendpoint.p.googleapis.com
gs_json_host_header = www.googleapis.com

更新 BOTO 时需要注意,不正确的语法会导致 DNS 查找失败,
需要在 [GSUtil] 配置之上进行 BOTO 配置。

more /etc/boto.cfg
[Credentials]
gs_host = storage-pscendpoint.p.googleapis.com
gs_host_header = storage.googleapis.com
gs_json_host = storage-pscendpoint.p.googleapis.com
gs_json_host_header = www.googleapis.com

[GSUtil]
default_project_id  = [your project number
default_api_version = 2

[GoogleCompute]
service_account = default

再次查看Gsutil 的 DNS记录信息,已经更新为自定义的Endpoint 接入点:

INFO 1103 14:43:34.058101 base_api.py] Making http GET to https://storage-pscendpoint.p.googleapis.com/storage/v1/b/mybucket-1101/o?alt=json&fields=prefixes%2CnextPageToken%2Citems%2Fname&delimiter=%2F&maxResults=1000&projection=noAcl&versions=False
INFO 1103 14:43:34.058560 base_api.py] Headers: {'Host': 'www.googleapis.com',
 'accept': 'application/json',
 'accept-encoding': 'gzip, deflate',

验证 Private Service Connect 端点 IP 现在用于 DNS 解析

$ nslookup storage-pscendpoint.p.googleapis.com
Server:         169.254.169.254
Address:        169.254.169.254#53

Non-authoritative answer:
Name:   storage-pscendpoint.p.googleapis.com
Address: 10.10.110.10

tcpdump 抓包获取的结果:

15:07:10.308745 IP (tos 0x0, ttl 64, id 3161, offset 0, flags [none], proto UDP (17), length 83)
    psc-vm-1.us-central1-a.c.yunion-.internal.51700 > metadata.google.internal.domain: [bad udp cksum 0x5e4f -> 0x1d79!] 60055+ A?
          storage-pscendpoint.p.googleapis.com. (55)
15:07:10.311144 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 99)
    metadata.google.internal.domain > psc-vm-1.us-central1-a.c.yunion.internal.51700: [udp sum ok] 60055 q: 
A? storage-pscendpoint.p.googleapis.com. 1/0/0 storage-pscendpoint.p.googleapis.com. A 10.10.110.10 (71)

发表评论

您的电子邮箱地址不会被公开。