使用 VPC 防火墙规则

本页面介绍了用于处理虚拟私有云 (VPC) 防火墙规则的命令,还提供了一些命令用法示例。通过 VPC 防火墙规则,您可以根据端口号、标记或协议来允许或拒绝进出 VPC 网络中的虚拟机 (VM) 实例的流量。

准备工作

如需详细了解 VPC 防火墙规则(例如默认网络的隐式规则和系统生成的规则),请参阅 VPC 防火墙规则

在配置防火墙规则前,请先查看防火墙规则组件,以熟悉 Google Cloud中使用的防火墙组件。

创建 VPC 防火墙规则

VPC 防火墙规则是在网络级别定义的,仅会应用于在其中创建它们的网络;但是,您为每条规则选择的名称在项目中必须是唯一的。

防火墙规则可以包含 IPv4 或 IPv6 地址范围,但不能同时包含两者。

创建防火墙规则时,可选择启用防火墙规则日志记录。如果启用日志记录,则可以省略元数据字段以节省存储费用。如需了解详情,请参阅使用 VPC 防火墙规则日志记录

如果您想要为目标或来源服务账号字段指定多个服务账号,请使用 Google Cloud CLI、API 或客户端库。

默认网络在创建时提供自动防火墙规则。如果您使用 Google Cloud 控制台,则可以利用自定义和自动模式网络在创建网络时轻松创建类似的防火墙。如果您使用 gcloud CLI 或 API,并且想要创建与默认网络提供的防火墙规则类似的防火墙规则,请参阅为常见使用场景配置防火墙规则

控制台

  1. 在 Google Cloud 控制台中,前往防火墙政策页面。

    转到“防火墙政策”

  2. 点击创建防火墙规则

  3. 输入防火墙规则的名称

    该名称在项目中必须是唯一的。

  4. (可选)您可以启用防火墙规则日志记录

    • 点击日志 > 开启
    • 如需省略元数据,请点击显示日志详细信息,然后清除包括元数据复选框。
  5. 为防火墙规则指定网络

  6. 指定规则的优先级

    数字越小,优先级越高。

  7. 选择“入站”或“出站”作为流量方向

  8. 对于对匹配项执行的操作,选择“允许”或“拒绝”。

  9. 指定规则的目标

    • 如果您希望将规则应用于网络中的所有实例,请选择 All instances in the network
    • 如果您希望按网络(目标)标记将规则应用于部分实例,请选择指定的目标标记,然后在目标标记字段中输入要应用该规则的标记。
    • 如果您希望按关联的服务账号将规则应用于部分实例,请选择指定的服务账号,在服务账号范围中指明该服务账号属于当前项目还是其他项目,然后在目标服务账号字段中选择或输入服务账号名称。
  10. 对于入站流量规则,请指定来源过滤条件

    • 如需按来源 IPv4 范围过滤传入的流量,请选择 IPv4 范围,然后在来源 IPv4 范围字段中输入 CIDR 地址块。如需选择所有 IPv4 来源,请使用 0.0.0.0/0
    • 如需按来源 IPv6 范围过滤传入的流量,请选择 IPv6 范围,然后在来源 IPv6 范围字段中输入 CIDR 地址块。如需选择所有 IPv6 来源,请使用 ::/0
    • 如需按网络标记过滤传入的流量,请选择来源标记,然后在来源标记字段中输入网络标记。如需了解针对来源标记数量的限制,请参阅每个网络的限制。只有在未按服务账号指定目标时,才能按来源标记过滤。
    • 如需按服务账号过滤传入的流量,请选择服务账号,在服务账号范围中指明该服务账号属于当前项目还是其他项目,然后在来源服务账号字段中选择或输入服务账号名称。只有在未通过网络标记指定目标时,才能按来源服务账号过滤。
    • 如果需要,请指定次要来源过滤条件。次要来源过滤条件不能与主要过滤条件相同。 来源 IP 地址范围可以与来源标记来源服务账号搭配使用。有效来源集是来源范围内的 IP 地址与网络标记或服务账号所标识实例的并集union。也就是说,如果来源 IP 地址范围或来源标记(或来源服务账号)与过滤条件匹配,则来源会包含在有效来源集中。
    • 来源标记来源服务账号不能同时使用。

    如需详细了解如何使用服务账号和网络标记,请参阅按服务账号过滤与按网络标记过滤

  11. 对于入站流量规则,请指定目标过滤条件

    • 如需按目标 IPv4 范围过滤传入的流量,请选择 IPv4 范围,然后在目标 IPv4 范围字段中输入 CIDR 地址块。对于任何 IPv4 目标,请使用 0.0.0.0/0
    • 如需按目标 IPv6 范围过滤传入的流量,请选择 IPv6 范围,然后在目标 IPv6 范围字段中输入 CIDR 地址块。对于任何 IPv6 目标,请使用 ::/0

    如需了解详情,请参阅入站流量规则的目的地

  12. 对于出站流量规则,请指定目标过滤条件

    • 如需按目标 IPv4 范围过滤传出的流量,请选择 IPv4 范围,然后在目标 IPv4 范围字段中输入 CIDR 地址块。对于任何 IPv4 目标,请使用 0.0.0.0/0
    • 如需按目标 IPv6 范围过滤传出的流量,请选择 IPv6 范围,然后在目标 IPv6 范围字段中输入 CIDR 地址块。对于任何 IPv6 目标,请使用 ::/0

    如需了解详情,请参阅出站流量规则的目的地

  13. 对于出站流量规则,请指定来源过滤条件

    • 如需按来源 IPv4 范围过滤传出的流量,请选择 IPv4 范围,然后在来源 IPv4 范围字段中输入 CIDR 地址块。如需选择所有 IPv4 来源,请使用 0.0.0.0/0
    • 如需按来源 IPv6 范围过滤传出的流量,请选择 IPv6 范围,然后在来源 IPv6 范围字段中输入 CIDR 地址块。对于任何 IPv6 目标,请使用 ::/0

    如需了解详情,请参阅出站流量规则的来源

  14. 定义规则适用的协议和端口

    • 要将规则应用于所有协议和目标端口,请选择全部允许全部拒绝,具体取决于操作。
    • 如需定义特定协议和目标端口,请选择指定的协议和端口
      • 选择 TCP 以包括 TCP 协议和目标端口。输入 all 或英文逗号分隔的目的地端口列表,例如 20-22, 80, 8080
      • 选择 UDP 以包括 UDP 协议和目标端口。输入 all 或英文逗号分隔的目的地端口列表,例如 67-69, 123
      • 选择其他以包括 icmpsctp 或某个协议编号等协议。例如,对于 IPv4 ICMP,请使用 icmp 或协议编号 1。对于 IPv6 ICMP,请使用协议编号 58

    如需了解详情,请参阅协议和目标端口

  15. (可选)您可以创建防火墙规则但不实施,只需将其实施状态设置为已停用即可。具体方法为:点击停用规则,然后选择已停用

  16. 点击创建

