使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

使用防火墙规则

本页面介绍了用于处理防火墙规则的命令,还提供了一些命令用法示例。

准备工作

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

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

创建防火墙规则

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

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

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

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

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

控制台

  1. 转到 Google Cloud Console 中的“防火墙”页面。
    转到“防火墙”页面
  2. 点击创建防火墙规则
  3. 输入防火墙规则的名称
    该名称在项目中必须是唯一的。
  4. (可选)您可以启用防火墙规则日志记录
    • 点击日志 > 开启
    • 如需省略元数据,请展开日志详细信息,然后清除包含元数据
  5. 为防火墙规则指定网络
  6. 指定规则的优先级
    数字越小,优先级越高。
  7. 选择“入站”或“出站”作为流量方向
  8. 对于对匹配项执行的操作,选择“允许”或“拒绝”。
  9. 指定规则的目标
    • 如果您希望将规则应用于网络中的所有实例,请选择 All instances in the network
    • 如果您希望按网络(目标)标记将规则应用于部分实例,请选择 Specified target tags,然后在目标标记字段中输入应将规则应用于的标记。
    • 如果您希望按关联的服务帐号将规则应用于部分实例,请选择 Specified service account,在服务帐号范围下指明该服务帐号属于当前项目还是其他项目,然后在目标服务帐号字段中选择或输入服务帐号名称。
  10. 对于入站规则,请指定来源过滤条件
    • 如需按来源 IPv4 范围过滤传入的流量,请选择 IPv4 ranges,然后在来源 IPv4 范围字段中输入所需的 CIDR 地址块。如需选择所有 IPv4 来源,请使用 0.0.0.0/0
    • 如需按来源 IPv6 范围过滤传入的流量,请选择 IPv6 ranges,然后在来源 IPv6 范围字段中输入所需的 CIDR 地址块。如需选择所有 IPv6 来源,请使用 ::/0
    • 如需按网络标记过滤传入的流量,请选择 Source tags,然后在来源标记字段中输入网络标记。如需了解针对来源标记数量的限制,请参阅每个网络的限制。只有在未按服务帐号指定目标时,才能按来源标记过滤。如需了解详情,请参阅按服务帐号过滤与按网络标记过滤
    • 如需按服务帐号过滤传入的流量,请选择 Service account,在服务帐号范围下指明该服务帐号属于当前项目还是其他项目,然后在来源服务帐号字段中选择或输入服务帐号名称。只有在未通过网络标记指定目标时,才能按源服务帐号过滤。如需了解详情,请参阅按服务帐号过滤与按网络标记过滤
    • 如果需要,请指定次要来源过滤条件。次要来源过滤条件不能与主要过滤条件相同。 来源 IP 地址范围可以与来源标记来源服务帐号搭配使用。有效来源集是来源范围内的 IP 地址与网络标记或服务帐号所标识实例的并集。也就是说,如果来源 IP 地址范围或来源标记(或来源服务帐号)与过滤条件匹配,则来源会包含在有效来源集中。
    • 来源标记来源服务帐号不能同时使用。
  11. 对于出站规则,请指定目标过滤条件
    • 如需按目标 IPv4 范围过滤传出的流量,请选择 IPv4 ranges,然后在目标 IPv4 范围字段中输入 CIDR 地址块。对于任何 IPv4 目标,请使用 0.0.0.0/0
    • 如需按目标 IPv6 范围过滤传出的流量,请选择 IPv6 ranges,然后在目标 IPv6 范围字段中输入 CIDR 地址块。对于任何 IPv6 目标,请使用 ::/0
  12. 定义规则适用的协议和端口

    • 选择 Allow allDeny all(具体取决于执行的操作)可将规则应用于所有协议和目的地端口。

    • 定义具体的协议和目的地端口:

      • 选择 tcp 以包括 TCP 协议和目的地端口。输入 all 或英文逗号分隔的目的地端口列表,例如 20-22, 80, 8080
      • 选择 udp 以包括 UDP 协议和目的地端口。输入 all 或英文逗号分隔的目的地端口列表,例如 67-69, 123
      • 选择其他协议以包括 icmpsctp 或某个协议编号等协议。对于 ICMPv6,请使用协议 58。如需了解详情,请参阅协议和目标端口
  13. (可选)您可以创建防火墙规则但不实施,只需将其实施状态设置为已停用即可。具体方法为:点击停用规则,然后选择已停用

  14. 点击创建

gcloud

用于创建防火墙规则的 gcloud 命令如下所示:

gcloud compute firewall-rules create 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:使用此标志可按关联的服务帐号定义目标
  • 对于入站规则,请指定来源
    • --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 地址不在来源范围内也是如此。
  • 对于出站规则,请指定目的地
    • --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:您可以在创建或更新规则时,为规则启用防火墙规则日志记录。通过防火墙规则日志记录,您可以审核、验证和分析防火墙规则所带来的影响。如需了解详情,请参阅防火墙规则日志记录
    • --logging-metadata:如果启用日志记录,则默认情况下防火墙规则日志记录包含基本字段和元数据字段。您可以省略元数据字段以节省存储费用。如需了解详情,请参阅使用防火墙规则日志记录

API

创建防火墙规则。

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

请将占位符替换为有效值:

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

  • 对于入站防火墙规则,请使用以下字段来指定入站来源:sourceRangessourceTagssourceServiceAccountssourceRanges 可以是 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。使用 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 "google.golang.org/genproto/googleapis/cloud/compute/v1"
	"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: %v", err)
	}
	defer firewallsClient.Close()

	firewallRule := &computepb.Firewall{
		Allowed: []*computepb.Allowed{
			{
				IPProtocol: proto.String("tcp"),
				Ports:      []string{"80", "443"},
			},
		},
		Direction: proto.String(computepb.Firewall_INGRESS.String()),
		Name:      &firewallRuleName,
		TargetTags: []string{
			"web",
		},
		Network:     &networkName,
		Description: proto.String("Allowing TCP traffic on port 80 and 443 from Internet."),
	}

	// Note that the default value of priority for the firewall API is 1000.
	// If you check the value of `firewallRule.GetPriority()` 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 need to explicitly set it so:

	// firewallRule.Priority = proto.Int32(0)

	req := &computepb.InsertFirewallRequest{
		Project:          projectID,
		FirewallResource: firewallRule,
	}

	op, err := firewallsClient.Insert(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to create firewall rule: %v", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %v", err)
	}

	fmt.Fprintf(w, "Firewall rule created\n")

	return nil
}

Java


