Security policy overview

Google Cloud Armor security policies protect your application by regulating which requests are allowed and denied access to your load balancer. Each security policy is made up of a set of rules that filter traffic based on conditions like an incoming request's IP address, IP range, region code, or request headers.

Google Cloud Armor security policies are available only for backend services behind an external HTTP(S) load balancer. The load balancer can be in Premium Tier or Standard Tier.

The backends to the backend service can be virtual machine (VM) instances in an instance group, zonal network endpoint groups (zonal NEGs), or internet network endpoint groups (internet NEGs). When you use Google Cloud Armor to protect a hybrid deployment or multi-cloud architecture, the backends must be internet NEGs, or hybrid connectivity NEGs when you use Traffic Director in a on-premises or multi-environment deployment. Google Cloud Armor also protects serverless NEGs when traffic is routed through a load balancer. To ensure that only traffic that has been routed through your load balancer reaches your NEG, see Ingress controls.

Edge security with Google Cloud Armor security policies

HTTP(S) Load Balancing is implemented at the edge of Google's network in Google's points of presence (PoPs) around the world. In Premium Tier, user traffic directed to an external HTTP(S) load balancer enters the PoP closest to the user. It is then load balanced over Google's global network to the closest backend that has sufficient capacity available. In Standard Tier, user traffic enters Google's network through peering, ISP, or transit networks in the region where you have deployed your Google Cloud resources.

Google Cloud Armor security policies enable you to allow or deny access to your external HTTP(S) load balancer at the Google Cloud edge, as close as possible to the source of incoming traffic. This prevents unwelcome traffic from consuming resources or entering your Virtual Private Cloud (VPC) networks.

The following diagram illustrates the location of the external HTTP(S) load balancers, the Google network, and Google data centers.

Google Cloud Armor policy at network edge.
Google Cloud Armor policy at network edge (click to enlarge)

Requirements

These are the requirements for Google Cloud Armor security policies:

  • The load balancer must be an external HTTP(S) load balancer.
  • The backend service's load balancing scheme must be EXTERNAL.
  • The backend service's protocol must be one of HTTP, HTTPS, or HTTP/2.

About Google Cloud Armor security policies

Google Cloud Armor security policies are sets of rules that match on attributes from L3 to L7 to protect externally facing applications or services. Each rule is evaluated with respect to incoming traffic.

A Google Cloud Armor security policy rule consists of a match condition and an action to take when that condition is met. Conditions can be as simple as whether the incoming traffic's source IP address matches a specific IP address or CIDR range (also known as IP address allowlist and denylist rules). Alternatively, by using the Google Cloud Armor custom rules language reference, you can create custom conditions that match on various attributes of the incoming traffic, such as the URL path, request method, or request header values.

You can associate a Google Cloud Armor security policy with one or more backend services. A backend service can have only one security policy associated with it, but your backend services do not all need to be associated with the same security policy.

If a Google Cloud Armor security policy is associated with any backend service, it can't be deleted. A backend service can be deleted regardless of whether it has an associated security policy.

If multiple forwarding rules point to a backend service that has an associated security policy, the policy rules are enforced for all traffic coming in to each of the forwarding rule IP addresses.

In the following illustration, the Google Cloud Armor security policy internal-users-policy is associated with the backend service test-network.

Google Cloud Armor security policy at network edge.
Google Cloud Armor security policy at network edge (click to enlarge)

Google Cloud Armor security policies have the following core features:

  • You can optionally use the QUIC protocol with load balancers that use Google Cloud Armor.

  • You can use Google Cloud Armor with external HTTP(S) load balancers that are in either of the following Network Service Tiers:

    • Premium Tier
    • Standard Tier
  • You can use security policies with GKE and the default Ingress controller.

Security policy actions

When matching with a condition, by default one of the following actions is enforced:

  • Allow
  • Deny

Rule evaluation order

