创建与远程站点的传统 VPN 连接

您可以在本地站点和 Google Cloud 之间配置传统 VPN 隧道连接,以便来源 IP 地址和目标 IP 地址都是外部(非 RFC 1918)IP 地址。 Google Cloud 例如,您可以配置与远程站点的传统 VPN 连接,以使得本地 IP 地址范围不会与 Google Cloud 虚拟机 IP 地址冲突。

在本教程中,您将使用 Google Cloud 项目、Google Cloud 控制台、虚拟机 (VM) 实例、传统 VPN 和一些 Linux 命令。如需测试连接,请创建一个新的虚拟机实例,以在虚拟机与远程对等方之间发送和接收流量。

准备工作

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Compute Engine API.

    Enable the API

  7. 在您的工作站上,安装 gcloud 命令行工具
  8. 配置 gcloud 命令行工具以使用您的项目。 在以下命令中,将 PROJECT_ID 替换为您的项目 ID:
    gcloud config set project PROJECT_ID
  9. 确保您的本地子网已连接到本地 VPN 网关。
  10. 按照 配置对等 VPN 网关中的说明,在 Google Cloud 和本地 VPN 网关之间配置对等 VPN 网关。

保留新的静态外部 IP 地址

在 Compute Engine 中,每个虚拟机实例都可以有多个网络接口。每个接口可以同时拥有内部和外部 IP 地址。转发规则可以拥有用于外部负载均衡的外部 IP 地址,或用于内部负载均衡的内部地址。如需详细了解静态 IP 地址,请参阅外部 IP 地址

静态外部 IP 地址是为您的项目预留的 IP 地址(直到您决定将其释放)。 如果您有一个客户要用来访问您服务的 IP 地址,就可以预留该 IP 地址,以仅供您的项目使用。您也可以将临时外部 IP 地址升级为静态外部 IP 地址。

您可以预留下面两种类型的外部 IP 地址:

  • 区域 IP 地址,供具有一个或多个网络接口的虚拟机实例或区域负载均衡器使用
  • 用于全球负载均衡器的全球 IP 地址

如需查看区域和全球负载平衡器列表,请参阅Google Cloud 负载平衡器摘要

可以使用 Google Cloud CLI 或通过 API 预留静态外部 IP 地址。预留 IP 地址后,在创建新实例时将该 IP 地址分配给新实例,或者将该 IP 地址分配给现有实例

控制台

  1. 转到预留静态地址页面。

    转到“预留静态地址”

  2. 为新地址选择一个名称。

  3. 指定该地址是 IPv4 地址还是 IPv6 地址。IPv6 地址仅限为全球地址,只适用于全球负载均衡器。

  4. 指定此 IP 地址是地区地址还是全球地址。如果您要为实例或区域负载均衡器预留静态 IP 地址,请选择区域。如果您要为全球负载均衡器预留静态 IP 地址,请选择全球

  5. 如果该地址为地区 IP 地址,请选择要在其中创建地址的地区。

  6. 可选:选择要连接到 IP 地址的资源。

  7. 点击预留以预留该 IP 地址。

gcloud

如需使用 gcloud compute 预留静态外部 IP 地址,请使用 compute addresses create 命令

如需预留全球 IP 地址,请使用 --global--ip-version 字段。对于 --ip-version 字段,请指定 IPV4IPV6。IPv6 地址仅限为全球地址,只适用于全球负载均衡器。

ADDRESS_NAME 替换为此地址的名称。

gcloud compute addresses create ADDRESS_NAME \
    --global \
    --ip-version [IPV4 | IPV6]

如需预留区域 IP 地址,请使用 --region 字段:

gcloud compute addresses create ADDRESS_NAME  \
    --region=REGION

请替换以下内容:

  • ADDRESS_NAME:此地址的名称。
  • REGION:要预留此地址的区域。此区域应与分配 IP 地址的资源相同。所有区域 IP 地址均为 IPv4 地址。

使用 compute addresses describe 命令可以查看结果:

gcloud compute addresses describe ADDRESS_NAME

API

如需创建区域 IPv4 地址,请调用区域 addresses.insert 方法

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/addresses

请求正文应包含以下内容:

{
  "name": "ADDRESS_NAME"
}

请替换以下内容:

  • ADDRESS_NAME:地址的名称
  • REGION:此请求的地区名称
  • PROJECT_ID:此请求的项目 ID

对于全球静态 IPv4 地址,请调用 globalAddresses.insert 方法

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses

请求正文应包含以下内容:

{
  "name": "ADDRESS_NAME"
}

