Use Google Cloud Armor security policies to protect your load-balanced services. Google Cloud Armor security policies are made up of rules that filter traffic based on layer 3, 4, and 7 attributes. For example, you can specify conditions that match on an incoming request's IP address, IP range, country 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 HTTP, HTTPS, HTTP/2, and QUIC protocols are all supported. For information about configuring Google Cloud Armor on Google Kubernetes Engine, see Configuring Google Cloud Armor.
Edge security with Google Cloud Armor security policies
Google Cloud HTTP(S) Load Balancing is implemented at the edge of Google's network in Google's points of presence around the world. In Premium Tier, user traffic directed to an external HTTP(S) load balancer enters the POP closest to the user and is then load balanced over Google's global network to the closest backend that has sufficient capacity available. In Standard Tier, user traffic enters 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 features
Google Cloud Armor security policies have the following features.
Security policies for HTTP(S) Load Balancing
- Ability to associate a Google Cloud Armor security policy with one or more HTTP(S) Load Balancing backend services.
- Designate the priority (evaluation order) when multiple rules are configured.
- Deny rules can be configured to display a 403, 404, or 502 error code.
IP address allow list and deny list rules in a Google Cloud Armor security policy
- Deny listing for IP address / CIDR provides the ability to block a source IP address or CIDR range from accessing external HTTP(S) load balancers.
- Allow listing for IP address / CIDR provides the ability to allow a source IP address or CIDR range to access external HTTP(S) load balancers.
- IPv4 and IPv6 addresses are supported in allow list and deny list rules.
Rules language and enforcement engine
- 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.
- Ability to combine multiple sub-expressions in a single rule.
- 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.
Pre-configured rules for XSS and SQLi
- Mitigate cross-site scripting (XSS) and SQL injection (SQLi) attacks by using pre-configured rules.
- XSS and SQLi rules are based on the OWASP Modsecurity core rule set version 3.0.1.
- Ability to preview the effects of the rules in a security policy in stackdriver logs without enforcing the actions in the rules.
- Enable preview mode on a per-rule level.
- 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.
About Google Cloud Armor security policies
Google Cloud Armor security policies are sets of rules you define to enforce application layer firewall rules protecting 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 allow list and deny list rules). Alternatively, by using the Google Cloud Armor custom rules language, 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.
When a condition is met, the action is either to allow or deny traffic. By default, this action is enforced, but a preview option is available. When you set the preview option to true, the previewed action is logged but not enforced.
You can associate a Google Cloud Armor security policy with one or more backend services. A backend service can have only one Google Cloud Armor security policy associated with it.
A Google Cloud Armor security policy can't be deleted if it is associated with any backend service. A backend service can be deleted regardless of whether it has an associated Google Cloud Armor security policy.
If multiple forwarding rules point to a backend service that has an associated Google Cloud Armor security policy, the policy rules are enforced for all traffic coming in to each of these forwarding rule IP addresses.
In the illustration below, the Google Cloud Armor security policy
internal-users-policy is associated with the backend service
Rule evaluation order
Rule evaluation order is determined by two factors: the rule priority and the rule type.
You assign a priority to rules, from the lowest to 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 (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 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 without any impact on existing rules.
Typically, the highest priority rule that matches the request is applied. However, for each HTTP request, Google Cloud Armor receives the request's header before the request's body (payload).
Because Google Cloud Armor receives the header information first, it evaluates rules that match against the header before receiving the request body. If there are multiple header-based rules, Google Cloud Armor evaluates them based on their priority.
After Google Cloud Armor receives the request's body, it evaluate rules that apply to the request body and rules that apply to both the request header and body. As a result, it's possible that lower priority rules that check a request's header are applied before higher priority rules that check the request's body. Only the first 8 KB of a POST body is inspected.
evaluatePreconfiguredExpr() expression for pre-configured rules is the
only expression that is evaluated against the request body. All other
expressions are evaluated against the request header.
In the following example, rules 1, 2, and 3 are evaluated in that order for the IP and HTTP header fields. But, if an XSS attack is being carried out in the HTTP data field only the HTTP data is blocked; the HTTP header passes through to the backend. In the example, traffic from 184.108.40.206/24 is still scanned against XSS attacks.
Rule1 expr: inIPRange(origin.ip, '220.127.116.11/24') action: deny(403) priority: 1 Rule2 expr: evaluatePreconfiguredExpr('xss-stable') action: deny(403) priority: 2 Rule3 expr: inIPRange(origin.ip, '18.104.22.168/16') action: allow priority: 3 Rule-default action: deny(403) priority: INT-MAX
In the following example, the policy allows 22.214.171.124/24 without scanning against XSS attacks:
Rule1 expr: inIPRange(origin.ip, '126.96.36.199/24') action: deny(403) priority: 1 Rule2 expr: inIPRange(origin.ip, '188.8.131.52/24') action: allow priority: 2 Rule3 expr: evaluatePreconfiguredExpr('xss-stable') action: deny(403) priority: 3 Rule-default action: allow priority: INT-MAX
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 (max int32) and it is always present in the Google Cloud Armor security policy. You cannot delete the default rule, but you can modify it. The default action for the default rule is deny, but you can change the action to allow.
Each Google Cloud Armor security policy has a field
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 Google Cloud Armor security
policy, you must specify the current fingerprint, which you get when you export
or describe the policy.
The fingerprint protects you from overriding another user's update. If the fingerprint that you provide is out of date, it means the Google Cloud Armor security policy was updated since you last retrieved the fingerprint. Describe the Google Cloud Armor security policy to check for any differences and to retrieve the latest fingerprint.
This section presents several common use cases for Google Cloud Armor security policies.
Use case 1: Limiting access to the GCP external HTTP(S) load balancer
A typical use case for placing user IP addresses on an allow list is when your external load balancer is used only by a specific set of users. In the following example, only users from your organization are allowed access to services behind your load balancer. These users have IP addresses or address blocks assigned by your organization. You can place these IP addresses or CIDR ranges on an allow list so that only these users have access to the load balancer.
You control access to the external HTTP(S) load balancer by configuring an allow list with source IP addresses or source CIDR ranges from which access to your load balancer is permitted. The following section further describes this configuration.
In this configuration, you only want to allow users from your organization with IP addresses from 203.0.113.0/24 to access the external HTTP(S) load balancer. You want all other traffic to be denied.
To create this configuration, follow these steps:
- Create a Google Cloud Armor security policy.
- In the Google Cloud Armor security policy, add a rule that allow lists 203.0.113.0/24 as the first rule. This rule has the description "allow 203.0.113.0/24".
- Modify the default rule in the policy from an
allowrule to a
denyrule. The default rule governs traffic that does not match any of the preceding rules. It is the last rule in the policy. Changing the rule from
denyblocks all traffic that does not originate in the range 203.0.113.0/24, which is on an allow list.
- Associate this policy with the external HTTP(S) load balancer's backend service.
Use case 2: Block unauthorized or malicious traffic at the edge with deny lists
Use deny lists to create Google Cloud Armor security policies that reject
traffic from an IP address or CIDR range. In the following illustration, the
Google Cloud Armor security policy has a
deny rule that blocks traffic
from the IP address 198.51.100.1, where a malicious user has been identified.
Use case 3: Allow traffic to the HTTPS load balancer only from a third-party security provider and other authorized users that are on an allow list
If your organization uses a third-party security provider to scrub traffic, you can allow list the security provider's IP address to ensure that only scrubbed traffic can access the load balancer and backends.
In the illustration below, the third-party provider is identified by the CIDR range 192.0.2.0/24, and this range is on an allow list.
Use case 4: Customize defenses with custom rules that match on layer 3 through layer 7 parameters
Use the Google Cloud Armor custom rules language to define one or more expressions in a rule's match condition. When Google Cloud Armor receives a request, it evaluates the request against these expressions. If there is a match, the rule's action takes effect, either denying or allowing the incoming traffic.
The following examples are expressions that are written in the Google Cloud Armor extension of the Common Expression Language (CEL). For more information, see the Google Cloud Armor custom rules language reference.
To define expressions in a rule, use the gcloud
--expression flag or console.
For more information, see Creating Google Cloud Armor security policy and
In the following example, requests from
184.108.40.206/24 (such as your alpha
testers) in the
AU region match the following expression:
origin.region_code == "AU" && inIpRange(origin.ip, '220.127.116.11/24')
The following example matches with requests from
18.104.22.168 and with a user
agent that contains the string
inIpRange(origin.ip, '22.214.171.124/32') && request.headers['user-agent'].contains('WordPress')
Use case 5: Mitigate application layer attacks by using pre-configured rules
Use pre-configured rules to detect and block common application layer attacks,
such as XSS and SQLi. Pre-configured rules are predefined expression sets that
you can add to a Google Cloud Armor security policy. To add these
expression sets to a rule, use the gcloud
--expression flag or console. For
more information, see Creating Google Cloud Armor security policy and
For more information about pre-configured rules, see Pre-configured rules in the rules language reference.
The following example uses a pre-configured rule to mitigate cross site scripting (XSS) attacks:
The following example uses a pre-configured rule to mitigate SQL injection (SQLi) attacks:
You can also combine pre-configured rules with other expressions. The following
example uses a pre-configured rule to mitigate SQLi attacks from the
126.96.36.199/24 IP address range:
inIpRange(origin.ip, '188.8.131.52/24') && evaluatePreconfiguredExpr('sqli-stable')
HTTP(S) Load Balancing request logging
Each HTTP(S) request is logged through Stackdriver Logging. The logs provide details such as the name of the applied security policy, the matching rule, and whether the rule was enforced. For more information, see Logging in the HTTP(S) Load Balancing documentation.
To view Google Cloud Armor logs, see Viewing logs.
Google Cloud Armor security policies for HTTP(S) Load Balancing and GCP firewall rules
Google Cloud Armor security policies and GCP firewall rules have complementary functions.
- Google Cloud Armor security policies provide edge security and act on client traffic.
- Distributed firewalls on load balanced instances provide VPC-related controls and act on the proxied traffic from the load balancer.
For instance, consider a scenario in which you want to allow traffic only from corporate users in California, with the CIDR range 184.108.40.206/24, and London, with the CIDR range 220.127.116.11/24, to access your external HTTP(S) load balancer. Your goal is to ensure that traffic cannot directly reach the backend load balanced instances; in other words, only external traffic proxied through the HTTP(S) load balancer with an associated security policy should reach the instances.
In the above illustration, you accomplish your security objectives by configuring your GCP deployment as follows:
- Deploy backend application instances in the us-west and europe regions.
- Deploy an external HTTP(S) load balancer as the front end to the instance, using 18.104.22.168 as the forwarding rule.
- Configure an Google Cloud Armor security policy that allows traffic from 22.214.171.124/24 and 126.96.36.199/24 and denies all other traffic.
- Associate this policy with the external HTTP(S) load balancer, or, more specifically, with the backend services. For more information, see Configuring Security Policies for HTTP(S) Load Balancing.
- Configure the distributed firewall rules for the instances to accept traffic only from the external HTTP(S) load balancer. HTTP(S) Load Balancing is a proxy- based solution where the source IP address of the traffic changes to an internal IP address range, so you can set a firewall rule for your instances that permits only this internal range.
Google Cloud Armor security policies for HTTP(S) Load Balancing and Identity-Aware Proxy
Cloud Identity-Aware Proxy (IAP) verifies a user's identity and then determines whether that user should be permitted to access an application. To enable IAP for the external HTTP(S) load balancer, you enable it on the load balancer's backend services. Similarly, edge Google Cloud Armor security policies are attached to the backend services of an external HTTP(S) load balancer.
If edge Google Cloud Armor security policies and IAP are both enabled for a backend service of an external HTTP(S) load balancer, the Google Cloud Armor security policy evaluation result and the IAP result are used together to determine whether the traffic should be allowed or denied at the edge. Traffic is blocked when either an edge Google Cloud Armor security policy or IAP results in a deny decision. The IAP evaluation happens first, meaning IAP serves a sign in page to the user even if their request is ultimately dropped as a result of a blocking Cloud Armor rule.
These features are configured independently. You can read more about IAP and related configurations in Cloud Identity-Aware Proxy.
- Google Cloud Armor security policies and IP deny list/allow list are not supported for Cloud CDN. If you try to associate a Google Cloud Armor security policy for a backend service and Cloud CDN is enabled, the config is rejected. Similarly, if you attempt to enable Cloud CDN for a backend service that has an associated Google Cloud Armor security policy, the configuration process fails.
- IP deny list/allow list for HTTP(S) Load Balancing is not supported for Cloud Storage backends.
- Google Cloud Armor is not supported with Internal HTTP(S) Load Balancing.