Rule evaluation order is determined by rule priority, from the lowest number to the highest number. The rule with the lowest numeric value assigned has the highest logical priority and is evaluated prior to rules with lower logical priorities. The minimum numeric priority is 0. The priority of a rule decreases as its number increases (1, 2, 3, N+1). You cannot configure two or more rules with the same priority. The priority for each rule must be set to a number from 0 to 2147483646 inclusive. The priority value 2147483647, also known as INT-MAX, is reserved for the default rule.

Priority numbers can have gaps, which enable you to add or remove rules in the future without affecting the rest of the rules. For example, 1, 2, 3, 4, 5, 9, 12, 16 is a valid series of priority numbers to which you could add rules numbered from 6 to 8, 10 to 11, and 13 to 15 in the future. You don't need to change the existing rules except for the order of execution.

Typically, the highest priority rule that matches the request is applied. However, there is an exception when HTTP POST requests are evaluated against preconfigured rules that use evaluatePreconfiguredExpr(). The exception is as follows.

For HTTP POST requests, Google Cloud Armor receives the request's header before the body (payload). Because Google Cloud Armor receives the header information first, it evaluates rules that match against the header, but it does not match any preconfigured rules on the body. If there are multiple header-based rules, Google Cloud Armor evaluates them based on their priority as expected.

After Google Cloud Armor receives the HTTP POST body, it evaluates rules that apply to both the request headers and body. As a result, it's possible that lower priority rules that allow a request's header are matched before higher priority rules that block the request's body. In such cases, it is possible that the HTTP header portion of the request is sent to the target backend service, but the POST body containing potentially malicious content is blocked.

Examples

In the following example, rules 1, 2, and 3 are evaluated in that order for the IP and HTTP header fields. However, if an IP 9.9.9.1 launches an XSS attack in the HTTP POST body, only the body is blocked (by rule 2); the HTTP header passes through to the backend (by rule 3).

Rule1
expr: inIPRange(origin.ip, '10.10.10.0/24')
action: deny(403)
priority: 1
Rule2
expr: evaluatePreconfiguredExpr('xss-stable')
action: deny(403)
priority: 2
Rule3
expr: inIPRange(origin.ip, '9.9.9.0/24')
action: allow
priority: 3
Rule-default
action: deny(403)
priority: INT-MAX

In the following example, the policy allows IP 9.9.9.1 without scanning against XSS attacks:

Rule1
expr: inIPRange(origin.ip, '10.10.10.0/24')
action: deny(403)
priority: 1
Rule2
expr: inIPRange(origin.ip, '9.9.9.0/24')
action: allow
priority: 2
Rule3
expr: evaluatePreconfiguredExpr('xss-stable')
action: deny(403)
priority: 3
Rule-default
action: allow
priority: INT-MAX

Default rule

Each Google Cloud Armor security policy contains a default rule that is matched if none of the higher priority rules are matched or if there are no other rules in the policy. The default rule is automatically assigned a priority of 2147483647 (INT-MAX), and it is always present in the security policy.

You cannot delete the default rule, but you can modify it. The default action for the default rule is allow, but you can change the action to deny.

Fingerprint

Each Google Cloud Armor security policy has a field fingerprint. The fingerprint is a hash of the contents stored in the policy. When you create a new policy, do not provide the value of this field. If you provide a value, it is ignored. However, when you update a security policy, you must specify the current fingerprint, which you get when you export or describe the policy (using EXPORT or DESCRIBE, respectively).

The fingerprint protects you from overriding another user's update. If the fingerprint that you provide is out of date, it means that the security policy was updated since you last retrieved the fingerprint. To check for any differences and to retrieve the latest fingerprint, run the DESCRIBE command.

Rules language and enforcement engine

The rules language and enforcement engine provides the following:

  • The ability to write custom rule expressions that can match on various layer 3 through layer 7 attributes of incoming requests. Google Cloud Armor provides a flexible language for writing custom match conditions.

  • The ability to combine multiple subexpressions in a single rule.

  • The ability to deny or allow requests based on the incoming request's region code. The region codes are based on the ISO 3166-1 alpha 2 codes. The region codes sometimes correspond to specific countries, but some encompass a country plus its associated areas. For example, the US code includes all states of the United States, one district, and six outlying areas.