对于全球静态 IPv6 地址,请调用 globalAddresses.insert 方法

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses

请求正文应包含以下内容:

{
  "name": "ADDRESS_NAME",
  "ipVersion": "IPV6"
}

使用 addresses.get 方法可以查看结果。

Terraform

您可以使用 Terraform 模块创建内部 IP 地址。

在以下示例中,Terraform 参数具有您可以更改的示例值。该示例会创建三个区域外部 IPv4 地址。

module "address" {
  source       = "terraform-google-modules/address/google"
  version      = "~> 4.0"
  project_id   = var.project_id # Replace this with your service project ID in quotes
  region       = "europe-west1"
  address_type = "EXTERNAL"
  names = [
    "regional-external-ip-address-1",
    "regional-external-ip-address-2",
    "regional-external-ip-address-3"
  ]
}

以下示例会创建全球外部 IPv6 地址:

resource "google_compute_global_address" "default" {
  project      = var.project_id # Replace this with your service project ID in quotes
  name         = "ipv6-address"
  address_type = "EXTERNAL"
  ip_version   = "IPV6"
}

启用 IP 转发

您可以在创建虚拟机时启用 IP 转发,也可以在现有虚拟机上更新 canIpForward 实例属性。IP 转发在虚拟机级层启用,适用于挂接到该虚拟机的所有接口。

创建虚拟机时启用 IP 转发

以下说明介绍了如何在创建虚拟机时启用 IP 转发。如果您需要在现有虚拟机上启用 IP 转发,请更新 canIpForward 实例属性

控制台

  1. 转到虚拟机实例页面。
    转到“虚拟机实例”
  2. 点击创建实例
  3. 启动磁盘中,确保您已选择 Linux 映像;例如 Debian GNU/Linux。
  4. 点击网络、磁盘、安全、管理、单租户
  5. 点击网络
  6. 对于 IP 转发,请选择启用
  7. 指定任何其他实例参数。
  8. 点击创建

gcloud

使用 gcloud 创建实例时,请在命令中添加 --can-ip-forward 标志:

gcloud compute instances create ... --can-ip-forward

API

创建实例时,请使用 canIpForward 字段启用 IP 转发。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances
{
  "canIpForward": true,
  ...other fields
}

请替换以下内容:

  • PROJECT_ID:在其中创建实例的项目的 ID。
  • ZONE:实例创建所在的 Google Cloud 区域。

如需了解详情,请参阅 instances.insert 方法。

Terraform

您可以使用 Terraform 资源创建启用了 IP 转发的虚拟机实例。

在此示例中,Terraform 参数分配了您可以更改的值。

resource "google_compute_instance" "default" {
  project      = var.project_id # Replace this with your project ID in quotes
  zone         = "southamerica-east1-b"
  name         = "instance-next-hop"
  machine_type = "e2-medium"
  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }
  network_interface {
    network = "default"
  }
  can_ip_forward = true
}

为入站流量创建路由

请按照以下步骤创建新的静态路由。在创建之前,请确保您熟悉以下内容:

  • 静态路由的目标范围和 VPC 网络中任何子网路由的目标范围都不能相同,而且前者不能比后者更具体。

    • 使用 VPC 网络对等互连来连接两个 VPC 网络时,一个网络中的静态路由的目标和两个网络中任何子网路由的目标都不能相同,而且前者不能比后者更具体。 Google Cloud 会拒绝与子网路由存在冲突的静态路由。
  • 为避免在使用自动模式 VPC 网络时发生冲突,请不要创建目标在 10.128.0.0/9 范围内的静态路由。如需了解详情,请查看自动模式 IPv4 范围

  • 静态路由的目标不能与任何内部分配的范围重叠。

  • 在创建将虚拟机用作下一跃点的自定义静态路由之前,请确保您熟悉充当下一个跃点的实例。如果您选择下一个跃点实例, Google Cloud 仅验证在创建路由时虚拟机是否存在。

  • 如果您使用网络标记创建路由,则只有具有该标记的虚拟机才会接收该路由。但是,已标记的 VM 仍会接收所有没有网络标记的路由。

