使用虛擬私有雲防火牆規則

本頁說明設定虛擬私有雲 (VPC) 防火牆規則的正確指令,並提供使用範例。有了 VPC 防火牆規則,您就能根據通訊埠號碼、標記或通訊協定,允許或拒絕 VPC 網路中虛擬機器 (VM) 執行個體的往來流量。

事前準備

如要進一步瞭解虛擬私有雲防火牆規則,例如預設網路的隱含規則和系統產生的規則,請參閱「虛擬私有雲防火牆規則」。

設定防火牆規則前,請先查看防火牆規則組成部分,熟悉 Trusted Cloud中使用的防火牆元件。

建立虛擬私有雲防火牆規則

虛擬私有雲防火牆規則是在網路層級定義,且僅會套用到規則建立時所在的網路。不過,您為各個防火牆規則選擇的名稱在專案內必須為專屬名稱。

防火牆規則可包含 IPv4 或 IPv6 範圍,但不能同時包含兩者。

建立防火牆規則時,您可以選擇啟用防火牆規則記錄。啟用記錄功能後,您可以省略中繼資料欄位,以節省儲存費用。詳情請參閱使用防火牆規則記錄

如要為目標或來源服務帳戶欄位指定多個服務帳戶,請使用 Google Cloud CLI、API 或用戶端程式庫。

預設網路會在建立時提供自動防火牆規則。如果您使用 Trusted Cloud 控制台,在建立網路時,可以輕鬆為自訂和自動模式網路建立類似的防火牆。如果您使用 gcloud CLI 或 API,並想建立與預設網路提供的防火牆規則類似的規則,請參閱「設定常見用途的防火牆規則」。