import com.google.cloud.compute.v1.Allowed;
import com.google.cloud.compute.v1.Firewall;
import com.google.cloud.compute.v1.Firewall.Direction;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.InsertFirewallRequest;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class CreateFirewallRule {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample
    /* project: project ID or project number of the Cloud project you want to use.
       firewallRuleName: name of the rule that is created.
       network: name of the network the rule will be applied to. Available name formats:
        * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
        * projects/{project_id}/global/networks/{network}
        * global/networks/{network} */
    String project = "your-project-id";
    String firewallRuleName = "firewall-rule-name-" + UUID.randomUUID();
    String network = "global/networks/default";

    // The rule will be created with default priority of 1000.
    createFirewall(project, firewallRuleName, network);
  }

  // Creates a simple firewall rule allowing for incoming HTTP and
  // HTTPS access from the entire Internet.
  public static void createFirewall(String project, String firewallRuleName, String network)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `firewallsClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (FirewallsClient firewallsClient = FirewallsClient.create()) {

      // The below firewall rule is created in the default network.
      Firewall firewallRule = Firewall.newBuilder()
          .setName(firewallRuleName)
          .setDirection(Direction.INGRESS.toString())
          .addAllowed(
              Allowed.newBuilder().addPorts("80").addPorts("443").setIPProtocol("tcp").build())
          .addSourceRanges("0.0.0.0/0")
          .setNetwork(network)
          .addTargetTags("web")
          .setDescription("Allowing TCP traffic on port 80 and 443 from Internet.")
          .build();

      /* Note that the default value of priority for the firewall API is 1000.
         If you check the value of `firewallRule.getPriority()` 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 so: setPriority(0) */

      InsertFirewallRequest insertFirewallRequest = InsertFirewallRequest.newBuilder()
          .setFirewallResource(firewallRule)
          .setProject(project).build();

      firewallsClient.insertAsync(insertFirewallRequest).get(3, TimeUnit.MINUTES);

      System.out.println("Firewall rule created successfully -> " + firewallRuleName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const firewallRuleName = 'YOUR_FIREWALL_RULE_NAME'
// const networkName = 'global/networks/default'

const compute = require('@google-cloud/compute');
const computeProtos = compute.protos.google.cloud.compute.v1;

async function createFirewallRule() {
  const firewallsClient = new compute.FirewallsClient();
  const operationsClient = new compute.GlobalOperationsClient();

  const firewallRule = new computeProtos.Firewall();
  firewallRule.name = firewallRuleName;
  firewallRule.direction = 'INGRESS';
  firewallRule.allowed = [
    {
      IPProtocol: 'tcp',
      ports: ['80', '443'],
    },
  ];
  firewallRule.targetTags = ['web'];
  firewallRule.network = networkName;
  firewallRule.description =
    'Allowing TCP traffic on port 80 and 443 from Internet.';

  // 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 null, 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 need to explicitly set it so:

  // firewallRule.priority = 0

  const [response] = await firewallsClient.insert({
    project: projectId,
    firewallResource: firewallRule,
  });
  let operation = response.latestResponse;

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Firewall rule created');
}

createFirewallRule();

PHP

use Google\Cloud\Compute\V1\FirewallsClient;
use Google\Cloud\Compute\V1\Allowed;
use Google\Cloud\Compute\V1\Firewall;

/**
 * To correctly handle string enums in Cloud Compute library
 * use constants defined in the Enums subfolder.
 */
use Google\Cloud\Compute\V1\Enums\Firewall\Direction;

/**
 * Creates a simple firewall rule allowing incoming HTTP and HTTPS access from the entire internet.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to create a rule for.
 * @param string $firewallRuleName Name of the rule that is created.
 * @param string $network Name of the network the rule will be applied to. Available name formats:
 *                        https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
 *                        projects/{project_id}/global/networks/{network}
 *                        global/networks/{network}
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */

function create_firewall_rule(string $projectId, string $firewallRuleName, string $network = 'global/networks/default')
{
    $firewallsClient = new FirewallsClient();
    $allowedPorts = (new Allowed())
      ->setIPProtocol('tcp')
      ->setPorts(['80', '443']);
    $firewallResource = (new Firewall())
      ->setName($firewallRuleName)
      ->setDirection(Direction::INGRESS)
      ->setAllowed([$allowedPorts])
      ->setSourceRanges(['0.0.0.0/0'])
      ->setTargetTags(['web'])
      ->setNetwork($network)
      ->setDescription('Allowing TCP traffic on ports 80 and 443 from Internet.');

    /**
    * Note that the default value of priority for the firewall API is 1000.
    * If you check the value of its 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 need to explicitly set it so:
    *
    *   $firewallResource->setPriority(0);
    */

    //Create the firewall rule using Firewalls Client.
    $operation = $firewallsClient->insert($firewallResource, $projectId);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Created rule %s.' . PHP_EOL, $firewallRuleName);
    } else {
        $error = $operation->getError();
        printf('Firewall rule creation failed: %s' . PHP_EOL, $error->getMessage());
    }
}

Python

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1

def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    This method will wait for the extended (long-running) operation to
    complete. If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result

def create_firewall_rule(
    project_id: str, firewall_rule_name: str, network: str = "global/networks/default"
) -> compute_v1.Firewall:
    """
    Creates a simple firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        firewall_rule_name: name of the rule that is created.
        network: name of the network the rule will be applied to. Available name formats:
            * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
            * projects/{project_id}/global/networks/{network}
            * global/networks/{network}

    Returns:
        A Firewall object.
    """
    firewall_rule = compute_v1.Firewall()
    firewall_rule.name = firewall_rule_name
    firewall_rule.direction = "INGRESS"

    allowed_ports = compute_v1.Allowed()
    allowed_ports.I_p_protocol = "tcp"
    allowed_ports.ports = ["80", "443"]

    firewall_rule.allowed = [allowed_ports]
    firewall_rule.source_ranges = ["0.0.0.0/0"]
    firewall_rule.network = network
    firewall_rule.description = "Allowing TCP traffic on port 80 and 443 from Internet."

    firewall_rule.target_tags = ["web"]

    # Note that the default value of priority for the firewall API is 1000.
    # If you check the value of `firewall_rule.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 need to explicitly set it so:
    # TODO: Uncomment to set the priority to 0
    # firewall_rule.priority = 0

    firewall_client = compute_v1.FirewallsClient()
    operation = firewall_client.insert(
        project=project_id, firewall_resource=firewall_rule
    )

    wait_for_extended_operation(operation, "firewall rule creation")

    return firewall_client.get(project=project_id, firewall=firewall_rule_name)

Ruby


require "google/cloud/compute/v1"

# Creates a simple firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] name: name of the rule that is created.
# @param network: name of the network the rule will be applied to. Available name formats:
#         * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
#         * projects/{project_id}/global/networks/{network}
#         * global/networks/{network}
def create_firewall_rule project:, name:, network: "global/networks/default"
  rule = {
    name: name,
    direction: "INGRESS",
    allowed: [{
      I_p_protocol: "tcp",
      ports: ["80", "443"]
    }],
    source_ranges: ["0.0.0.0/0"],
    network: network,
    description: "Allowing TCP traffic on port 80 and 443 from Internet.",
    target_tags: ["web"]
  }

  # Note that the default value of priority for the firewall API is 1000.
  # If you want to create a rule that has priority == 0, you need to explicitly set it:
  #   rule[:priority] = 0
  # Use `rule.has_key? :priority` to check if the priority has been set.
  # Use `rule.delete :priority` method to unset the priority.

  request = {
    firewall_resource: rule,
    project: project
  }

  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  operation = client.insert request

  wait_until_done operation: operation
end

Terraform

您可以使用 Terraform 资源来创建防火墙规则。

resource "google_compute_firewall" "rules" {
  project     = var.project_id # Replace this with your project ID in quotes
  name        = "my-firewall-rule"
  network     = "default"
  description = "Creates firewall rule targeting tagged instances"

  allow {
    protocol = "tcp"
    ports    = ["80", "8080", "1000-2000"]
  }
  target_tags = ["web"]
}

如需了解如何应用或移除 Terraform 配置,请参阅使用 Terraform 配置

更新防火墙规则