控制台

  1. 转到 Google Cloud Console 中的“路由”页面。
    转到“路由”
  2. 点击创建路由
  3. 指定该路由的名称说明
  4. 选择将应用该路由的现有网络
  5. 指定目标 IP 范围以定义该路由的目标。
  6. 指定该路由的优先级。只有在多个路由具有等效目标时,才会使用优先级来确定路由顺序。 如需了解详情,请参阅路由参数
  7. 要使该路由仅适用于具有匹配网络标记的实例,请在实例标记字段中指定标记。将该字段留空以使路由适用于网络中的所有实例,或选择内部 TCP/UDP 负载均衡器作为路由的下一个跃点。网络标记不适用于将内部 TCP/UDP 负载平衡器作为下一个跃点的路由。
  8. 为该路由选择下一个跃点

    • 指定实例允许您按名称选择实例。 流量将路由到该实例(或同一区域中同名的任何替换实例),即使该实例的 IP 地址发生更改也是如此。
    • 指定 IP 地址允许您输入 VPC 网络中现有实例的 IP 地址。如需了解有效的下一个跃点 IP 地址的重要限制,请参阅下一个跃点和功能
  9. 点击创建

gcloud

创建新的静态路由:

gcloud compute routes create ROUTE_NAME \
    --destination-range=DESTINATION_RANGE \
    --network=NETWORK \
    NEXT_HOP_SPECIFICATION

替换占位符:

  • ROUTE_NAME 是该路由的名称。
  • DESTINATION_RANGE 表示该路由适用的目标 IP 地址。最宽泛的目标是 0.0.0.0/0
  • NETWORK 是包含该路由的 VPC 网络的名称。
  • NEXT_HOP_SPECIFICATION 表示静态路由的下一个跃点。您必须将下面其中一项指定为下一个跃点。如需详细了解不同类型的下一个跃点,请参阅下一个跃点和功能
    • --next-hop-instance=INSTANCE_NAME--next-hop-instance-zone=ZONE:通过此类型的下一个跃点,可按名称和可用区将流量定向到现有虚拟机实例。流量将被发送到与路由位于同一网络中的虚拟机网络接口的主要内部 IP 地址。
    • --next-hop-address=ADDRESS:通过此类型的下一个跃点,可将流量定向到现有虚拟机实例的 IP 地址。

如需使静态路由仅适用于精选虚拟机(按网络标记),请添加 --tags 标志并指定一个或多个网络标记。如需详细了解网络标记与静态路由如何协同工作,请参阅适用路由。您可以将标记与任何静态路由搭配使用。

如需详细了解 gcloud 语法,请参阅 SDK 文档

API

创建新的静态路由。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/routes
{
  "destRange": "DESTINATION_RANGE",
  "name": "ROUTE_NAME",
  "network": "NETWORK_NAME",
  "priority": PRIORITY,
  "NEXT_HOP_SPECIFICATION": VALUE
}

替换占位符:

  • PROJECT_ID 是创建您的路由所在项目的 ID。
  • DESTINATION_RANGE 表示该路由适用的目标 IP 地址。最宽泛的目标是 0.0.0.0/0
  • ROUTE_NAME 是路由的名称。
  • NETWORK_NAME 是包含该路由的 VPC 网络的名称。
  • NEXT_HOP_SPECIFICATIONVALUE 表示静态路由的下一个跃点。对于 NEXT_HOP_SPECIFICATION,您必须仅指定以下下一个跃点字段中的一个:nextHopIpnextHopInstance。如需详细了解不同类型的下一个跃点和功能,请参阅下一个跃点和功能

如需了解详情,请参阅 routes.insert 方法。

Terraform

您可以使用 Terraform 模块来创建静态路由。

此静态路由会创建一个通向互联网的默认路由。

module "google_compute_route" {
  source       = "terraform-google-modules/network/google//modules/routes"
  version      = "~> 10.0"
  project_id   = var.project_id # Replace this with your project ID in quotes
  network_name = "default"

  routes = [
    {
      name              = "egress-internet"
      description       = "route through IGW to access internet"
      destination_range = "0.0.0.0/0"
      tags              = "egress-inet"
      next_hop_internet = "true"
    }
  ]
}

创建使用静态路由的传统 VPN

VPN 设置向导是创建传统 VPN 网关的唯一 Google Cloud 控制台选项。该向导包含创建传统 VPN 网关、隧道、BGP 会话和外部 VPN 网关资源所需的所有配置步骤。但是,您可以稍后完成某些步骤,例如配置 BGP 会话。

控制台

配置网关

  1. 在 Google Cloud 控制台中,前往 VPN 页面。

    转到 VPN

  2. 如果您是首次创建网关,请点击创建 VPN 连接

  3. 选择 VPN 设置向导

  4. 选择传统 VPN 选项按钮。

  5. 点击继续

  6. 创建 VPN 连接页面上,指定以下网关设置:

    • 名称:VPN 网关的名称。该名称以后无法更改。
    • 说明:(可选)添加说明。
    • 网络:指定要在其中创建 VPN 网关和隧道的现有 VPC 网络。
    • 区域:Cloud VPN 网关和隧道是区域对象。选择网关所在的 Google Cloud区域。不同区域中的实例和其他资源可按照路由顺序使用隧道发送出站流量。为获得最佳性能,网关和隧道应位于相关 Google Cloud 资源所在的同一区域中。
    • IP 地址:创建或选择现有的区域外部 IP 地址