gcloud

如需创建 VPC 防火墙规则,请使用 gcloud compute firewall-rules create 命令:

gcloud compute firewall-rules create RULE_NAME \
    [--network NETWORK; default="default"] \
    [--priority PRIORITY;default=1000] \
    [--direction (ingress|egress|in|out); default="ingress"] \
    [--action (deny | allow )] \
    [--target-tags TAG[,TAG,...]] \
    [--target-service-accounts=IAM_SERVICE_ACCOUNT[,IAM_SERVICE_ACCOUNT,...]] \
    [--source-ranges CIDR_RANGE[,CIDR_RANGE,...]] \
    [--source-tags TAG[,TAG, ...]] \
    [--source-service-accounts=IAM_SERVICE_ACCOUNT[,IAM_SERVICE_ACCOUNT,...]] \
    [--destination-ranges CIDR_RANGE[,CIDR_RANGE,...]] \
    [--rules (PROTOCOL[:PORT[-PORT]],[PROTOCOL[:PORT[-PORT]],...]] | all ) \
    [--disabled | --no-disabled] \
    [--enable-logging | --no-enable-logging] \
    [--logging-metadata LOGGING_METADATA]

请使用如下参数。如需详细了解各个参数,请参阅 SDK 参考文档

  • --network 规则的网络。如果省略此参数,则会在 default 网络中创建规则。如果您没有默认网络或者想要在特定网络中创建规则,则必须使用该字段。
  • --priority:表示规则优先级的数值。数字越小,优先级越高。
  • --direction流量方向INGRESSEGRESS)。
  • --action对匹配项执行的操作allowdeny)。必须与 --rules 标志结合使用。
  • 通过以下任一方式指定目标
    • 如果应将规则应用于网络中的所有目标,则省略 --target-tags--target-service-accounts
    • 使用 --target-tags 标记可按网络标记定义目标
    • 使用 --target-service-accounts 标记可按关联的服务账号定义目标
  • 对于入站流量规则,如需进一步优化目的地,请使用 --destination-ranges 以 CIDR 格式指定 IPv4 或 IPv6 地址范围。如果省略 --destination-ranges,则入站流量目的地是任何 IPv4 地址 0.0.0.0/0。如需了解详情,请参阅入站流量规则的目的地以及入站流量规则的目标和 IP 地址

  • 对于入站流量规则,请指定来源

    • --source-ranges:使用此标志可以以 CIDR 格式指定来源 IPv4 或 IPv6 地址的范围。
    • 如果省略 --source-rangessource-tags--source-service-accounts,则入站流量来源是任何 IPv4 地址 0.0.0.0/0
    • --source-tags:使用此标志可以按网络标记指定来源实例。只有在未按服务账号指定目标时,才能按来源标记过滤。如需了解详情,请参阅按服务账号过滤与按网络标记过滤
    • --source-ranges--source-tags 可同时使用。如果同时指定了两者,则有效来源集就是来源范围内的 IP 地址与网络标记所标识实例的并集,即使所标记实例的 IP 不在来源范围内也是如此。
    • --source-service-accounts:使用此标志可以按实例使用的服务账号指定实例。只有在未按网络标记指定目标时,才能按来源服务账号过滤。如需了解详情,请参阅按服务账号过滤与按网络标记过滤--source-ranges--source-service-accounts 可同时使用。如果同时指定了两者,则有效来源集就是来源范围内的 IP 地址与来源服务账号所标识实例的并集,即使来源服务账号所标识的实例的 IP 地址不在来源范围内也是如此。union
  • 对于出站流量规则,如需进一步优化来源,请使用 --source-ranges 指定 CIDR 格式的 IPv4 或 IPv6 地址范围。如果省略 --source-ranges,则出站流量来源是任何 IPv4 地址 0.0.0.0/0。如需了解详情,请参阅出站流量规则的来源以及出站流量规则的目标和 IP 地址

  • 对于出站流量规则,请指定目的地

    • --destination-ranges:使用此标志可以以 CIDR 格式指定目标 IPv4 或 IPv6 地址的范围。
    • 如果省略 --destination-ranges,则出站流量目的地是任何 IPv4 地址 0.0.0.0/0
  • --rules:规则适用的协议和目标端口列表。使用 all 可使规则适用于所有协议和所有目的地端口。需要用到 --action 标志。

  • 默认情况下,防火墙规则会在创建后自动执行,不过,您可以改变这种做法。

    • 如果同时省略 --disabled--no-disabled,则系统会创建并实施防火墙规则。
    • --disabled:添加此标志可以创建防火墙规则,但不会实施。防火墙规则会保持停用状态,直到您更新防火墙规则以将其启用。
    • --no-disabled:添加此标志可确保实施防火墙规则。
  • --enable-logging | --no-enable-logging:您可以在创建或更新规则时,为规则启用防火墙规则日志记录。通过 VPC 防火墙规则日志记录,您可以审核、验证和分析防火墙规则所带来的影响。 如需了解详情,请参阅 VPC 防火墙规则日志记录

    • --logging-metadata:如果启用日志记录,则默认情况下防火墙规则日志记录包含基本字段和元数据字段。您可以省略元数据字段以节省存储费用。如需了解详情,请参阅使用 VPC 防火墙规则日志记录