您可以修改防火墙规则的某些组成部分,例如匹配条件的指定协议和目的地端口。您不能修改防火墙规则的名称、网络、对匹配项执行的操作流量方向

如果您需要更改名称、网络、操作或方向组件,则必须删除现有规则,然后改为创建新规则

如果要添加或移除多个服务帐号,请使用 Google Cloud CLI、API 或客户端库。您无法使用控制台来指定多个目标服务帐号或来源服务帐号。

控制台

  1. 转到 Google Cloud Console 中的“防火墙”页面。
    转到“防火墙”页面
  2. 点击要修改的防火墙规则。
  3. 点击修改
  4. 根据您的需求修改任何可修改的组件

    指定的协议和端口字段中,使用英文分号分隔列表来指定多个协议以及协议和目的地端口组合。 如需指定 IPv4 ICMP,请使用 icmp 或协议编号 1。如需指定 IPv6 ICMP,请使用协议编号 58。如需了解详情,请参阅协议和目标端口

  5. 点击保存

gcloud

用于更新防火墙规则的 gcloud 命令如下所示:

gcloud compute firewall-rules update NAME \
    [--priority=PRIORITY] \
    [--description=DESCRIPTION] \
    [--target-tags=TAG,...] \
    [--target-service-accounts=IAM_SERVICE_ACCOUNT,_] \
    [--source-ranges=CIDR_RANGE,...] \
    [--source-tags=TAG,...] \
    [--source-service-accounts=IAM_SERVICE_ACCOUNT,_] \
    [--destination-ranges=CIDR_RANGE,...] \
    [--rules=[PROTOCOL[:PORT[-PORT]],…]] \
    [--disabled | --no-disabled] \
    [--enable-logging | --no-enable-logging]

每个标志的说明均与创建防火墙规则部分相同。如需详细了解各个标志,请参阅 SDK 参考文档

API

使用 PATCH 可更新以下字段:alloweddescriptionsourceRangessourceTagstargetTags。对所有其他字段使用 PUT 或 POST。

(PATCH|(POST|PUT)) https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/FIREWALL_NAME
{
  "name": "FIREWALL_NAME",
  "network": "projects/PROJECT-ID/global/networks/NETWORK",
  ... other fields
}

请将占位符替换为有效值:

  • PROJECT_ID 是 VPC 网络所在项目的 ID。
  • NETWORK 是防火墙规则所在 VPC 网络的名称。
  • FIREWALL_NAME 是要更新的防火墙规则的名称。

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

C#


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