主控台

  1. 在 Trusted Cloud 控制台中,前往「Firewall policies」(防火牆政策) 頁面。

    前往「防火牆政策」頁面

  2. 點按「建立防火牆規則」

  3. 輸入防火牆規則的「Name」(名稱)

    此名稱在專案中不得重複。

  4. (選用) 您可以啟用防火牆規則記錄

    • 按一下 [Logs] (記錄) > [On] (啟用)
    • 如要省略中繼資料,請按一下「顯示記錄詳細資料」,然後取消勾選「包含中繼資料」核取方塊。
  5. 指定防火牆規則的「Network」(網路)

  6. 指定規則的「優先順序」

    數值越低,優先順序越高。

  7. 針對「Direction of traffic」(流量方向),選擇輸入或輸出。

  8. 針對「Action on match」(相符時執行的動作),選擇允許或拒絕。

  9. 指定規則的「Targets」(目標)

    • 如要將規則套用到網路中的所有執行個體,請選擇 All instances in the network
    • 如要根據網路 (目標) 標記將規則套用到特定執行個體,請選擇「指定的目標標記」,接著在「目標標記」欄位中,輸入要套用規則的標記。
    • 如要讓規則套用至與特定服務帳戶相關聯的執行個體,請選擇「指定的服務帳戶」,並在「服務帳戶範圍」底下,指示服務帳戶是位於目前專案還是其他專案,接著在「目標服務帳戶」欄位中選擇或輸入服務帳戶名稱。
  10. 針對輸入規則,指定「Source filter」(來源篩選器)

    • 如要依來源 IPv4 範圍篩選傳入流量,請選取「IPv4 範圍」,然後在「來源 IPv4 範圍」欄位中輸入 CIDR 區塊。如為任何 IPv4 來源,請使用 0.0.0.0/0
    • 如要依來源 IPv6 範圍篩選傳入流量,請選取「IPv6 範圍」,然後在「來源 IPv6 範圍」欄位中輸入 CIDR 區塊。如為任何 IPv6 來源,請使用 ::/0
    • 如要依網路標記篩選傳入流量,請選擇「來源標記」,然後在「來源標記」欄位中輸入網路標記。如需瞭解來源標記數量限制,請參閱每個網路的限制。只有在目標「並非」以服務帳戶指定時,才可依據來源標記進行篩選。詳情請參閱依服務帳戶篩選與依網路標記篩選的比較
    • 如要依服務帳戶篩選傳入流量,請選擇「Service account」(服務帳戶),並在「Service account scope」(服務帳戶範圍) 底下,指示服務帳戶是位於目前專案還是其他專案,接著在「Source service account」(來源服務帳戶) 欄位中選擇或輸入服務帳戶名稱。只有在目標「並非」以網路標記指定時,才可依據來源服務帳戶進行篩選。詳情請參閱依服務帳戶篩選與依網路標記篩選的比較
    • 必要時,可以指定「Second source filter」(次要來源篩選器)。次要來源篩選器無法使用與主要來源篩選器相同的篩選條件。來源 IP 範圍可與來源標記來源服務帳戶搭配使用。有效的來源設定會「結合」來源範圍 IP 位址,以及使用網路標記或服務帳戶標示的執行個體。也就是說,只要來源 IP 範圍「或」來源標記 (或來源服務帳戶) 符合篩選條件,來源就會納入有效來源集。
    • 來源標記來源服務帳戶無法同時使用。
  11. 針對輸入規則,指定「Destination filter」(目的地篩選器)

    • 如要依目的地 IPv4 範圍篩選傳入流量,請選取「IPv4 範圍」,並在「目的地 IPv4 範圍」欄位中輸入 CIDR 區塊。針對任何 IPv4 目的地使用 0.0.0.0/0
    • 如要依目的地 IPv6 範圍篩選傳入流量,請選取「IPv6 範圍」,並在「目的地 IPv6 範圍」欄位中輸入 CIDR 區塊。任何 IPv6 目的地都可使用 ::/0。 詳情請參閱「連入規則的目的地」。
  12. 針對輸出規則,指定「Destination filter」(目的地篩選器)

    • 如要依目的地 IPv4 範圍篩選傳出流量,請選取「IPv4 ranges」(IPv4 範圍),並在「Destination IPv4 ranges」(目的地 IPv4 範圍) 欄位中輸入 CIDR 區塊。針對任何 IPv4 目的地使用 0.0.0.0/0
    • 如要依目的地 IPv6 範圍篩選傳出流量,請選取「IPv6 範圍」,並在「目的地 IPv6 範圍」欄位中輸入 CIDR 區塊。針對任何 IPv6 目的地使用 ::/0
  13. 針對輸出規則,指定「Source filter」(來源篩選器)

    • 如要依來源 IPv4 範圍篩選傳出流量,請選取「IPv4 ranges」(IPv4 範圍),並在「Source IPv4 ranges」(來源 IPv4 範圍) 欄位中輸入 CIDR 區塊。如為任何 IPv4 來源,請使用 0.0.0.0/0
    • 如要依來源 IPv6 範圍篩選傳出流量,請選取「IPv6 範圍」,並在「來源 IPv6 範圍」欄位中輸入 CIDR 區塊。任何 IPv6 目的地都可使用 ::/0。 詳情請參閱輸出規則的來源
  14. 定義要套用規則的「Protocols and ports」(通訊協定和通訊埠)

    • 如要將規則套用到所有通訊協定和目的地通訊埠,請根據要採取的動作選取「全部允許」或「全部拒絕」
    • 如要定義特定通訊協定和目的地通訊埠,請選取「指定的通訊協定和通訊埠」

      • 選取「TCP」TCP以包含 TCP 通訊協定和目的地通訊埠。輸入 all 或以逗號分隔的目的地通訊埠清單,例如 20-22, 80, 8080
      • 選取「UDP」以包含 UDP 通訊協定和目的地通訊埠。輸入 all 或以逗號分隔的目的地通訊埠清單,例如 67-69, 123
      • 選取「其他」,以包含 icmpsctp 等通訊協定或通訊協定編號。舉例來說,使用 icmp 或通訊協定編號 1 代表 IPv4 ICMP。針對 IPv6 ICMP 使用通訊協定編號 58

        詳情請參閱通訊協定和目的地連接埠

  15. (選用) 您可以將防火牆規則的強制執行狀態設為已停用,如此一來,您就能在不強制執行防火牆規則的情況下建立規則。按一下「停用規則」,然後選取「已停用」

  16. 點選「建立」

gcloud

如要建立虛擬私有雲防火牆規則,請使用 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 也是如此。
  • 如果是輸出規則,如要進一步調整來源,請使用 --source-ranges 以 CIDR 格式指定 IPv4 或 IPv6 位址範圍。如果省略 --source-ranges,則輸出來源為任何 IPv4 位址 0.0.0.0/0。詳情請參閱「Egress 規則的來源」和「Egress 規則的目標和 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 啟用記錄功能後,防火牆規則記錄功能預設會納入基礎和中繼資料欄位。您可以省略中繼資料欄位,以節省儲存費用。詳情請參閱「使用防火牆規則記錄」。

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