配置隧道

  1. 对于新隧道的隧道部分,指定以下设置:

    • 名称:VPN 隧道的名称。该名称以后无法更改。
    • 说明:输入说明(可选)。
    • 远程对等 IP 地址:指定对等 VPN 网关的外部 IP 地址。
    • IKE 版本:选择对等 VPN 网关支持的相应 IKE 版本。推荐选择 IKEv2(如果受对等设备支持)。
    • IKE 预共享密钥:提供用于身份验证的预共享密钥(共享密钥)。Cloud VPN 隧道的预共享密钥必须与在对等 VPN 网关上配置对应隧道时使用的预共享密钥一致。如需生成加密型强预共享键,请按照这些说明操作。
    • 选择基于政策的隧道
    • 路由选项下,选择基于政策
    • 远程网络 IP 地址范围下,提供本地 VPN 设置中本地流量使用的 IP 地址范围的空格分隔列表。
    • 本地 IP 地址范围字段中,输入您之前使用子网前缀 /32 创建的外部 IP 地址范围。
    • 点击完成
    • 点击创建

gcloud

要创建 Cloud VPN 网关,请完成以下命令序列。在命令中,替换以下内容:

  • PROJECT_ID:您的项目的 ID
  • NETWORK: Google Cloud 网络的名称
  • REGION:您在其中创建网关和隧道的 Google Cloud区域
  • GW_NAME:网关的名称
  • GW_IP_NAME:网关使用的外部 IP 地址的名称
  • 可选:--target-vpn-gateway-region 是运行传统 VPN 网关的区域。其值应与 --region 相同。如果未指定,则系统会自动设置此选项。该选项会替换此命令调用中的默认计算/区域属性值。

配置网关资源

  1. 创建目标 VPN 网关对象:

    gcloud compute target-vpn-gateways create GW_NAME \
       --network=NETWORK \
       --region=REGION \
       --project=PROJECT_ID
    
  2. 保留一个区域外部(静态)IP 地址:

    gcloud compute addresses create GW_IP_NAME \
       --region=REGION \
       --project=PROJECT_ID
    
  3. 请记下此 IP 地址(以便在配置对等 VPN 网关时使用):

    gcloud compute addresses describe GW_IP_NAME \
       --region=REGION \
       --project=PROJECT_ID \
       --format='flattened(address)'
    
  4. 创建三条转发规则;这些规则指示Google Cloud 将 ESP (IPsec)、UDP 500 和 UDP 4500 流量发送到网关:

    gcloud compute forwarding-rules create fr-GW_NAME-esp \
       --load-balancing-scheme=EXTERNAL \
       --network-tier=PREMIUM \
       --ip-protocol=ESP \
       --address=GW_IP_NAME \
       --target-vpn-gateway=GW_NAME \
       --region=REGION \
       --project=PROJECT_ID
    
    gcloud compute forwarding-rules create fr-GW_NAME-udp500 \
       --load-balancing-scheme=EXTERNAL \
       --network-tier=PREMIUM \
       --ip-protocol=UDP \
       --ports=500 \
       --address=GW_IP_NAME \
       --target-vpn-gateway=GW_NAME \
       --region=REGION \
       --project=PROJECT_ID
    
    gcloud compute forwarding-rules create fr-GW_NAME-udp4500 \
       --load-balancing-scheme=EXTERNAL \
       --network-tier=PREMIUM \
       --ip-protocol=UDP \
       --ports=4500 \
       --address=GW_IP_NAME \
       --target-vpn-gateway=GW_NAME \
       --region=REGION \
       --project=PROJECT_ID
    