Terraform

如需创建防火墙规则,您可以使用 google_compute_firewall 资源

resource "google_compute_firewall" "rules" {
  name        = "my-firewall-rule"
  network     = "default"
  description = "Creates firewall rule targeting tagged instances"

  allow {
    protocol = "tcp"
    ports    = ["80", "443"]
  }

  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["web"]
}

如需了解如何应用或移除 Terraform 配置,请参阅基本 Terraform 命令

API

创建 VPC 防火墙规则。

POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "name": "RULE_NAME",
  "network": "projects/PROJECT-ID/global/networks/NETWORK",
  ... other fields
}

请替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • NETWORK:在其中创建防火墙规则的 VPC 网络的名称。
  • RULE_NAME:防火墙规则的名称。

  • 对于入站流量防火墙规则,请指定入站流量来源和目的地:

    • 使用 sourceRangessourceTagssourceServiceAccounts 字段指定入站流量来源。

    • sourceRanges 可以是 IPv4 或 IPv6 范围,但不能是这两者的组合。如需使用范围 0.0.0.0/0,请勿指定任何字段。

    • 您不能同时使用 sourceTagssourceServiceAccounts 字段。不过,您可以将 sourceRangessourceTagssourceServiceAccounts 结合使用。如果这样,连接只需要匹配其中一个字段,即可应用防火墙规则。

    • 对于目标字段,如果您使用 sourceTags 字段,则不能使用 targetServiceAccounts 字段。您必须使用 targetTags 字段或不使用目标字段。同样,如果您使用 sourceServiceAccounts 字段,则不能使用 targetTags 字段。如果您不指定目标字段,则规则将应用于网络中的所有目标。

    • 使用 destinationRanges 字段指定入站流量目的地。destinationRanges 可以是 IPv4 范围或 IPv6 范围,但不能是这两者的组合。
      如果您不指定目的地,则 Google Cloud 将使用 0.0.0.0/0。如需了解详情,请参阅入站流量规则的目的地以及入站流量规则的目标和 IP 地址

  • 对于出站流量防火墙规则,请指定出站流量来源和目的地:

    • 使用 sourceRanges 字段指定出站来源。sourceRange 可以是 IPv4 或 IPv6 范围,但不能是这两者的组合。
      如果您不指定来源, Google Cloud 将使用 0.0.0.0/0。如需了解详情,请参阅出站流量规则的来源以及出站流量规则的目标和 IP 地址

    • 使用 destinationRanges 字段指定目的地。destinationRanges 可以是 IPv4 或 IPv6 范围,但不能是这两者的组合。
      如果您不指定目的地, Google Cloud将使用 0.0.0.0/0。使用 targetTagstargetServiceAccounts 字段可指定规则应用于的目标。如果您不指定目标字段,则规则将应用于网络中的所有目标。