建立虛擬私有雲防火牆規則。

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:虛擬私有雲網路所在的專案 ID。
  • NETWORK:建立防火牆規則的虛擬私有雲網路名稱。
  • RULE_NAME:防火牆規則的名稱。

  • 針對輸入防火牆規則,指定輸入來源和目的地:

    • 使用 sourceRangessourceTagssourceServiceAccounts 欄位指定進入來源。

    • sourceRanges 可以是 IPv4 或 IPv6 範圍,但不能同時包含兩者。如要使用範圍 0.0.0.0/0,請勿指定任何欄位。

    • 您無法同時使用 sourceTagssourceServiceAccounts 欄位。不過,您可以搭配 sourceTagssourceServiceAccounts 使用 sourceRanges。如果有的話,連線只要符合其中一項,就會套用防火牆規則。

    • 如果是目標欄位,使用 sourceTags 欄位時,就無法使用 targetServiceAccounts 欄位。您必須使用 targetTags 欄位或不使用目標欄位。同樣地,如果您使用 sourceServiceAccounts 欄位,就無法使用 targetTags 欄位。如未指定目標欄位,規則會套用至網路中的所有目標。

    • 使用 destinationRanges 欄位指定連入目的地。destinationRanges 可以是 IPv4 或 IPv6 範圍,但不能同時包含兩者。
      如果未指定目的地, Trusted Cloud 會使用 0.0.0.0/0。詳情請參閱「連入規則的目的地」和「連入規則的目標和 IP 位址」。

  • 針對輸出防火牆規則,請指定輸出來源和目的地:

    • 使用 sourceRanges 欄位指定輸出來源。sourceRange 可以是 IPv4 或 IPv6 範圍,但不能同時包含兩者。
      如未指定來源, Trusted Cloud 會使用 0.0.0.0/0。 詳情請參閱「Egress 規則的來源」和「Egress 規則的目標和 IP 位址」。

    • 使用 destinationRanges 欄位指定目的地。 destinationRanges 可以是 IPv4 或 IPv6 範圍,但不得同時包含兩者。
      如未指定目的地, Trusted 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.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: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", 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\Allowed;
use Google\Cloud\Compute\V1\Client\FirewallsClient;
use Google\Cloud\Compute\V1\Enums\Firewall\Direction;

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