创建 Cloud VPN 隧道

  1. 在命令中,替换以下内容:

    • TUNNEL_NAME:隧道的名称
    • ON_PREM_IP:对等 VPN 网关的外部 IP 地址
    • IKE_VERS1(对于 IKEv1)或 2(对于 IKEv2)
    • SHARED_SECRET:您的预共享密钥(共享密钥)。Cloud VPN 隧道的预共享密钥必须与在对等 VPN 网关上配置对应隧道时使用的预共享密钥一致。如需生成加密型强预共享键,请按照这些说明操作。

    对于基于政策的 VPN:

    • LOCAL_IP_RANGES:以英文逗号分隔的Google Cloud IP 地址范围列表。例如,您可以为 VPC 网络中的每个子网提供 CIDR 块。从 Cloud VPN 的角度来看,这是左侧。
    • REMOTE_IP_RANGES:以英文逗号分隔的对等网络 IP 地址范围列表。对于 Cloud VPN 来说,此为“右侧”。

    如需配置基于政策的 VPN 隧道,请运行以下命令:

    gcloud compute vpn-tunnels create TUNNEL_NAME \
        --peer-address=ON_PREM_IP \
        --ike-version=IKE_VERS \
        --shared-secret=SHARED_SECRET \
        --local-traffic-selector=LOCAL_IP_RANGES \
        --remote-traffic-selector=REMOTE_IP_RANGES \
        --target-vpn-gateway=GW_NAME \
        --region=REGION \
        --project=PROJECT_ID
    

    对于基于路由的 VPN,本地和远程流量选择器都为 0.0.0.0/0(如路由选项和流量选择器中所定义)。

    如需配置基于路由的 VPN 隧道,请运行以下命令:

    gcloud compute vpn-tunnels create TUNNEL_NAME \
        --peer-address=ON_PREM_IP \
        --ike-version=IKE_VERS \
        --shared-secret=SHARED_SECRET \
        --local-traffic-selector=0.0.0.0/0 \
        --remote-traffic-selector=0.0.0.0/0 \
        --target-vpn-gateway=GW_NAME \
        --region=REGION \
        --project=PROJECT_ID
    
  2. 为您在上一步中的 --remote-traffic-selector 选项中指定的每个远程 IP 地址范围创建静态路由。为每个远程 IP 地址范围重复运行此命令。将 ROUTE_NAME 替换为路由的唯一名称,并将 REMOTE_IP_RANGE 替换为适当的远程 IP 地址范围。

    gcloud compute routes create ROUTE_NAME \
        --destination-range=REMOTE_IP_RANGE \
        --next-hop-vpn-tunnel=TUNNEL_NAME \
        --network=NETWORK \
        --next-hop-vpn-tunnel-region=REGION \
        --project=PROJECT_ID
    

配置虚拟机以发送和接收流量

如需完成设置并测试您是否可以从虚拟机发送和接收流量,请执行以下步骤:

接收流量

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。
  2. 在虚拟机实例列表中,找到您之前创建的虚拟机,然后点击 SSH
  3. 使用您之前预留的公共 IP 地址为虚拟机创建 IP 地址别名。完成此步骤后,您就可以接收发送到虚拟机的流量。

    运行以下命令:

    sudo ip address add EXTERNAL_IP_ADDRESS/32 dev eth0
    

    EXTERNAL_IP_ADDRESS 替换为您之前预留的公共 IP 地址。

发送流量

  1. 在 Google Cloud Console 中,转到虚拟机实例页面。
  2. 在虚拟机实例列表中,找到您之前创建的虚拟机,然后点击 SSH
  3. 运行以下命令以测试您是否可以 ping 外部 IP 地址:

    $ ping -I EXTERNAL_IP_ADDRESS REMOTE_PEER_IP_ADDRESS
    PING 10.0.0.1 (10.0.0.1) from EXTERNAL_IP_ADDRESS : 56(84) bytes of data.
    64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=4.46 ms
    64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=1.11 ms
    

    REMOTE_PEER_IP_ADDRESS 替换为远程对等子网中的一个 IP 地址。

  4. 如需允许虚拟机在向 VPN 隧道发送流量时自动使用此接口,您可以创建 iptables 规则。

    例如,您可以运行下面的命令来创建该 iptables 规则:

    $ sudo iptables -t nat -A POSTROUTING --destination REMOTE_PEER_SUBNET -j SNAT --to-source EXTERNAL_IP_ADDRESS
    

    REMOTE_PEER_SUBNET 替换为远程对等子网。

  5. 接下来,运行下面的命令对 Cloud VPN 隧道进行测试:

    $ ping REMOTE_PEER_IP_ADDRESS
    PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
    64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=3.48 ms
    64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=1.42 ms
    
    $ ping EXTERNAL_IP_ADDRESS
    PING 35.195.72.19 (35.195.72.19) 56(84) bytes of data.
    64 bytes from 35.195.72.19: icmp_seq=1 ttl=64 time=0.033 ms
    64 bytes from 35.195.72.19: icmp_seq=2 ttl=64 time=0.062 ms