如需详细了解各字段,请参阅 firewalls.insert 方法。

C#


using Google.Cloud.Compute.V1;
using System.Threading.Tasks;

public class CreateFirewallRuleAsyncSample
{
    public async Task CreateFirewallRuleAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id",
        string firewallRuleName = "my-test-firewall-rule",
        // Name of the network the rule will be applied to. Some available name formats:
        // projects/{project_id}/global/networks/{network}
        // global/networks/{network}
        string networkName = "global/networks/default")
    {
        Firewall firewallRule = new Firewall
        {
            Name = firewallRuleName,
            Network = networkName,
            Direction = ComputeEnumConstants.Firewall.Direction.Ingress,
            Allowed =
            {
                new Allowed
                {
                    Ports = { "80", "443" },
                    IPProtocol = "tcp"
                }
            },
            TargetTags = { "web" },
            Description = "Allows TCP traffic on port 80 and 443 from anywhere."
        };

        // Note that the default value of priority for the firewall API is 1000.
        // If you check the value of firewallRule.Priority at this point it
        // will be equal to 0, however it is not treated as "set" by the library, and thus
        // the default will be applied to the new rule. If you want to create a rule that
        // has priority == 0, you'll need to explicitly set it: firewallRule.Priority = 0.
        // You can use the firewallRule.HasPriority property to check if the priority has been set.
        // You can use the firewallRule.ClearPriority() method to unset the priority.

        // Initialize client that will be used to send requests. This client only needs to be created
        // once, and can be reused for multiple requests.
        FirewallsClient client = await FirewallsClient.CreateAsync();

        // Create the firewall rule in the specified project.
        var firewallRuleCreation = await client.InsertAsync(projectId, firewallRule);

        // Wait for the operation to complete using client-side polling.
        await firewallRuleCreation.PollUntilCompletedAsync();
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/protobuf/proto"
)

// createFirewallRule creates a firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.
func createFirewallRule(w io.Writer, projectID, firewallRuleName, networkName string) error {
	// projectID := "your_project_id"
	// firewallRuleName := "europe-central2-b"
	// networkName := "global/networks/default"

	ctx := context.Background()
	firewallsClient, err := compute.NewFirewallsRESTClient(ctx)
	if err != nil {
		return fmt.Errorf("NewInstancesRESTClient: %w", err)
	}
	defer firewallsClient.