/**
 * 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.
    $request = (new InsertFirewallRequest())
        ->setFirewallResource($firewallResource)
        ->setProject($projectId);
    $operation = $firewallsClient->insert($request);

    // 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

from __future__ import annotations

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:
    """
    Waits 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

更新虛擬私有雲防火牆規則

您可以修改虛擬私有雲防火牆規則的部分元件,例如相符條件中指定的通訊協定和目的地通訊埠。您無法修改防火牆規則的名稱、網路、相符時執行的動作流量方向

如要變更名稱、網路、動作或方向部分,您必須改為刪除規則建立新規則

如要新增或移除多個服務帳戶,請使用 gcloud CLI、API 或用戶端程式庫。您無法使用 Trusted Cloud 主控台指定多個目標服務帳戶或來源服務帳戶。

主控台

  1. 在 Trusted Cloud 控制台中,前往「Firewall policies」(防火牆政策) 頁面。

    前往「防火牆政策」頁面

  2. 按一下要修改的防火牆規則。

  3. 按一下 [Edit] (編輯)

  4. 修改任何可編輯的元件以符合您的需求。

  5. 按一下 [儲存]

gcloud

如要更新虛擬私有雲防火牆規則,請使用 gcloud compute firewall-rules update 指令:

gcloud compute firewall-rules update RULE_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/RULE_NAME
{
  "name": "RULE_NAME",
  "network": "projects/PROJECT-ID/global/networks/NETWORK",
  ... other fields
}

更改下列內容:

  • PROJECT_ID:虛擬私有雲網路所在的專案 ID。
  • NETWORK:防火牆規則所在的虛擬私有雲網路名稱。
  • RULE_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 "cloud.google.com/go/compute/apiv1/computepb"
	"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: %w", 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: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", 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\Client\FirewallsClient;
use Google\Cloud\Compute\V1\Firewall;
use Google\Cloud\Compute\V1\PatchFirewallRequest;

/**
 * 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.
    $request = (new PatchFirewallRequest())
        ->setFirewall($firewallRuleName)
        ->setFirewallResource($firewallResource)
        ->setProject($projectId);
    $operation = $firewallsClient->patch($request);

    // 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

from __future__ import annotations

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:
    """
    Waits 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")

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 網路的所有 VPC 防火牆規則。針對每個防火牆規則,Trusted Cloud 會顯示規則類型、目標和篩選器等詳細資料。

啟用防火牆規則記錄後,防火牆深入分析就能提供防火牆規則的深入分析資訊,協助您瞭解並安全地最佳化規則設定。舉例來說,您可以查看過去六週內未使用的 allow 規則。詳情請參閱防火牆洞察說明文件中的「使用防火牆規則詳細資料畫面」。

主控台

如要顯示專案中所有網路的所有虛擬私有雲防火牆規則:

如要顯示特定網路的虛擬私有雲防火牆規則:

  1. 在 Trusted Cloud 控制台中,前往「VPC networks」(虛擬私有雲網路) 頁面。

    前往「VPC networks」(虛擬私有雲網路)

  2. 按一下 VPC 網路的名稱,即可前往該 VPC 網路的詳細資料頁面。

  3. 在網路的詳細資料頁面中,按一下「Firewalls」(防火牆) 分頁標籤。

  4. 展開「vpc-firewall-rules」

gcloud

如要產生特定網路的虛擬私有雲防火牆規則排序清單,請使用 gcloud compute firewall-rules list 指令:

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
        )"

請將 NETWORK 替換為要列出防火牆規則的網路名稱。

API

列出特定網路的所有虛擬私有雲防火牆規則。

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

更改下列內容:

  • PROJECT_ID:虛擬私有雲網路所在的專案 ID。
  • NETWORK:虛擬私有雲網路的名稱,其中包含要列出的防火牆規則。

詳情請參閱 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"
	computepb "cloud.google.com/go/compute/apiv1/computepb"
	"google.golang.org/api/iterator"
)

// 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: %w", 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\Client\FirewallsClient;
use Google\Cloud\Compute\V1\ListFirewallsRequest;

/**
 * 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();
    $request = (new ListFirewallsRequest())
        ->setProject($projectId);
    $firewallList = $firewallClient->list($request);

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

Python

from __future__ import annotations

from collections.abc 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

列出 VM 執行個體網路介面的虛擬私有雲防火牆規則

針對每個網路介面, Trusted Cloud 主控台會列出套用到該介面的所有 VPC 防火牆規則,以及介面實際使用的規則。防火牆規則可以遮蔽其他規則,因此介面實際上可能不會使用所有套用到介面的規則。

防火牆規則是透過規則的目標參數,與 VM 執行個體建立關聯並套用到該執行個體。您可以查看所有套用規則,確認特定規則是否正套用至介面。

啟用防火牆規則記錄後,防火牆深入分析就能提供防火牆規則的深入分析資訊,協助您瞭解並安全地最佳化規則設定。舉例來說,您可以查看介面上的哪些規則在過去六週內發揮作用。詳情請參閱防火牆洞察說明文件中的「使用 VM 網路介面詳細資料畫面」一文。

主控台

如要查看套用到 VM 執行個體特定網路介面的 VPC 規則:

  1. 前往 Trusted Cloud 控制台的「VM instances」(VM 執行個體) 頁面

    前往 VM 執行個體

  2. 找出要查看的執行個體。

  3. 在執行個體的「更多動作」選單 () 中,選取「查看網路詳細資料」

  4. 如果執行個體擁有多個網路介面,請在「Selected network interface」(選取的網路介面) 欄位中,選取要查看的網路介面。

  5. 在「防火牆和路徑詳細資料」部分中,選取「防火牆」分頁標籤。

  6. 展開「vpc-firewall-rules」

  7. 查看資料表,判斷是否允許進出特定 IP 位址的流量。

查看虛擬私有雲防火牆規則詳細資料

您可以檢查虛擬私有雲防火牆規則,查看其名稱、適用網路和元件等資訊,包含該規則是否啟用或停用在內。

主控台

  1. 列出您的防火牆規則,您可以查看所有規則的清單或特定網路中的規則清單。
  2. 按一下要查看的規則。

gcloud

下列指令會說明個別的 VPC 防火牆規則,由於防火牆規則名稱為專案內的專屬名稱,因此在說明現有防火牆規則時,您不必指定網路。

gcloud compute firewall-rules describe RULE_NAME

RULE_NAME 替換為防火牆規則的名稱。

API

說明指定的虛擬私有雲防火牆規則。

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

將預留位置替換為有效值:

  • PROJECT_ID:防火牆規則所在的專案 ID。
  • RULE_NAME:要說明的防火牆規則名稱。

詳情請參閱 firewalls.get 方法。

刪除虛擬私有雲防火牆規則

主控台

  1. 列出虛擬私有雲防火牆規則,您可以查看所有規則的清單或特定網路中的規則清單。
  2. 按一下要刪除的規則。
  3. 按一下 [Delete] (刪除)
  4. 再按一下 [刪除] 加以確認。

gcloud

如要刪除虛擬私有雲防火牆規則,請使用 gcloud compute firewall-rules delete 指令:

gcloud compute firewall-rules delete RULE_NAME

RULE_NAME 替換為要刪除的規則名稱。

API

刪除虛擬私有雲防火牆規則。

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

更改下列內容:

  • PROJECT_ID:防火牆規則所在專案的 ID。
  • RULE_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 "cloud.google.com/go/compute/apiv1/computepb"
)

// 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: %w", 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: %w", err)
	}

	if err = op.Wait(ctx); err != nil {
		return fmt.Errorf("unable to wait for the operation: %w", 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\Client\FirewallsClient;
use Google\Cloud\Compute\V1\DeleteFirewallRequest;

/**
 * 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.
    $request = (new DeleteFirewallRequest())
        ->setFirewall($firewallRuleName)
        ->setProject($projectId);
    $operation = $firewallsClient->delete($request);

    // 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

from __future__ import annotations

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:
    """
    Waits 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")

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 位址範圍,不能同時包含兩者。

允許 VM 之間的內部輸入連線

下列範例會建立防火牆規則,允許內部 TCP、UDP 和 ICMP 連線連至 VM 執行個體,類似於預設網路的 allow-internal 規則。

gcloud

使用 gcloud compute firewall-rules create 指令:

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

更改下列內容:

  • RULE_NAME:這個防火牆規則的名稱。
  • NETWORK:這個防火牆規則套用到的網路名稱。預設值為 default
  • ICMP_PROTOCOL:ICMP 通訊協定類型。使用通訊協定名稱 icmp 或通訊協定編號 1,指定 ICMPv4。使用通訊協定編號 58 指定 ICMPv6。
  • SUBNET_RANGES:一或多個 IP 位址範圍。 加入 IP 位址範圍後,該範圍的流量就能抵達虛擬私有雲網路中的任何 VM 目的地。您可以在特定防火牆規則中指定 IPv4 或 IPv6 範圍。

    IPv4 子網路範圍:

    • 自動模式虛擬私有雲端網路使用的 IP 位址範圍位於 10.128.0.0/9 內。
    • 自訂模式網路可以使用任何有效 IPv4 範圍。如果虛擬私有雲網路中的子網路未使用連續範圍,您可能需要指定多個範圍。
    • 您可以使用 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 允許來自所有私人 IPv4 位址範圍 (RFC 1918 範圍) 的流量。

    IPv6 子網路範圍:

    • 如果您已為 VPC 網路指派內部 IPv6 位址範圍,即可將該範圍做為來源範圍。使用 VPC 網路的內部 IPv6 範圍,表示防火牆規則包含所有目前和未來的內部 IPv6 子網路範圍。您可以使用下列指令,找出虛擬私有雲網路的內部 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": "RULE_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:虛擬私有雲網路所在的專案 ID。
  • RULE_NAME:防火牆規則的名稱。
  • NETWORK:建立防火牆規則的虛擬私有雲網路名稱。預設值為 default
  • ICMP_PROTOCOL:ICMP 通訊協定類型。 使用通訊協定名稱 icmp 或通訊協定編號 1 指定 ICMPv4。使用通訊協定編號 58 指定 ICMPv6。
  • INTERNAL_SOURCE_RANGES:一或多個 IP 範圍。 如要允許虛擬私有雲網路中所有子網路的內部流量,請指定虛擬私有雲網路中使用的 IP 位址範圍。您可以在特定防火牆規則中指定 IPv4 或 IPv6 範圍。

    IPv4 子網路範圍:

    • 自動模式虛擬私有雲端網路使用的 IP 位址範圍位於 10.128.0.0/9 內。
    • 自訂模式網路可以使用任何有效 IPv4 範圍。如果虛擬私有雲網路中的子網路未使用連續範圍,您可能需要指定多個範圍。
    • 您可以使用 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 允許來自所有私人 IPv4 位址範圍 (RFC 1918 範圍) 的流量。

    IPv6 子網路範圍:

    • 如果您已為 VPC 網路指派內部 IPv6 位址範圍,即可將該範圍做為來源範圍。使用 VPC 網路的內部 IPv6 範圍,表示防火牆規則包含所有目前和未來的內部 IPv6 子網路範圍。您可以使用下列指令,找出虛擬私有雲網路的內部 IPv6 範圍:

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

      您也可以指定特定的內部 IPv6 子網路範圍。

    • 如要允許外部 IPv6 子網路範圍的流量,您必須指定要納入的每個子網路的 IPv6 位址範圍。

允許連線至 VM 的輸入 SSH 連線

下列範例會建立防火牆規則,允許與 VM 執行個體建立 SSH 連線,類似於預設網路的 allow-ssh 規則。

gcloud

使用 gcloud compute firewall-rules create 指令:

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

更改下列內容:

  • RULE_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 來源的流量,包括 Trusted Cloud外部的來源。
    • 如果來源範圍是 ::/0,系統會允許來自所有 IPv6 來源的流量,包括 Trusted Cloud外部的來源。

API

POST https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
  "kind": "compute#firewall",
  "name": "RULE_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:虛擬私有雲網路所在的專案 ID。
  • RULE_NAME:防火牆規則的名稱。
  • 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 來源的流量,包括 Trusted Cloud外部的來源。
    • 如果來源範圍是 ::/0,系統會允許來自所有 IPv6 來源的流量,包括 Trusted Cloud外部的來源。

允許連入 VM 的 RDP 連線

下列範例會建立防火牆規則,允許 Microsoft 遠端桌面通訊協定 (RDP) 連線至 VM 執行個體,類似於預設網路的 allow-rdp 規則。

gcloud

使用 gcloud compute firewall-rules create 指令:

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

更改下列內容:

  • RULE_NAME:這個防火牆規則的名稱。
  • NETWORK:這個防火牆規則套用到的網路名稱。預設值為 default
  • RANGES_OUTSIDE_VPC_NETWORK:一或多個 IP 位址範圍。您可以在特定防火牆規則中指定 IPv4 或 IPv6 範圍。最佳做法是指定需要允許存取的特定 IP 位址範圍,而非所有 IPv4 或 IPv6 來源。

    • 如果來源範圍包含 35.235.240.0/20,且符合所有其他必要條件,即可使用 Identity-Aware Proxy (IAP) TCP 轉送功能建立遠端桌面協定連線。詳情請參閱「使用 IAP 進行轉送 TCP」一文。
    • 如果來源範圍是 0.0.0.0/0,系統會允許來自所有 IPv4 來源的流量,包括 Trusted Cloud外部的來源。
    • 如果來源範圍是 ::/0,系統會允許來自所有 IPv6 來源的流量,包括 Trusted Cloud外部的來源。

API

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

更改下列內容:

  • PROJECT_ID:虛擬私有雲網路所在的專案 ID。
  • RULE_NAME:防火牆規則的名稱。
  • NETWORK:建立防火牆規則的虛擬私有雲網路名稱。
  • RANGES_OUTSIDE_VPC_NETWORK:一或多個 IP 位址範圍。您可以在特定防火牆規則中指定 IPv4 或 IPv6 範圍。最佳做法是指定需要允許存取的特定 IP 位址範圍,而非所有 IPv4 或 IPv6 來源。

    • 如果來源範圍包含 35.235.240.0/20,且符合所有其他必要條件,即可使用 Identity-Aware Proxy (IAP) TCP 轉送功能建立遠端桌面協定連線。詳情請參閱「使用 IAP 進行轉送 TCP」。
    • 如果來源範圍是 0.0.0.0/0,系統會允許來自所有 IPv4 來源的流量,包括 Trusted Cloud外部的來源。
    • 如果來源範圍是 ::/0,系統會允許來自所有 IPv6 來源的流量,包括 Trusted Cloud外部的來源。

允許輸入 ICMP 連線至 VM

下列範例會建立防火牆規則,允許與 VM 執行個體建立 ICMP 連線,類似於預設網路的 allow-icmp 規則。

gcloud

使用 gcloud compute firewall-rules create 指令:

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

更改下列內容:

  • RULE_NAME:防火牆規則的名稱。
  • NETWORK:這個防火牆規則套用到的網路名稱。預設值為 default
  • ICMP_PROTOCOL:ICMP 通訊協定類型。 使用通訊協定名稱 icmp 或通訊協定編號 1 指定 ICMPv4。使用通訊協定編號 58 指定 ICMPv6。
  • RANGES_OUTSIDE_VPC_NETWORK:一或多個 IP 位址範圍。您可以在特定防火牆規則中指定 IPv4 或 IPv6 範圍。最佳做法是指定需要允許存取的特定 IP 位址範圍,而非所有 IPv4 或 IPv6 來源。

    • 如果來源範圍是 0.0.0.0/0,系統會允許來自所有 IPv4 來源的流量,包括 Trusted Cloud外部的來源。
    • 如果來源範圍是 ::/0,系統會允許來自所有 IPv6 來源的流量,包括 Trusted Cloud外部的來源。

API

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

更改下列內容:

  • PROJECT_ID:虛擬私有雲網路所在的專案 ID。
  • RULE_NAME:防火牆規則的名稱。
  • NETWORK:建立防火牆規則的虛擬私有雲網路名稱。
  • ICMP_PROTOCOL:要使用的 ICMP 通訊協定類型。使用通訊協定名稱 icmp 或通訊協定編號 1 指定 ICMPv4。 使用通訊協定編號 58 指定 ICMPv6。
  • RANGES_OUTSIDE_VPC_NETWORK:一或多個 IP 位址範圍。您可以在特定防火牆規則中指定 IPv4 或 IPv6 範圍。最佳做法是指定需要允許存取的特定 IP 位址範圍,而非所有 IPv4 或 IPv6 來源。

    • 如果來源範圍是 0.0.0.0/0,系統會允許來自所有 IPv4 來源的流量,包括 Trusted Cloud外部的來源。
    • 如果來源範圍是 ::/0,系統會允許來自所有 IPv6 來源的流量,包括 Trusted Cloud外部的來源。

其他設定範例

圖 1 說明名為 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
這個虛擬私有雲網路包含兩個子網路,每個子網路都含有 VM;subnet2 包含已指派網路標記的 VM。
圖 1. 這個 VPC 網路包含兩個子網路,每個子網路都含有 VM;subnet2 含有已指派網路標記的 VM (按一下可放大)。

範例 1:除了從 subnet1 到通訊埠 80 的連線以外,拒絕其他所有輸入 TCP 連線

本範例會建立一系列防火牆虛擬私有雲規則,拒絕所有輸入 TCP 連線,從 subnet1 到通訊埠 80 的連線則除外。

gcloud

  1. 建立防火牆規則,拒絕所有輸入 TCP 流量傳送到具有 webserver 標記的執行個體。

    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
    

    NETWORK_NAME 替換為網路名稱。

  2. 建立防火牆規則,允許 subnet1 中的所有 IP 位址 (10.240.10.0/24) 存取具有 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
    

    NETWORK_NAME 替換為網路名稱。

範例 2:除了與 vm1 的通訊埠 80 的連線以外,拒絕其他所有輸出 TCP 連線

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
    

    NETWORK_NAME 替換為網路名稱。

  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
    

    NETWORK_NAME 替換為網路名稱。

範例 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

NETWORK_NAME 替換為網路名稱。

範例 4:允許從 vm2 到 vm1 的 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

NETWORK_NAME 替換為網路名稱。

範例 5:使用服務帳戶允許從網路伺服器到資料庫之間的 TCP:1443

如要進一步瞭解服務帳戶與角色,請參閱將角色授予服務帳戶

設想圖 2 中的情境。在範例情境中,有兩個會透過範本自動調整資源配置的應用程式:一個與 my-sa-webserver 服務帳戶相關聯的網路伺服器應用程式,以及一個與 my-sa-database 服務帳戶相關聯的資料庫應用程式。安全管理員想要允許 TCP 流量從具有 my-sa-webserver 服務帳戶的 VM,傳送到具有 my-sa-database 服務帳戶的 VM 的目的地通訊埠 1443

防火牆規則允許流量從服務帳戶為 my-sa-webserver 的 VM,傳送到服務帳戶為 my-sa-database 的 VM 的 1443 連接埠。
圖 2. 防火牆規則允許流量從服務帳戶為 my-sa-webserver 的 VM,傳送到服務帳戶為 my-sa-database 的 VM 的 1443 埠 (按一下可放大)。

包含建立服務帳戶在內的設定步驟如下所示。

gcloud

  1. 專案「編輯者」或專案「擁有者」建立服務帳戶 my-sa-webservermy-sa-database

    gcloud iam service-accounts create my-sa-webserver \
        --display-name "webserver service account"
    
    gcloud iam service-accounts create my-sa-database \
        --display-name "database service account"
    
  2. 專案「擁有者」設定身分與存取權管理 (IAM) 政策,以針對網路伺服器開發人員 web-dev@example.com 指派服務帳戶 my-sa-webserverserviceAccountUser 角色。

    gcloud iam service-accounts add-iam-policy-binding \
    my-sa-webserver@my-project.s3ns-system.iam.gserviceaccount.com \
        --member='user:web-dev@example.com' \
        --role='roles/iam.serviceAccountUser'
    
  3. 專案「擁有者」設定身分與存取權管理政策,以針對資料庫開發人員 db-dev@example.com 指派服務帳戶 my-sa-databaseserviceAccountUser 角色。

    gcloud iam service-accounts add-iam-policy-binding \
    my-sa-database@my-project.s3ns-system.iam.gserviceaccount.com \
        --member='user:db-dev@example.com' \
        --role='roles/iam.serviceAccountUser'
    
  4. 擁有執行個體管理員角色的開發人員 web-dev@example.com 建立網路伺服器執行個體範本,並授權執行個體以服務帳戶 my-sa-webserver 的身分執行。

    gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
        --service-account my-sa-webserver@my-project-123.s3ns-system.iam.gserviceaccount.com
    
  5. 擁有執行個體管理員角色的開發人員 db-dev@example.com 建立資料庫執行個體範本,並授權執行個體以服務帳戶 my-sa-database 的身分執行。

    gcloud compute instance-templates create INSTANCE_TEMPLATE_NAME \
        --service-account my-sa-database@my-project-123.s3ns-system.iam.gserviceaccount.com
    
  6. 安全管理員建立防火牆規則,允許來自服務帳戶 my-sa-webserver 的 VM 流量,連線至服務帳戶 my-sa-database 的 VM 通訊埠 1443。

    gcloud compute firewall-rules create RULE_NAME \
        --network network_a \
        --allow TCP:1443 \
        --source-service-accounts my-sa-webserver@my-project.s3ns-system.iam.gserviceaccount.com \
        --target-service-accounts my-sa-database@my-project.s3ns-system.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.
    

找不到資源錯誤

刪除虛擬私有雲網路或防火牆規則時,您可能會看到類似下列訊息: The resource "aet-uscentral1-subnet--1-egrfw" was not found.

這個錯誤可能會導致您無法刪除默示防火牆規則或查看其詳細資料。處於這種狀態的防火牆規則也可能會導致您無法刪除虛擬私有雲網路。

如要刪除以這種方式封鎖的防火牆規則或網路,請先刪除相關聯的無伺服器虛擬私有雲存取連接器,然後再試一次。如要進一步瞭解如何刪除無伺服器虛擬私有雲存取連接器,請參閱刪除連接器

防火牆過大錯誤

您可能會看到下列錯誤訊息: Google Compute Engine: The network contains too many large firewalls.

為維護安全性和效能,虛擬私有雲網路可實作的防火牆規則複雜度和數量設有限制。如果看到這個錯誤,請要求帳戶管理團隊簡化或合併防火牆規則。

無法連線至 VM 執行個體

如果您無法連線至 VM 執行個體,請檢查您的防火牆規則。

gcloud

  1. 如果您從另一個 VM 執行個體啟動連線,請列出該執行個體的輸出防火牆規則。

    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
          )"
    

    NETWORK_NAME 替換為網路名稱。

  2. 檢查是否有任何輸出規則拒絕目的地 IP。優先順序最高 (優先順序數字最小) 的規則會覆寫優先順序較低的規則。如果有兩個規則的優先順序相同,將以動作為拒絕的規則為優先。

  3. 針對包含目的地 VM 執行個體的網路,檢查輸入防火牆規則。

    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
          )"
    

    NETWORK_NAME 替換為網路名稱。

    輸出範例。您的輸出內容視您的防火牆規則清單而定。

    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. 您也可以對虛擬私有雲網路中的 VM 執行個體,以及其他虛擬私有雲網路或非 Google 雲端網路執行連線測試,藉此排解流量是否遭任何輸入或輸出防火牆規則捨棄的問題。如要進一步瞭解如何執行連線能力測試來排解各種情境的問題,請參閱「執行連線能力測試」。

我的虛擬私有雲防火牆規則為啟用狀態或停用狀態?

如要查看是否啟用或停用防火牆規則,請參閱防火牆規則詳細資料

Trusted Cloud console中,查看「Enforcement」(強制執行) 區段顯示為「Enabled」(已啟用) 還是「Disabled」(已停用)

在 gcloud CLI 輸出內容中,找出 disabled 欄位。 如果顯示 disabled:false,則規則為啟用狀態且強制執行中;如果顯示 disabled: true,則規則為停用狀態。

哪個規則會套用在 VM 執行個體上?

建立規則後,您可以檢查規則是否正確套用到特定執行個體。詳情請參閱列出 VM 執行個體網路介面的防火牆規則

含有來源標記的虛擬私有雲防火牆規則不會立即生效

使用來源標記的輸入防火牆規則可能需要一段時間才能傳播。詳情請參閱與輸入防火牆規則來源標記相關的注意事項

後續步驟