Types of rules

IP address allowlist and denylist rules

You can create IP address allowlist and denylist rules within a security policy. Some examples include the following:

  • Denylisting for IP address/CIDR enables you to block a source IP address or CIDR range from accessing external HTTP(S) load balancers.

  • Allowlisting for IP address/CIDR enables you to allow a source IP address or CIDR range to access external HTTP(S) load balancers.

  • IPv4 and IPv6 addresses are supported in allowlist and denylist rules.

  • IP address rules can block or allow individual source IP addresses or CIDRs. Both IPv4 and IPv6 source addresses are supported, but IPv6 addresses must have subnet masks no larger than /64.

  • Deny rules can return an HTTP 403 (Unauthorized), 404 (Access Denied), or 502 (Bad Gateway) response.

Preconfigured rules for XSS, SQLi, LFI, RFI, and RCE

You can use preconfigured rules to mitigate the following attacks:

  • Cross-site scripting (XSS)
  • SQL injection (SQLi) attacks
  • Local file inclusion (LFI) attacks
  • Remote file inclusion (RFI) attacks
  • Remote code execution (RCE) attacks

These rules are based on the OWASP Modsecurity core rule set version 3.0.2.

Preconfigured rules for named IP address lists

Preconfigured rules for named IP address lists provide the following:

  • Integrate third-party providers' named IP address lists with Google Cloud Armor.

  • Simplify maintenance of allowed or denied IP address ranges.

  • Synchronize third-party providers' lists daily.

  • Increase your capacity for configuring IP addresses and ranges in security policies because named IP address lists are not subject to limits on the number of IP addresses per rule.

Preview mode

You can preview the effects of a rule without enforcing it. In preview mode, actions are noted in Cloud Monitoring. You can choose to preview individual rules in a security policy, or you can preview every rule in the policy.

You can enable preview mode for a rule by using the gcloud command-line tool and the --preview flag of gcloud compute security-policies rules update.

To disable preview mode, use the --no-preview flag, which is not currently documented. You can also use the Cloud Console.

Logging

The Google Cloud Armor security policy name, matched rule priority, associated action, and related information are logged for HTTP(S) requests to your external HTTP(S) load balancer. To record Google Cloud Armor logging information, you must enable logging for HTTP(S) requests.

HTTP(S) Load Balancing request logging

Each HTTP(S) request is logged through Cloud Logging. The logs provide details such as the name of the applied security policy, the matching rule, and whether the rule was enforced. Request logging for new backend service resources is disabled by default. To ensure that Google Cloud Armor requests are logged, you must enable HTTP(S) logging.

For more information, see Logging for IP denylist/allowlist.

To view Google Cloud Armor logs, see Viewing logs.

Google Cloud Armor with Google Kubernetes Engine (GKE) Ingress

Once you have configured a Google Cloud Armor security policy, you can enable it through Kubernetes Ingress.

You can reference your security policy with a BackendConfig resource by adding the name of your security policy to the BackendConfig. The following BackendConfig manifest specifies a security policy named example-security-policy:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backendconfig
spec:
  securityPolicy:
    name: "example-security-policy"

For more information about Ingress features, see Configuring Ingress features.

Limitations

  • An IP address denylist/allowlist for HTTP(S) Load Balancing is not supported for Cloud Storage backend buckets.

  • Security policies are enforced for CDN cache misses only. Content is served from cache even if a rule in a security policy would have denied the request.

How WebSocket connections are handled

External HTTP(S) Load Balancing has built-in support for the WebSocket protocol. WebSocket channels are initiated from HTTP(S) requests. Google Cloud Armor can block a WebSocket channel from being established, for example, if an IP address denylist blocks the originating IP address. However, subsequent transactions in the channel do not conform to the HTTP protocol, and Google Cloud Armor does not evaluate any messages after the first request.

What's next