public class PatchFirewallRuleAsyncSample
{
    public async Task PatchFirewallRuleAsync(
        // 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",
        int newPriority = 10)
    {
        // The patch operation doesn't require the full definition of a Firewall object.
        // It will only update the values that were set in it,
        // in this case it will only change the priority.
        Firewall firewallRule = new Firewall
        {
            Priority = newPriority
        };

        // 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();

        // Patch the firewall rule in the specified project.
        var firewallRulePatching = await client.PatchAsync(projectId, firewallRuleName, firewallRule);

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

Go

import (
	"context"
	"fmt"
	"io"

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

// patchFirewallPriority modifies the priority of a given firewall rule.
func patchFirewallPriority(w io.Writer, projectID, firewallRuleName string, priority int32) error {
	// projectID := "your_project_id"
	// firewallRuleName := "europe-central2-b"
	// priority := 10

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

	firewallRule := &computepb.Firewall{
		Priority: proto.Int32(priority),
	}

	req := &computepb.PatchFirewallRequest{
		Project:          projectID,
		Firewall:         firewallRuleName,
		FirewallResource: firewallRule,
	}

	// The patch operation doesn't require the full definition of a Firewall interface. It will only update
	// the values that were set in it, in this case it will only change the priority.
	op, err := firewallsClient.Patch(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to patch firewall rule: %v", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %v", err)
	}

	fmt.Fprintf(w, "Firewall rule updated\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.Firewall;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.Operation;
import com.google.cloud.compute.v1.PatchFirewallRequest;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class PatchFirewallRule {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample
    // project: project ID or project number of the Cloud project you want to use.
    // firewallRuleName: name of the rule you want to modify.
    // priority: the new priority to be set for the rule.
    String project = "your-project-id";
    String firewallRuleName = "firewall-rule-name-" + UUID.randomUUID();
    int priority = 10;

    patchFirewallPriority(project, firewallRuleName, priority);
  }

  // Modifies the priority of a given firewall rule.
  public static void patchFirewallPriority(String project, String firewallRuleName, int priority)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `firewallsClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (FirewallsClient firewallsClient = FirewallsClient.create()) {

      /* The patch operation doesn't require the full definition of a Firewall object. It will only
         update the values that were set in it, in this case it will only change the priority. */
      Firewall firewall = Firewall.newBuilder()
          .setPriority(priority).build();

      PatchFirewallRequest patchFirewallRequest = PatchFirewallRequest.newBuilder()
          .setProject(project)
          .setFirewall(firewallRuleName)
          .setFirewallResource(firewall).build();

      OperationFuture<Operation, Operation> operation = firewallsClient.patchAsync(
          patchFirewallRequest);
      operation.get(3, TimeUnit.MINUTES);
      System.out.println("Firewall Patch applied successfully ! ");
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const firewallRuleName = 'FIREWALL_RULE_NAME';
// const priority = 10;

const compute = require('@google-cloud/compute');
const computeProtos = compute.protos.google.cloud.compute.v1;

async function patchFirewallPriority() {
  const firewallsClient = new compute.FirewallsClient();
  const operationsClient = new compute.GlobalOperationsClient();

  const firewallRule = new computeProtos.Firewall();
  firewallRule.priority = priority;

  // The patch operation doesn't require the full definition of a Firewall object. It will only update
  // the values that were set in it, in this case it will only change the priority.
  const [response] = await firewallsClient.patch({
    project: projectId,
    firewall: firewallRuleName,
    firewallResource: firewallRule,
  });
  let operation = response.latestResponse;

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Firewall rule updated');
}

patchFirewallPriority();

PHP

use Google\Cloud\Compute\V1\FirewallsClient;
use Google\Cloud\Compute\V1\Firewall;

/**
 * Modifies the priority of a given firewall rule.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to patch a rule from.
 * @param string $firewallRuleName Name of the rule that you want to modify.
 * @param int $priority The new priority to be set for the rule.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function patch_firewall_priority(string $projectId, string $firewallRuleName, int $priority)
{
    $firewallsClient = new FirewallsClient();
    $firewallResource = (new Firewall())->setPriority($priority);

    // The patch operation doesn't require the full definition of a Firewall object. It will only update
    // the values that were set in it, in this case it will only change the priority.
    $operation = $firewallsClient->patch($firewallRuleName, $firewallResource, $projectId);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Patched %s priority to %d.' . PHP_EOL, $firewallRuleName, $priority);
    } else {
        $error = $operation->getError();
        printf('Patching failed: %s' . PHP_EOL, $error->getMessage());
    }
}

Python

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1

def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    This method will wait for the extended (long-running) operation to
    complete. If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result

def patch_firewall_priority(
    project_id: str, firewall_rule_name: str, priority: int
) -> None:
    """
    Modifies the priority of a given firewall rule.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        firewall_rule_name: name of the rule you want to modify.
        priority: the new priority to be set for the rule.
    """
    firewall_rule = compute_v1.Firewall()
    firewall_rule.priority = priority

    # The patch operation doesn't require the full definition of a Firewall object. It will only update
    # the values that were set in it, in this case it will only change the priority.
    firewall_client = compute_v1.FirewallsClient()
    operation = firewall_client.patch(
        project=project_id, firewall=firewall_rule_name, firewall_resource=firewall_rule
    )

    wait_for_extended_operation(operation, "firewall rule patching")
    return

Ruby


require "google/cloud/compute/v1"

# Modifies the priority of a given firewall rule.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] name name of the rule you want to modify.
# @param [Google::Protobuf::RepeatedField] allowed the repeated instances of the Allowed field in the rule.
#         Compute errors out if allowed is empty.
# @param [Integer] priority the new priority to be set for the rule.
def patch_firewall_priority project:, name:, allowed:, priority:
  allowed_arr = allowed.map do |instance|
    {
      I_p_protocol: instance.I_p_protocol,
      ports: instance.ports.to_a
    }
  end.to_a

  rule = {
    priority: priority,
    allowed: allowed_arr
  }

  request = {
    project: project,
    firewall: name,
    firewall_resource: rule
  }

  # The patch operation doesn't require the full definition of a Firewall object. It will only update
  # the values that were set in it, in this case it will only change the priority.
  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  operation = client.patch request

  wait_until_done operation: operation
end

列出 VPC 网络的防火墙规则

在 Google Cloud 控制台中,您可以列出您的项目或某个特定 VPC 网络的所有防火墙规则。对于每个防火墙规则,Google Cloud 控制台都会显示规则详情,例如规则的类型、目标和过滤条件。

如果您启用了防火墙规则日志记录,则防火墙数据分析可以提供有关您的防火墙规则的数据分析,以帮助您更好地了解并安全地优化防火墙配置。例如,您可以查看最近六周未使用哪些 allow 规则。如需了解详情,请参阅防火墙数据分析文档中的使用防火墙规则详情屏幕

控制台

要显示项目中所有网络的所有防火墙规则,请执行以下操作:

要显示特定网络中的防火墙规则,请执行以下操作:

  1. 转到 Google Cloud Console 中的“VPC 网络”页面。
    转到“VPC 网络”页面
  2. 点击某个 VPC 网络的名称以转到其详情页面。
  3. 在该网络的详情页面上,点击防火墙规则标签页。

gcloud

以下命令会生成给定网络 ([NETWORK-NAME]) 经过排序的防火墙规则列表。

gcloud compute firewall-rules list --filter network=NETWORK \
    --sort-by priority \
    --format="table(
        name,
        network,
        direction,
        priority,
        sourceRanges.list():label=SRC_RANGES,
        destinationRanges.list():label=DEST_RANGES,
        allowed[].map().firewall_rule().list():label=ALLOW,
        denied[].map().firewall_rule().list():label=DENY,
        sourceTags.list():label=SRC_TAGS,
        targetTags.list():label=TARGET_TAGS
        )"

API

列出给定网络的所有防火墙规则。

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/?filter=network="NETWORK

请将占位符替换为有效值:

  • PROJECT_ID 是 VPC 网络所在项目的 ID。
  • NETWORK 是包含所要列出防火墙规则的 VPC 网络的名称。

如需了解详情,请参阅 firewalls.list 方法。

C#


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

public class ListFirewallRulesAsyncSample
{
    public async Task ListFirewallRulesAsync(
        // TODO(developer): Set your own default values for these parameters or pass different values when calling this method.
        string projectId = "your-project-id")
    {
        // 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();

        // Make the request to list all firewall rules.
        await foreach (var firewallRule in client.ListAsync(projectId))
        {
            // The result is a Firewall sequence that you can iterate over.
            Console.WriteLine($"Firewal Rule: {firewallRule.Name}");
        }
    }
}

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	"google.golang.org/api/iterator"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
)

// listFirewallRules prints the list of firewall names and their descriptions in specified project
func listFirewallRules(w io.Writer, projectID string) error {
	// projectID := "your_project_id"

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

	req := &computepb.ListFirewallsRequest{
		Project: projectID,
	}

	it := firewallsClient.List(ctx, req)
	for {
		firewallRule, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintf(w, "- %s: %s\n", firewallRule.GetName(), firewallRule.GetDescription())
	}

	return nil
}

Java


import com.google.cloud.compute.v1.Firewall;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.FirewallsClient.ListPagedResponse;
import java.io.IOException;

public class ListFirewallRules {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample
    // project: project ID or project number of the Cloud project you want to use.
    String project = "your-project-id";
    listFirewallRules(project);
  }

  // Return a list of all the firewall rules in specified project.
  // Also prints the list of firewall names and their descriptions.
  public static ListPagedResponse listFirewallRules(String project)
      throws IOException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `firewallsClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (FirewallsClient firewallsClient = FirewallsClient.create()) {
      ListPagedResponse firewallResponse = firewallsClient.list(project);
      for (Firewall firewall : firewallResponse.iterateAll()) {
        System.out.println(firewall.getName());
      }
      return firewallResponse;
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';

const compute = require('@google-cloud/compute');

async function listFirewallRules() {
  const firewallsClient = new compute.FirewallsClient();

  const [firewallRules] = await firewallsClient.list({
    project: projectId,
  });

  for (const rule of firewallRules) {
    console.log(` - ${rule.name}: ${rule.description}`);
  }
}

listFirewallRules();

PHP

use Google\Cloud\Compute\V1\FirewallsClient;

/**
 * Return a list of all the firewall rules in specified project. Also prints the
 * list of firewall names and their descriptions.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to list rules from.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 */
function list_firewall_rules(string $projectId)
{
    // List all firewall rules defined for the project using Firewalls Client.
    $firewallClient = new FirewallsClient();
    $firewallList = $firewallClient->list($projectId);

    print('--- Firewall Rules ---' . PHP_EOL);
    foreach ($firewallList->iterateAllElements() as $firewall) {
        printf(' -  %s : %s : %s' . PHP_EOL, $firewall->getName(), $firewall->getDescription(), $firewall->getNetwork());
    }
}

Python

from typing import Iterable

from google.cloud import compute_v1

def list_firewall_rules(project_id: str) -> Iterable[compute_v1.Firewall]:
    """
    Return a list of all the firewall rules in specified project. Also prints the
    list of firewall names and their descriptions.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.

    Returns:
        A flat list of all firewall rules defined for given project.
    """
    firewall_client = compute_v1.FirewallsClient()
    firewalls_list = firewall_client.list(project=project_id)

    for firewall in firewalls_list:
        print(f" - {firewall.name}: {firewall.description}")

    return firewalls_list

Ruby


require "google/cloud/compute/v1"

# Return a list of all the firewall rules in specified project. Also prints the
# list of firewall names and their descriptions.
#
# @param [String] project project ID or project number of the project you want to use.
# @return [Array<::Google::Cloud::Compute::V1::Firewall>]
#     A list of all firewall rules defined for the given project.
def list_firewall_rules project:
  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  firewalls = client.list project: project

  firewall_list = []
  firewalls.each do |firewall|
    puts " - #{firewall.name}: #{firewall.description}"
    firewall_list << firewall
  end

  firewall_list
end

列出虚拟机实例网络接口的防火墙规则

对于每个网络接口,Google Cloud 控制台都会列出适用于该接口的所有防火墙规则以及该接口实际使用的规则。防火墙规则可以屏蔽其他规则,因此并非所有适用于接口的规则都会被该接口实际使用。

防火墙规则通过规则的目标参数关联并适用于虚拟机实例。通过查看所有适用的规则,您可以检查特定规则是否适用于接口。

如果您启用了防火墙规则日志记录,则防火墙数据分析可以提供有关您的防火墙规则的数据分析,以帮助您更好地了解并安全地优化防火墙配置。例如,您可以查看最近六周内界面上有哪些规则命中。如需了解详情,请参阅防火墙数据分析文档中的使用虚拟机网络接口详情屏幕

控制台

如需查看某个虚拟机实例的特定网络接口的规则,请执行以下操作:

  1. 转到 Google Cloud Console 中的“虚拟机实例”页面并找到要查看的实例。
    转到“虚拟机实例”页面
  2. 在该实例的更多操作菜单 () 中,选择查看网络详情
  3. 如果某个实例具有多个网络接口,请在网络接口详情部分选择要查看的网络接口。
  4. 防火墙和路由详情部分中,选择防火墙规则标签页。
  5. 查看表,以确定是否允许流量进出特定 IP 地址。

查看防火墙规则详情

您可以检查防火墙规则,以查看其名称、适用网络和组件(包括规则是否处于启用状态)。

控制台

  1. 列出您的防火墙规则。您可以查看规则的完整列表,也可以仅查看特定网络中的规则。
  2. 点击要查看的规则。

gcloud

以下命令可描述单个防火墙规则。请将 [FIREWALL-NAME] 替换为防火墙规则的名称。防火墙规则名称在项目中是唯一的,因此您在描述现有规则时无需指定网络。

gcloud compute firewall-rules describe [FIREWALL-NAME]

API

描述给定防火墙规则。

GET https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/FIREWALL_NAME

请将占位符替换为有效值:

  • PROJECT_ID 是防火墙规则所在项目的 ID。
  • FIREWALL_NAME 是要说明的防火墙规则的名称。

如需了解详情,请参阅 firewalls.get 方法。

删除防火墙规则

控制台

  1. 列出您的防火墙规则。您可以查看规则的完整列表,也可以仅查看特定网络中的规则。
  2. 点击要删除的规则。
  3. 点击删除
  4. 再次点击删除进行确认。

gcloud

以下命令可删除防火墙规则。请将 [FIREWALL-NAME] 替换为要删除的规则的名称。

gcloud compute firewall-rules delete [FIREWALL-NAME]

API

删除防火墙规则。

DELETE https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls/FIREWALL_NAME

请将占位符替换为有效值:

  • PROJECT_ID 是防火墙规则所在项目的 ID。
  • FIREWALL_NAME 是要删除的防火墙规则的名称。

如需了解详情,请参阅 firewalls.delete 方法。

C#


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

public class DeleteFirewallRuleAsyncSample
{
    public async Task DeleteFirewallRuleAsync(
        // 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")
    {

        // 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();

        // Make the request to delete the firewall rule.
        var firewallRuleDeletion = await client.DeleteAsync(projectId, firewallRuleName);

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

Go

import (
	"context"
	"fmt"
	"io"

	compute "cloud.google.com/go/compute/apiv1"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
)

// deleteFirewallRule deletes a firewall rule from the project.
func deleteFirewallRule(w io.Writer, projectID, firewallRuleName string) error {
	// projectID := "your_project_id"
	// firewallRuleName := "europe-central2-b"

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

	req := &computepb.DeleteFirewallRequest{
		Project:  projectID,
		Firewall: firewallRuleName,
	}

	op, err := firewallsClient.Delete(ctx, req)
	if err != nil {
		return fmt.Errorf("unable to delete firewall rule: %v", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %v", err)
	}

	fmt.Fprintf(w, "Firewall rule deleted\n")

	return nil
}

Java


import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.compute.v1.FirewallsClient;
import com.google.cloud.compute.v1.Operation;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class DeleteFirewallRule {

  public static void main(String[] args)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    // TODO(developer): Replace these variables before running the sample
    // project: project ID or project number of the Cloud project you want to use.
    // firewallRuleName: name of the firewall rule you want to delete.
    String project = "your-project-id";
    String firewallRuleName = "firewall-rule-name-" + UUID.randomUUID();
    deleteFirewallRule(project, firewallRuleName);
  }

  // Deletes a firewall rule from the project.
  public static void deleteFirewallRule(String project, String firewallRuleName)
      throws IOException, ExecutionException, InterruptedException, TimeoutException {
    /* Initialize client that will be used to send requests. This client only needs to be created
       once, and can be reused for multiple requests. After completing all of your requests, call
       the `firewallsClient.close()` method on the client to safely
       clean up any remaining background resources. */
    try (FirewallsClient firewallsClient = FirewallsClient.create()) {

      OperationFuture<Operation, Operation> operation = firewallsClient.deleteAsync(project,
          firewallRuleName);
      operation.get(3, TimeUnit.MINUTES);

      System.out.println("Deleted firewall rule -> " + firewallRuleName);
    }
  }
}

Node.js

/**
 * TODO(developer): Uncomment and replace these variables before running the sample.
 */
// const projectId = 'YOUR_PROJECT_ID';
// const firewallRuleName = 'FIREWALL_RULE_NAME';

const compute = require('@google-cloud/compute');

async function deleteFirewallRule() {
  const firewallsClient = new compute.FirewallsClient();
  const operationsClient = new compute.GlobalOperationsClient();

  const [response] = await firewallsClient.delete({
    project: projectId,
    firewall: firewallRuleName,
  });
  let operation = response.latestResponse;

  // Wait for the create operation to complete.
  while (operation.status !== 'DONE') {
    [operation] = await operationsClient.wait({
      operation: operation.name,
      project: projectId,
    });
  }

  console.log('Firewall rule deleted');
}

deleteFirewallRule();

PHP

use Google\Cloud\Compute\V1\FirewallsClient;

/**
 * Delete a firewall rule from the specified project.
 *
 * @param string $projectId Project ID or project number of the Cloud project you want to delete a rule for.
 * @param string $firewallRuleName Name of the rule that is deleted.
 *
 * @throws \Google\ApiCore\ApiException if the remote call fails.
 * @throws \Google\ApiCore\ValidationException if local error occurs before remote call.
 */
function delete_firewall_rule(string $projectId, string $firewallRuleName)
{
    $firewallsClient = new FirewallsClient();

    // Delete the firewall rule using Firewalls Client.
    $operation = $firewallsClient->delete($firewallRuleName, $projectId);

    // Wait for the operation to complete.
    $operation->pollUntilComplete();
    if ($operation->operationSucceeded()) {
        printf('Rule %s deleted successfully!' . PHP_EOL, $firewallRuleName);
    } else {
        $error = $operation->getError();
        printf('Failed to delete firewall rule: %s' . PHP_EOL, $error->getMessage());
    }
}

Python

import sys
from typing import Any

from google.api_core.extended_operation import ExtendedOperation
from google.cloud import compute_v1

def wait_for_extended_operation(
    operation: ExtendedOperation, verbose_name: str = "operation", timeout: int = 300
) -> Any:
    """
    This method will wait for the extended (long-running) operation to
    complete. If the operation is successful, it will return its result.
    If the operation ends with an error, an exception will be raised.
    If there were any warnings during the execution of the operation
    they will be printed to sys.stderr.

    Args:
        operation: a long-running operation you want to wait on.
        verbose_name: (optional) a more verbose name of the operation,
            used only during error and warning reporting.
        timeout: how long (in seconds) to wait for operation to finish.
            If None, wait indefinitely.

    Returns:
        Whatever the operation.result() returns.

    Raises:
        This method will raise the exception received from `operation.exception()`
        or RuntimeError if there is no exception set, but there is an `error_code`
        set for the `operation`.

        In case of an operation taking longer than `timeout` seconds to complete,
        a `concurrent.futures.TimeoutError` will be raised.
    """
    result = operation.result(timeout=timeout)

    if operation.error_code:
        print(
            f"Error during {verbose_name}: [Code: {operation.error_code}]: {operation.error_message}",
            file=sys.stderr,
            flush=True,
        )
        print(f"Operation ID: {operation.name}", file=sys.stderr, flush=True)
        raise operation.exception() or RuntimeError(operation.error_message)

    if operation.warnings:
        print(f"Warnings during {verbose_name}:\n", file=sys.stderr, flush=True)
        for warning in operation.warnings:
            print(f" - {warning.code}: {warning.message}", file=sys.stderr, flush=True)

    return result

def delete_firewall_rule(project_id: str, firewall_rule_name: str) -> None:
    """
    Deletes a firewall rule from the project.

    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        firewall_rule_name: name of the firewall rule you want to delete.
    """
    firewall_client = compute_v1.FirewallsClient()
    operation = firewall_client.delete(project=project_id, firewall=firewall_rule_name)

    wait_for_extended_operation(operation, "firewall rule deletion")
    return

Ruby


require "google/cloud/compute/v1"

# Deletes a firewall rule from the project.
#
# @param [String] project project ID or project number of the Cloud project you want to use.
# @param [String] name name of the firewall rule you want to delete.
def delete_firewall_rule project:, name:
  client = ::Google::Cloud::Compute::V1::Firewalls::Rest::Client.new
  operation = client.delete project: project, firewall: name

  wait_until_done operation: operation
end

监控防火墙规则

您可以为防火墙规则启用日志记录,以便了解哪条规则允许流量、哪条规则会阻止流量以及这些流量的具体信息。如需了解相关说明,请参阅使用防火墙规则日志记录

为常见使用场景配置防火墙规则

以下部分提供了用于重新创建为默认网络创建的预定义防火墙规则的 gcloud CLI 和 API 示例。您可以使用这些示例为自定义和自动模式网络创建类似的规则。 每条防火墙规则都可以包含 IPv4 或 IPv6 地址范围,但不能同时包含两者。

允许虚拟机之间的内部入站连接

以下示例创建一条防火墙规则,以允许通过内部 TCP、UDP 和 ICMP 连接到虚拟机实例,类似于默认网络的 allow-internal 规则:

gcloud

gcloud compute firewall-rules create NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK; default="default" \
    --priority=1000 \
    --rules=tcp:0-65535,udp:0-65535,ICMP_PROTOCOL \
    --source-ranges=SUBNET_RANGES

替换以下内容:

  • NAME:此防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • ICMP_PROTOCOL:使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6
  • SUBNET_RANGES:一个或多个 IP 地址范围。添加 IP 地址范围后,来自该范围的流量便可以到达 VPC 网络中的任何虚拟机目的地。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。

    IPv4 子网范围:

    • 自动模式 VPC 网络使用 10.128.0.0/9 内的 IP 地址范围。
    • 自定义模式网络可以使用任何有效的 IPv4 地址范围。如果您未使用 VPC 网络中子网的连续范围,则可能需要指定多个范围。
    • 您可以使用 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 允许来自所有专用 IPv4 地址范围(RFC 1918 范围)的流量。

    IPv6 子网范围:

    • 如果您为 VPC 网络分配了内部 IPv6 地址范围,则可以将该范围用作来源范围。如果对 VPC 网络使用内部 IPv6 范围,防火墙规则将包含所有当前和未来的内部 IPv6 子网范围。您可以使用以下命令找到 VPC 网络的内部 IPv6 范围:

      gcloud compute networks describe NETWORK \
        --format="flattened(internalIpv6Range)"
      

      您还可以指定特定的内部 IPv6 子网范围。

    • 如需允许来自双栈子网的外部 IPv6 子网范围的流量,您必须指定要包含的每个子网的 IPv6 地址范围。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "FIREWALL_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "targetTags": [],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "0-65535"
      ]
    },
    {
      "IPProtocol": "udp",
      "ports": [
        "0-65535"
      ]
    },
    {
      "IPProtocol": "ICMP_PROTOCOL"
    }
  ],
  "sourceRanges": [
    "SUBNET_RANGES"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • FIREWALL_NAME:在其中创建防火墙规则的 VPC 网络的名称。
  • NETWORK:防火墙规则适用的名称。默认值为 default
  • ICMP_PROTOCOL:使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6
  • INTERNAL_SOURCE_RANGES:一个或多个 IP 地址范围。要允许 VPC 网络中所有子网内的内部流量,请指定您的 VPC 网络中使用的 IP 地址范围。 您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。

    IPv4 子网范围:

    • 自动模式 VPC 网络使用 10.128.0.0/9 内的 IP 地址范围。
    • 自定义模式网络可以使用任何有效的 IPv4 地址范围。如果您未使用 VPC 网络中子网的连续范围,则可能需要指定多个范围。
    • 您可以使用 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 允许来自所有专用 IPv4 地址范围(RFC 1918 范围)的流量。

    IPv6 子网范围:

    • 如果您为 VPC 网络分配了内部 IPv6 地址范围,则可以将该范围用作来源范围。如果对 VPC 网络使用内部 IPv6 范围,防火墙规则将包含所有当前和未来的内部 IPv6 子网范围。您可以使用以下命令找到 VPC 网络的内部 IPv6 范围:

      gcloud compute networks describe NETWORK \
        --format="flattened(internalIpv6Range)"
      

      您还可以指定特定的内部 IPv6 子网范围。

    • 如需允许来自双栈子网的外部 IPv6 子网范围的流量,您必须指定要包含的每个子网的 IPv6 地址范围。

允许到虚拟机的入站 SSH 连接

以下示例创建一条防火墙规则,以允许通过 SSH 连接到虚拟机实例,类似于默认网络的 allow-ssh 规则:

gcloud

gcloud compute firewall-rules create NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK; default="default" \
    --priority=1000 \
    --rules=tcp:22 \
    --source-ranges=RANGES_OUTSIDE_VPC_NETWORK

替换以下内容:

  • NAME:此防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 SSH 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "FIREWALL_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "targetTags": [],
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "22"
      ]
    }
  ],
  "sourceRanges": [
    "RANGES_OUTSIDE_VPC_NETWORK"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • FIREWALL_NAME:在其中创建防火墙规则的 VPC 网络的名称。
  • NETWORK:防火墙规则的名称。
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 SSH 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

允许到虚拟机的入站 RDP 连接

以下示例会创建一条防火墙规则,以允许通过 Microsoft 远程桌面协议 (RDP) 连接到虚拟机实例,类似于默认网络的 allow-rdp 规则:

gcloud

gcloud compute firewall-rules create NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK; default="default" \
    --priority=1000 \
    --rules=tcp:3389 \
    --source-ranges=RANGES_OUTSIDE_VPC_NETWORK

替换以下内容:

  • NAME:此防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 RDP 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "FIREWALL_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "allowed": [
    {
      "IPProtocol": "tcp",
      "ports": [
        "3389"
      ]
    }
  ],
  "sourceRanges": [
    "EXTERNAL_SOURCE_RANGES"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • FIREWALL_NAME:在其中创建防火墙规则的 VPC 网络的名称。
  • NETWORK:防火墙规则的名称。
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果满足所有其他前提条件,则在来源范围中包含 35.235.240.0/20 允许使用 Identity-Aware Proxy (IAP) TCP 转发的 RDP 连接。如需了解详情,请参阅使用 IAP 进行 TCP 转发
    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

允许到虚拟机的入站 ICMP 连接

以下示例创建一条防火墙规则,以允许通过 ICMP 连接到虚拟机实例,类似于默认网络的 allow-icmp 规则:

gcloud

gcloud compute firewall-rules create NAME \
    --action=ALLOW \
    --direction=INGRESS \
    --network=NETWORK; default="default" \
    --priority=1000 \
    --rules=ICMP_PROTOCOL \
    --source-ranges=RANGES_OUTSIDE_VPC_NETWORK

替换以下内容:

  • NAME:此防火墙规则的名称。
  • NETWORK:应用此防火墙规则的网络的名称。默认值为 default
  • ICMP_PROTOCOL:使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "FIREWALL_NAME",
  "network": "projects/PROJECT_ID/global/networks/NETWORK",
  "direction": "INGRESS",
  "priority": 1000,
  "targetTags": [],
  "allowed": [
    {
      "IPProtocol": "ICMP_PROTOCOL"
    }
  ],
  "sourceRanges": [
    "RANGES_OUTSIDE_VPC_NETWORK"
  ]
}

替换以下内容:

  • PROJECT_ID:VPC 网络所在项目的 ID。
  • FIREWALL_NAME:在其中创建防火墙规则的 VPC 网络的名称。
  • NETWORK:防火墙规则的名称。
  • ICMP_PROTOCOL:使用协议名称 icmp 或协议编号 1 指定 ICMPv4。使用协议编号 58 指定 ICMPv6
  • RANGES_OUTSIDE_VPC_NETWORK:一个或多个 IP 地址范围。您可以在给定的防火墙规则中指定 IPv4 或 IPv6 范围。最佳实践是指定您需要允许访问的特定来源 IP 地址范围,而不是所有 IPv4 或 IPv6 来源。

    • 如果使用 0.0.0.0/0 作为来源范围,系统会允许来自所有 IPv4 来源(包括 Google Cloud 外部的来源)的流量。
    • 如果使用 ::/0 作为来源范围,系统会允许来自所有 IPv6 来源(包括 Google Cloud 外部的来源)的流量。

其他配置示例

下图是一个防火墙配置示例。该场景涉及 my-network,其中包含以下内容:

  • 子网 subnet1,IP 范围为 10.240.10.0/24
  • 子网 subnet2,IP 范围为 192.168.1.0/24
  • subnet2 中的实例 vm1,标记为 webserver,内部 IP 为 192.168.1.2
  • subnet2 中的实例 vm2,标记为 database,内部 IP 地址为 192.168.1.3
网络配置示例(点击可放大)
网络配置示例(点击可放大)

示例 1:拒绝所有入站 TCP 连接(从 subnet1 到端口 80 的连接除外)

此示例会创建一组防火墙规则,以拒绝所有入站 TCP 连接(从 subnet1 到端口 80 的连接除外)。

gcloud

  1. 创建一条防火墙规则,以拒绝流向带有 webserver 标记的实例的所有入站 TCP 流量。

    gcloud compute firewall-rules create deny-subnet1-webserver-access \
     --network NETWORK_NAME \
     --action deny \
     --direction ingress \
     --rules tcp \
     --source-ranges 0.0.0.0/0 \
     --priority 1000 \
     --target-tags webserver
    
  2. 创建一条防火墙规则,以允许 subnet1 (10.240.10.0/24) 中的所有 IP 访问带有 webserver 标记的实例上的 TCP 端口 80

    gcloud compute firewall-rules create vm1-allow-ingress-tcp-port80-from-subnet1 \
     --network NETWORK_NAME \
     --action allow \
     --direction ingress \
     --rules tcp:80 \
     --source-ranges 10.240.10.0/24 \
     --priority 50 \
     --target-tags webserver
    

示例 2:拒绝所有出站 TCP 连接(与 vm1 的端口 80 的连接除外)

gcloud

  1. 创建一条防火墙规则,拒绝所有出站 TCP 流量。

    gcloud compute firewall-rules create deny-all-access \
      --network NETWORK_NAME \
      --action deny \
      --direction egress \
      --rules tcp \
      --destination-ranges 0.0.0.0/0 \
      --priority 1000
    
  2. 创建一条防火墙规则,以允许定向到 vm1 的端口 80 的 TCP 流量。

    gcloud compute firewall-rules create vm1-allow-egress-tcp-port80-to-vm1 \
      --network NETWORK_NAME \
      --action allow \
      --direction egress \
      --rules tcp:80 \
      --destination-ranges 192.168.1.2/32 \
      --priority 60
    

示例 3:允许与外部主机的端口 443 的出站 TCP 连接

创建一条防火墙规则,以允许带有 webserver 标记的实例将出站 TCP 流量发送到示例外部 IP 地址 192.0.2.5 的端口 443

gcloud

gcloud compute firewall-rules create vm1-allow-egress-tcp-port443-to-192-0-2-5 \
   --network NETWORK_NAME \
   --action allow \
   --direction egress \
   --rules tcp:443 \
   --destination-ranges 192.0.2.5/32 \
   --priority 70 \
   --target-tags webserver

示例 4:允许从 vm2vm1 的 SSH 连接

创建一条防火墙规则,以允许 SSH 流量从带有 database 标记的实例 (vm2) 到达带有 webserver 标记的实例 (vm1)。

gcloud

gcloud compute firewall-rules create vm1-allow-ingress-tcp-ssh-from-vm2 \
   --network NETWORK_NAME \
   --action allow \
   --direction ingress \
   --rules tcp:22 \
   --source-tags database \
   --priority 80 \
   --target-tags webserver

示例 5:允许 1443 端口的 TCP 流量从网络服务器流向数据库(使用服务帐号)

如需详细了解服务帐号和角色,请参阅向服务帐号授予角色

请考虑下图中的情景,其中有两个通过模板自动扩缩的应用,一个是 Web 服务器应用 my-sa-web,另一个是数据库应用“my-sa-db”。安全管理员希望允许 TCP 流量通过目的地端口 1443my-sa-web 流向 my-sa-db

将防火墙规则与服务帐号搭配使用(点击可放大)
将防火墙规则与服务帐号搭配使用(点击可放大)

配置步骤(包括创建服务帐号的步骤)如下所示:

gcloud

  1. 项目 EDITOR 或项目 OWNER 创建服务帐号 my-sa-webmy-sa-db

    gcloud iam service-accounts create my-sa-web \
      --display-name "webserver service account"
    
    gcloud iam service-accounts create my-sa-db \
      --display-name "database service account"
    
  2. 项目 OWNER 通过设置 Identity and Access Management (IAM) 政策,为服务帐号 my-sa-web 的网络服务器开发者 web-dev@example.com 分配了 serviceAccountUser 角色。

    gcloud iam service-accounts add-iam-policy-binding \
     my-sa-web@my-project.iam.gserviceaccount.com \
     --member='user:web-dev@example.com' \
     --role='roles/iam.serviceAccountUser'
    
  3. 项目 OWNER 通过设置 IAM 政策针对服务帐号 my-sa-db 为数据库开发者“db-dev@example.com”分配 serviceAccountUser 角色。

    gcloud iam service-accounts add-iam-policy-binding \
     my-sa-db@my-project.iam.gserviceaccount.com \
     --member='user:db-dev@example.com' \
     --role='roles/iam.serviceAccountUser'
    
  4. 具有 Instance Admin 角色的开发者 web-dev@example.com 创建 Web 服务器实例模板,并授权实例以服务帐号 my-sa-web 的身份运行。

    gcloud compute instance-templates create [INSTANCE_TEMPLATE_NAME]  \
       --service-account my-sa-web@my-project-123.iam.gserviceaccount.com
    
  5. 具有 Instance Admin 角色的开发者 db-dev@example.com 创建数据库实例模板,并授权实例以服务帐号 my-sa-db 的身份运行。

    gcloud compute instance-templates create [INSTANCE_TEMPLATE_NAME] \
      --service-account my-sa-db@my-project-123.iam.gserviceaccount.com
    
  6. Security Admin 使用服务帐号创建防火墙规则,允许流量 TCP:1443 从服务帐号 my-sa-web 流向服务帐号 my-sa-db

    gcloud compute firewall-rules create FIREWALL_NAME \
       --network network_a \
       --allow TCP:1443 \
       --source-service-accounts my-sa-web@my-project.iam.gserviceaccount.com \
       --target-service-accounts my-sa-db@my-project.iam.gserviceaccount.com
    

问题排查

创建或更新防火墙规则时出现错误消息

您可能会看到以下某条错误消息:

  • Should not specify destination range for ingress direction.

    目标地址范围不是入站防火墙规则的有效参数。 除非明确指定方向为 egress,否则防火墙规则假定为入站规则。如果您创建的规则未指定方向,则该规则为入站规则,此类规则不允许使用目标范围。此外,对出站规则来说,来源范围也是无效参数。

  • Firewall direction cannot be changed once created.

    现有防火墙规则的方向无法更改。您必须使用正确的参数创建新规则,然后删除旧规则。

  • Firewall traffic control action cannot be changed once created.

    现有防火墙规则的操作无法更改。您必须使用正确的参数创建新规则,然后删除旧规则。

  • Service accounts must be valid RFC 822 email addresses. 防火墙规则中指定的服务帐号必须采用符合 RFC 822 规范的电子邮件地址格式。

    gcloud compute firewall-rules create bad --allow tcp --source-service-accounts invalid-email
    
    Creating firewall...failed.
    ERROR: (gcloud.compute.firewall-rules.create) Could not fetch resource:
    – Invalid value for field 'resource.sourceServiceAccounts[0]': 'invalid-email'. Service accounts must be valid RFC 822 email addresses.
    
  • ServiceAccounts and Tags are mutually exclusive and can't be combined in the same firewall rule. 您不能在同一条规则中同时指定服务帐号和标记。

    gcloud compute firewall-rules create bad --allow tcp --source-service-accounts test@google.com --target-tags target
    
    Creating firewall...failed.
     ERROR: (gcloud.compute.firewall-rules.create) Could not fetch resource:
    – ServiceAccounts and Tags are mutually exclusive and can't be combined in the same firewall rule.
    

无法连接到虚拟机实例

如果无法连接到虚拟机实例,请检查您的防火墙规则。

gcloud

  1. 如果您是从其他虚拟机实例发起连接,请列出该实例的出站防火墙规则。

    gcloud compute firewall-rules list --filter network=[NETWORK-NAME] \
      --filter EGRESS \
      --sort-by priority \
      --format="table(
          name,
          network,
          direction,
          priority,
          sourceRanges.list():label=SRC_RANGES,
          destinationRanges.list():label=DEST_RANGES,
          allowed[].map().firewall_rule().list():label=ALLOW,
          denied[].map().firewall_rule().list():label=DENY,
          sourceTags.list():label=SRC_TAGS,
          sourceServiceAccounts.list():label=SRC_SVC_ACCT,
          targetTags.list():label=TARGET_TAGS,
          targetServiceAccounts.list():label=TARGET_SVC_ACCT
          )"
    
  2. 检查目标 IP 是否被任何出站规则拒绝。优先级最高的规则(优先级数值最小)将替换优先级较低的规则。如果两个规则的优先级相同,则拒绝规则优先。

  3. 检查目标虚拟机实例所在网络的入站防火墙规则。

    gcloud compute firewall-rules list --filter network=[NETWORK-NAME] \
      --filter INGRESS \
      --sort-by priority \
      --format="table(
          name,
          network,
          direction,
          priority,
          sourceRanges.list():label=SRC_RANGES,
          destinationRanges.list():label=DEST_RANGES,
          allowed[].map().firewall_rule().list():label=ALLOW,
          denied[].map().firewall_rule().list():label=DENY,
          sourceTags.list():label=SRC_TAGS,
          sourceServiceAccounts.list():label=SRC_SVC_ACCT,
          targetTags.list():label=TARGET_TAGS,
          targetServiceAccounts.list():label=TARGET_SVC_ACCT
          )"
    

    示例输出。您的输出取决于防火墙规则列表。

    NAME                    NETWORK  DIRECTION  PRIORITY  SRC_RANGES    DEST_RANGES  ALLOW                         DENY  SRC_TAGS  SRC_SVC_ACCT      TARGET_TAGS  TARGET_SVC_ACCT
    default-allow-icmp      default  INGRESS    65534     0.0.0.0/0                  icmp
    default-allow-internal  default  INGRESS    65534     10.128.0.0/9               tcp:0-65535,udp:0-65535,icmp
    default-allow-rdp       default  INGRESS    65534     0.0.0.0/0                  tcp:3389
    default-allow-ssh       default  INGRESS    65534     0.0.0.0/0                  tcp:22
    firewall-with-sa        default  INGRESS    1000                                 tcp:10000                                     test1@google.com               target@google.com
    
  4. 此外,如果流量被任何入站流量或出站流量防火墙规则丢弃,您还可以在某个 VPC 网络中的虚拟机实例与其他 VPC 网络或非 Google Cloud 网络之间运行连接测试,以便排查问题。如需详细了解如何运行连接测试以排查各种场景问题,请参阅运行连接测试

我的防火墙规则是否处于启用状态?

要了解某条防火墙规则是否处于启用状态,请查看防火墙规则详情

Google Cloud Console 中的实施下,查找 EnabledDisabled

在 Google Cloud CLI 输出中,查找 disabled 字段。如果该字段显示 disabled:false,则表明规则已启用且正在实施。如果该字段显示 disabled: true,则表明规则已停用。

虚拟机实例上正在应用什么规则?

创建规则后,您可以检查它是否在特定实例上得到正确应用。如需了解详情,请参阅列出虚拟机实例网络接口的防火墙规则

使用来源标记的防火墙规则不会立即生效

使用来源标记的入站防火墙规则可能需要一段时间才能生效。如需了解详情,请参阅与入站防火墙规则的来源标记相关的注意事项

后续步骤