

# Managing your own rule groups in AWS Network Firewall
<a name="rule-groups"></a>

A Network Firewall *rule group* is a reusable set of criteria for inspecting and handling network traffic. You add one or more rule groups to a firewall policy as part of policy configuration. For more information about firewall policies and firewalls, see [Firewall policies](firewall-policies.md) and [Firewalls and firewall endpoints](firewalls.md).

You can use your own rule groups and you can use rule groups that are managed for you by AWS. For information on managed rule groups, see [Using managed rule groups](nwfw-managed-rule-groups.md).

Network Firewall rule groups are either *stateless* or *stateful*. These rule groups determine how packets are evaluated in your network traffic inspection.

------
#### [ Stateless rule groups ]

Stateless rule groups evaluate packets in isolation. They define standard network connection attributes for examining a packet on its own, without additional context from the broader traffic flow.

------
#### [ Stateful rule groups ]

Stateful rule groups evaluate packets in the context of traffic flow. They define criteria for examining a packet within the context of its traffic flow and other related traffic.

Network Firewall uses a Suricata rules engine to process all stateful rules. You can write any of your stateful rules in Suricata compatible format. Alternatively, for domain list rules and for very basic rules, you can use an easy entry form provided by Network Firewall.

Stateful rule groups are available in the following categories:
+ **Standard stateful rules** – Defines standard network connection attributes for examining a packet within the context of a traffic flow. For more information, see [Standard stateful rule groups in AWS Network Firewall](stateful-rule-groups-basic.md)
+ **Domain list** – Defines a list of domain names and specifies the protocol type to inspect. You can create these rules from an traffic analysis report. For more information, see [Creating stateful rule groups from reports](reporting.md#creating-stateful-rule-groups-from-reports).
+ **Suricata compatible rule strings** – Provides match and action settings, in Suricata compatible format. You can provide all of your stateful rules through this method if you want to. For more information, see [Suricata compatible rule strings in AWS Network Firewall](stateful-rule-groups-suricata.md).

------

Depending on the type of rule group, you might also define rules inside the rule group. Rules provide detailed criteria for packet inspection and specify what to do when a packet matches the criteria. When Network Firewall finds a match between the criteria and a packet, we say that the packet matches the rule group.

Follow the guidance in this section to manage your AWS Network Firewall rule groups. 

**Note**  
This section and others that describe Suricata-based concepts are not intended to replace or duplicate information from the Suricata documentation. For more Suricata-specific information, see the [Suricata documentation](https://docs.suricata.io/en/suricata-7.0.8/).

**Topics**
+ [

# Common rule group settings in AWS Network Firewall
](rule-group-settings.md)
+ [

# Options for stateful rules in Network Firewall
](stateful-rule-group-options.md)
+ [

# Working with stateful rule groups in AWS Network Firewall
](stateful-rule-groups-ips.md)
+ [

# Working with stateless rule groups in AWS Network Firewall
](stateless-rule-groups-standard.md)
+ [

# Defining rule actions in AWS Network Firewall
](rule-action.md)
+ [

# Setting rule group capacity in AWS Network Firewall
](nwfw-rule-group-capacity.md)

# Common rule group settings in AWS Network Firewall
<a name="rule-group-settings"></a>

Every Network Firewall rule group has the following top-level settings:
+ **Type** – Whether the rule group is stateless or stateful. 
+ **Name** – Identifier for the rule group. You assign a unique name to every rule group. You can't change the name of a rule group after you create it.
+ **Description** – Optional additional information about the rule group. Fill in any information that might help you remember the purpose of the rule group and how you want to use it. The description is included in rule group lists in the console and through the APIs.
+ **Capacity** – Limit on the processing requirements for the rule group. You can't change this setting after you create the rule group. For more information, including how to estimate your required capacity for a rule group, see [Setting rule group capacity in AWS Network Firewall](nwfw-rule-group-capacity.md). 
+ **Rules** – Set of packet inspection criteria used in the rule group. Rules in a rule group are either stateless or stateful, depending on the rule group type. 
+ **Encryption options** (Optional) – Network Firewall encrypts and decrypts Network Firewall resources, to protect against unauthorized access. By default, Network Firewall uses AWS owned keys for this. If you want to use your own keys, you can configure customer managed keys from AWS Key Management Service and provide them to Network Firewall. For information about this option, see [Encryption at rest with AWS Key Management Service](kms-encryption-at-rest.md).
+ **Tags** – Zero or more key-value tag pairs. A tag is a label that you assign to an AWS resource. You can use tags to search and filter your resources and to track your AWS costs. For more information, see [Tagging AWS Network Firewall resources](tagging.md).

# Options for stateful rules in Network Firewall
<a name="stateful-rule-group-options"></a>

A stateful rule group is a rule group that uses Suricata compatible intrusion prevention system (IPS) specifications. Suricata is an open source network IPS that includes a standard rule-based language for stateful network traffic inspection. 

When you create a Network Firewall stateful rule group from Suricata compatible rules, you can provide the rules to the rule group creation operation in one of the following ways: 
+ **Standard, simple rule group specification** – With this option, Network Firewall translates your specification into Suricata compatible rules and then passes the resulting rule strings to Suricata for processing.
+ **Domain list rule specification** – With this option, Network Firewall translates your rule specification into Suricata compatible rules and then passes the resulting rule strings to Suricata for processing.
+ **Rule strings that are written in Suricata compatible syntax** – When you use this option, Network Firewall passes your rule strings to Suricata for processing.

The sections that follow provide details for each of these options.

**Topics**
+ [

# Standard stateful rule groups in AWS Network Firewall
](stateful-rule-groups-basic.md)
+ [

# Suricata compatible rule strings in AWS Network Firewall
](stateful-rule-groups-suricata.md)
+ [

# Stateful domain list rule groups in AWS Network Firewall
](stateful-rule-groups-domain-names.md)
+ [

# IP set references in Suricata compatible AWS Network Firewall rule groups
](rule-groups-ip-set-references.md)
+ [

# Geographic IP filtering in Suricata compatible AWS Network Firewall rule groups
](rule-groups-geo-ip-filtering.md)
+ [

# URL and Domain Category Filtering in Suricata compatible AWS Network Firewall rule groups
](rule-groups-url-filtering.md)

# Standard stateful rule groups in AWS Network Firewall
<a name="stateful-rule-groups-basic"></a>

AWS Network Firewall supports easy entry for standard stateful rules for network traffic inspection. The match criteria for this stateful rule type is similar to the Network Firewall stateless rule. 

All rule groups have the common settings that are defined at [Common rule group settings in AWS Network Firewall](rule-group-settings.md).

**General settings**  
A stateful basic rule has the following general settings. 
+ **Action** – Defines how Network Firewall handles a packet that matches the rule match settings. Valid values are pass, drop, reject, and alert. For more information about actions, see [Defining rule actions in AWS Network Firewall](rule-action.md).

**Match settings**  
A basic stateful rule has the following match settings. These specify what the Network Firewall stateful rules engine looks for in a packet. To be a match, a packet must satisfy all of the match settings in the rule. 
+ **Protocol** – Transport protocol. Choose the protocol that you want to inspect. For all protocols, you can use `IP`, because all traffic on AWS and on the internet is IP.
+ **Source IP** – Source IP addresses and ranges. If specified, a packet must come from a source address that's included in this list in order to match.
+ **Source port** – Source ports and port ranges. If specified, a packet must have a source port that's included in this list in order to match.
+ **Destination IP** – Destination IP addresses and ranges. If specified, a packet must have a destination address that's included in this list in order to match.
+ **Destination port** – Destination ports and port ranges. If specified, a packet must have a destination port that's included in this list in order to match.
+ **Traffic direction** – Direction of traffic flow. Valid settings are `Any` and `Forward`. `Forward` matches packets whose origination matches the rule's source settings and whose destination matches the rule's destination settings. `Any` matches the forward match, and also matches packets whose origination matches the rule's destination settings, and whose destination matches the rule's source settings.
+ **Rule options** – Define the specifics of the rule, in keyword, settings pairs. 
**Note**  
The console doesn't currently allow entry of rule options. Rule options are usually required for complete specification of this rule type. If you need to specify rule options, use one of the APIs or AWS CloudFormation. For information, see [StatefulRule](https://docs.aws.amazon.com/network-firewall/latest/APIReference/API_StatefulRule.html) in the *AWS Network Firewall API Reference* and [AWS::NetworkFirewall::RuleGroup StatefulRule](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statefulrule.html) in the *AWS CloudFormation User Guide*.

For an example rule specification and the Suricata compatible rule that Network Firewall generates from it, see [Stateful rules examples: standard stateful rule groups](suricata-examples.md#suricata-example-basic).

# Suricata compatible rule strings in AWS Network Firewall
<a name="stateful-rule-groups-suricata"></a>

When you use this rule group type, you provide match and action settings in a string, in a Suricata compatible specification. Your specification fully defines what the stateful rules engine looks for in a traffic flow and the action to take on the packets in a flow that matches the inspection criteria. 

All rule groups have the common settings that are defined at [Common rule group settings in AWS Network Firewall](rule-group-settings.md).

You can provide your Suricata compatible specification to Network Firewall in rules strings or files, depending on how you're accessing Network Firewall. 
+ **Console** – In the AWS Management Console, provide the rules string in the text box that appears for the stateful rule group option **Import Suricata compatible rules**. For information about using the console to manage your rule group, see [Creating a stateful rule group](rule-group-stateful-creating.md).
+ **API** – Through the API, you can provide either the rules or the name of the file that contains the rules. In a file, Suricata compatible rules are usually written one rule per line.

  You provide either the file or the rules string in the `RulesString` field within the `RuleGroup` structure when you create or update the rule group. For information, see [CreateRuleGroup](https://docs.aws.amazon.com/network-firewall/latest/APIReference/API_CreateRuleGroup.html) in the *AWS Network Firewall API Reference*. 
+ **CLI** – Through the CLI, you can provide the rules, the name of a file that contains the rules, or the name of a file that contains the rule group structure in JSON format, with the rules defined in that. 

  The following listing shows the syntax for providing the rules in a file. To use a command like this, substitute in your new rule group name, its calculated capacity, and the JSON rules file name. 

  ```
  aws network-firewall create-rule-group --rule-group-name <ruleGroupName> --capacity <capacityCalculation> --type STATEFUL --rules <rules file name>
  ```

# Stateful domain list rule groups in AWS Network Firewall
<a name="stateful-rule-groups-domain-names"></a>

AWS Network Firewall supports domain name stateful network traffic inspection. You can create allow lists and deny lists with domain names that the stateful rules engine looks for in network traffic. 

All rule groups have the common settings that are defined at [Common rule group settings in AWS Network Firewall](rule-group-settings.md).

## General settings
<a name="stateful-rule-groups-domain-names-general-settings"></a>

A domain list rule group has the following general settings.
+ **Action** – Defines how Network Firewall handles traffic that matches the rule match settings. Valid values for domain rules are `Allow` `Deny`, `Reject`, and `Alert`:
  + For `Allow`, traffic of the specified protocol type that does not match the domain specifications is denied.
  + For `Deny`, traffic matching the domain specifications is blocked. Non-matching traffic is allowed to pass.
  + For `Reject`, traffic matching the domain specifications is blocked and a TCP reset packet is sent back to the source. This option is only available for TCP traffic.
  + For `Alert`, traffic matching the domain specifications generates an alert in the firewall's logs (when logging is enabled). Then, traffic either passes, is rejected, or drops based based on other rules in the firewall policy.
**For firewall policies that use default action ordering**  
We recommend that you avoid combining `Reject` or `Alert` domain list rule groups with `Allow` domain list rule groups. When this combination of rule groups is defined in a firewall policy that uses default action ordering, the default drop rule added by the `Allow` rule group will take effect before the `Reject` and `Alert` rules.

  For more information about actions, see [Defining rule actions in AWS Network Firewall](rule-action.md).
+ **(Optional) `HOME_NET` rule group variable** – Used to expand the local network definition beyond the CIDR range of the VPC where you deploy Network Firewall. For additional information about this setting, see [Domain list inspection for traffic from outside the deployment VPC](#stateful-rule-groups-domain-names-home-net).

  See the caveats for the `HOME_NET` and `EXTERNAL_NET` settings at [Suricata features that Network Firewall supports with caveatsSupported with caveats](suricata-limitations-caveats.md#suricata-supported-with-caveats).
**Note**  
The console doesn't currently allow entry of all rule group variables. To specify other rule group variables, use one of the APIs or AWS CloudFormation. For information, see [StatefulRule](https://docs.aws.amazon.com/network-firewall/latest/APIReference/API_StatefulRule.html) in the *AWS Network Firewall API Reference* and [AWS::NetworkFirewall::RuleGroup StatefulRule](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statefulrule.html) in the *AWS CloudFormation User Guide*.

## Match settings
<a name="stateful-rule-groups-domain-names-match-settings"></a>

A domain list rule group has the following match settings. These specify what the Network Firewall stateful rules engine looks for in a packet. A packet must satisfy all match settings to be a match. 
+ **Domain list** – List of strings specifying the domain names that you want to match. A packet must match one of the domain specifications in the list to be a match for the rule group. Valid domain name specifications are the following: 
  + Explicit names. For example, `abc.example.com` matches only the domain `abc.example.com`.
  + Names that use a domain wildcard, which you indicate with an initial '`.`'. For example,`.example.com` matches `example.com` and matches all subdomains of `example.com`, such as `abc.example.com` and `www.example.com`. 
+ **Protocols** – You can inspect HTTP or HTTPS protocols, or both. 

For HTTPS traffic, Network Firewall uses the Server Name Indication (SNI) extension in the TLS handshake to determine the hostname, or domain name, that the client is trying to connect to. For HTTP traffic, Network Firewall uses the HTTP host header to get the name. In both cases, Network Firewall doesn't pause connections to do out-of-band DNS lookups. It uses the SNI or host header, not the IP addresses, when evaluating domain list rule groups. If you want to inspect IP addresses, to mitigate situations where the SNI or host headers have been manipulated, write separate rules for that and use them in conjunction with or in place of your domain list rules. 

For examples of domain list specifications and the Suricata compatible rules that Network Firewall generates from them, see [Stateful rules examples: domain list rules](suricata-examples.md#suricata-example-domain-filtering).

## Domain list inspection for traffic from outside the deployment VPC
<a name="stateful-rule-groups-domain-names-home-net"></a>

To use domain name filtering for traffic from outside the VPC where you've deployed Network Firewall, you must manually set the `HOME_NET` variable for the rule group. The most common use case for this is a central firewall VPC with traffic coming from other VPCs through a transit gateway. 

By default, domain list inspection uses a `HOME_NET` that is set to the CIDR range of the VPC where Network Firewall is deployed. Only traffic from that range is passed through the domain list filtering. To filter traffic from outside the deployment VPC, you must provide a `HOME_NET` setting that includes the other CIDR ranges that you want to inspect, along with the CIDR range of the VPC where Network Firewall is deployed. 

For example, say that the VPC where you deploy Network Firewall has the CIDR range `192.0.2.0/24`. In addition to the traffic for that VPC, you want to filter traffic for two other VPCs that have CIDR ranges `10.0.0.0/16` and `10.1.0.0/16`. You're using a domain list rule group named `domains`. 

The following command line call retrieves the JSON listing for the rule group:

```
aws network-firewall describe-rule-group --type STATEFUL \
--rule-group-name domains --region us-west-2
```

The following shows the example JSON response. This rule group has only `RulesSource` defined, which contains the domain list inspection specifications. 

```
{
    "UpdateToken": "a4648a25-e315-4d17-8553-283c2eb33118",
    "RuleGroup": {
        "RulesSource": {
            "RulesSourceList": {
                "Targets": [
                    ".example.com",
                    "www.example.org"
                ],
                "TargetTypes": [
                    "HTTP_HOST",
                    "TLS_SNI"
                ],
                "GeneratedRulesType": "DENYLIST"
            }
        }
    },
    "RuleGroupResponse": {
        "RuleGroupArn": "arn:aws:network-firewall:us-west-2:111122223333:stateful-rulegroup/domains",
        "RuleGroupName": "domains",
        "RuleGroupId": "f3333333-fb99-11c1-bbe3-1d1caf1d1111",
        "Type": "STATEFUL",
        "Capacity": 100,
        "RuleGroupStatus": "ACTIVE",
        "Tags": []
    }
}
```

Variable settings are defined for a rule group in a `RuleVariables` setting. This rule group currently has no `HOME_NET` variable declaration, so we know that `HOME_NET` is set to the default. In our example case, it's `192.0.2.0/24`. 

To add CIDR ranges to the `HOME_NET` setting, we update the rule group with our variable declaration. The following shows a file named `variables.json` that contains the rule group JSON with the added variables settings:

```
{
    "RuleVariables": {
        "IPSets": {
           "HOME_NET": {
             "Definition": [
               "10.0.0.0/16",
               "10.1.0.0/16",
               "192.0.2.0/24"
             ]
           }
        }
    },
    "RulesSource": {
        "RulesSourceList": {
           "Targets": [
               ".example.com",
               "www.example.org"
           ],
           "TargetTypes": [
               "HTTP_HOST",
               "TLS_SNI"
           ],
           "GeneratedRulesType": "DENYLIST"
        }
    }
}
```

The following command uses the `variables.json` file to update the rule group definition with the correct `HOME_NET` settings:

```
aws network-firewall update-rule-group \
--rule-group-arn arn:aws:network-firewall:us-west-2:111122223333:stateful-rulegroup/domains \
--update-token a4648a25-e315-4d17-8553-283c2eb33118 \
--rule-group file://variables.json \
--region us-west-2
```

The following shows an example response to the call: 

```
{
    "UpdateToken": "32ebfb82-40a2-4896-b34d-91dada978f67",
    "RuleGroupResponse": {
        "RuleGroupArn": "arn:aws:network-firewall:us-west-2:111122223333:stateful-rulegroup/domains",
        "RuleGroupName": "domains",
        "RuleGroupId": "f3333333-fb99-11c1-bbe3-1d1caf1d1111",
        "Type": "STATEFUL",
        "Capacity": 100,
        "RuleGroupStatus": "ACTIVE",
        "Tags": []
    }
}
```

If we retrieve the `domains` rule group again, we see that the rule group has the added variable definition:

```
aws network-firewall describe-rule-group --type STATEFUL \
--rule-group-name domains --region us-west-2
```

The response JSON contains the added variable: 

```
{
    "UpdateToken": "42ffac91-20b5-5512-a24c-85cbca797e23",
    "RuleGroup": {
        "RuleVariables": {
            "IPSets": {
                "HOME_NET": {
                    "Definition": [
                        "10.0.0.0/16",
                        "10.1.0.0/16",
                        "192.0.2.0/24"
                    ]
                }
            }
        },
        "RulesSource": {
            "RulesSourceList": {
                "Targets": [
                    ".example.com",
                    "www.example.org"
                ],
                "TargetTypes": [
                    "HTTP_HOST",
                    "TLS_SNI"
                ],
                "GeneratedRulesType": "DENYLIST"
            }
        }
    },
    "RuleGroupResponse": {
        "RuleGroupArn": "arn:aws:network-firewall:us-west-2:111122223333:stateful-rulegroup/domains",
        "RuleGroupName": "domains",
        "RuleGroupId": "f3333333-fb99-11c1-bbe3-1d1caf1d1111",
        "Type": "STATEFUL",
        "Capacity": 100,
        "RuleGroupStatus": "ACTIVE",
        "Tags": []
    }
}
```

# IP set references in Suricata compatible AWS Network Firewall rule groups
<a name="rule-groups-ip-set-references"></a>

You can use an IP set reference with **Suricata compatible rule strings** and with **standard Network Firewall stateful rule groups**.

An *IP set reference* is a Network Firewall rule group variable that references a set of IP addresses or CIDR blocks contained in an AWS resource, such as an Amazon Virtual Private Cloud prefix list. IP set references enable you to dynamically use IP addresses or CIDRs from another AWS service in your Suricata compatible rules. When you create, update, or delete the IP sets that you reference in your rules, Network Firewall automatically updates the rules with the changes. For example, if you add five CIDRs to an IP set resource that you're referencing in a rule, then the rule will automatically include the five CIDRs that you added to the resource.

Network Firewall currently supports the following AWS resources as IP set references:
+ **Amazon VPC prefix lists**. For information about referencing Amazon VPC prefix lists in your rule groups, see the following section [Referencing Amazon VPC prefix lists](#rule-groups-referencing-prefix-lists).
+ **Resource groups**. For information about referencing resource groups in your rule groups, see following section [Referencing resource groups](#rule-groups-referencing-resource-groups).

For an example of a rule that uses an IP set reference, see [Stateful rules examples: IP set reference](suricata-examples.md#suricata-example-rule-with-ip-set-reference).

For more information about adding IP sets to your Suricata compatible rule groups via the console, see the [Creating a stateful rule group](rule-group-stateful-creating.md) procedure.

## Limits for IP set references
<a name="rule-groups-ip-set-reference-limits"></a>

The following limits apply to IP set references:
+ Maximum of five IP set references per rule group. You can use IP set references in addition to IP set variables or port variables in a rule group. Only IP set references count against this limit.
+ Maximum of 1,000,000 CIDRs - You can use a maximum of 1,000,000 CIDRs in all of the IP set references used in a single firewall. If you exceed this limit, then Network Firewall includes only the first 1,000,000 CIDRs from your referenced IP set resources. Network Firewall calculates CIDRs differently for prefix lists and resource groups:
  + Prefix lists – Network Firewall takes an aggregated account of the CIDRs in each referenced IP set.
  + Resource groups – Network Firewall calculates the number of IP addresses associated with all of the resources in the group, such as all of the IP addresses associated with an Amazon EC2 instance, both public and private.

## Referencing Amazon VPC prefix lists
<a name="rule-groups-referencing-prefix-lists"></a>

A *prefix list* is a set of one or more CIDR block entries that you can use to configure security groups, routing tables, and transit gateways in Amazon VPC. A reference to a prefix list helps you to simplify the management of the CIDR blocks in your rules. If you frequently use the same CIDRs across multiple rules, you can manage those CIDRs in a single prefix list, instead of repeatedly referencing the same CIDRs in each rule. If you need to remove a CIDR block, you can remove its entry from the prefix list instead of removing the CIDR from every affected rule.

For more information about Amazon VPC prefix lists, see [Group CIDR blocks using managed prefix lists ](https://docs.aws.amazon.com/vpc/latest/userguide/managed-prefix-lists.html) in the *Amazon VPC User Guide*.

## Referencing resource groups
<a name="rule-groups-referencing-resource-groups"></a>

A *tag-based resource group* is a collection of AWS resources whose membership in a resource group is based on tags. Tags are key value metadata that you associated with a resource type, such as an Amazon EC2 instance. Similar to prefix lists, a reference to a resource group helps you to simplify the management of the IP addresses in your rules. If you frequently want to reference the IP addresses of the same set of resources, you can manage those IPs in a single resource group, instead of repeatedly referencing the same IPs in each rule. Network Firewall constantly checks for resources that match the resource group grouping criteria in your account, and then resolves IPs of the matching resources in the rule. If you need to remove a set of IP addresses, you can remove the tagged resource type from the resources group instead of removing the IP from every affected rule.

For more information about using resource groups in Network Firewall, see [Using tag-based resource groups in Network Firewall](resource-groups.md).

# Geographic IP filtering in Suricata compatible AWS Network Firewall rule groups
<a name="rule-groups-geo-ip-filtering"></a>

You can use Geographic IP filtering with **Suricata compatible rule strings** and with **standard Network Firewall stateful rule groups**. This optional filter matches country codes for the IP addresses of network traffic.

Suricata supports filtering for source and destination IPs. You can filter on either of these types by itself, by specifying `dst` or `src`. You can filter on the two types together with AND or OR logic, by specifying `both` or `any`. For more information see the Suricata `geoip` keyword documentation at [IP Keywords: geoip](https://docs.suricata.io/en/suricata-7.0.8/rules/header-keywords.html?highlight=geoip#geoip).

To use a Geographic IP filter, you provide the `geoip` keyword, the filter type, and the country codes for the countries that you want to filter for, for example `geoip:dst,CN,US;`. For additional examples, see [Stateful rules examples: Geographic IP filter](suricata-examples.md#suricata-example-rule-with-geo-ip-filter). 

For more information about adding Geographic IP filtering to your Suricata compatible rule groups via the console, see the [Creating a stateful rule group](rule-group-stateful-creating.md) procedure. 

**IPv4 and IPv6 support**  
The Network Firewall implementation of Suricata `geoip` provides support for IPv6 and IPv4. This is an expansion of the support provided by Suricata.

**MaxMind IP geolocation**  
Suricata determines the location of requests using MaxMind GeoIP databases. MaxMind reports very high accuracy of their data at the country level, although accuracy varies according to factors such as country and type of IP. For more information about MaxMind, see [MaxMind IP Geolocation](https://support.maxmind.com/hc/en-us/sections/4407519834267-IP-Geolocation). 

If you think any of the geographic IP data is incorrect, you can submit a correction request to Maxmind at [MaxMind Correct GeoIP Data](https://support.maxmind.com/hc/en-us/articles/4408252036123-GeoIP-Correction).

**Country codes**  
IP geolocation uses the alpha-2 country codes from the International Organization for Standardization (ISO) 3166 standard. 
+ You can search country codes at the ISO website, at [ISO Online Browsing Platform (OBP)](https://www.iso.org/obp/ui#home). 
+ You can also find them listed on Wikipedia, at [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2).

Network Firewall only allows you to save Geographic IP filter rules that have valid country codes. 

If you configure Geographic IP rules to allow or pass connections to IP addresses in specific countries, we recommend that you set the Default action on your firewall policy to one of our available Drop actions. Geographic IP country mappings are derived from the MaxMind database, and IP-to-country associations can change between database updates. By configuring a default drop action, you ensure that if an IP address is reassigned to a different country and no longer matches your allow rule or any other rules in your firewall policy, the firewall drops the connection. 

AWS Network Firewall uses the MaxMind GeoIP database to resolve IP addresses to their associated countries. While MaxMind provides industry-standard geolocation data, IP-to-country associations may be inaccurate or change over time due to IP address reassignments, database updates, or other factors. Before you create or troubleshoot Geographic IP rules, verify the country mapping of your target IP addresses by using the [MaxMind IP lookup tool](https://www.maxmind.com/en/geoip-demo). This helps you confirm that the IP addresses you expect to match a given country code are correctly classified in the database and can prevent unexpected rule behavior. However, the lookup tool reflects MaxMind's most current data - AWS Network Firewall's database is updated on a rolling basis, so there may be a brief window where mappings differ. If this is the case, refer to the Workarounds section below for options to override specific IPs. 

If you observe that an IP address is being incorrectly allowed by a Geographic IP rule due to a country mapping change or database inaccuracy, you can create an explicit deny or reject rule in your rule group that targets the specific IP address. You would need to place this rule with a higher priority than the original rule for it to take precedence. Please see [Managing Evaluation order for Suricata compatible rules in AWS Network Firewall](https://docs.aws.amazon.com/network-firewall/latest/developerguide/suricata-rule-evaluation-order.html). 

# URL and Domain Category Filtering in Suricata compatible AWS Network Firewall rule groups
<a name="rule-groups-url-filtering"></a>

URL and Domain Category filtering enables you to filter network traffic based on predefined content categories. You can use this feature with **Suricata compatible rule strings** and **standard Network Firewall stateful rule groups**.

Network Firewall provides two filtering keywords: 
+ `aws_url_category` - Evaluates complete URLs and domains in HTTP/HTTPS traffic
+ `aws_domain_category` - Evaluates only domain information from TLS SNI or HTTP host headers

To use URL and Domain Category filtering, you provide either the `aws_url_category` or `aws_domain_category` keyword followed by the category you want to filter for, for example `aws_url_category:Malicious;` You can specify multiple categories per rule. For additional examples, see [Stateful rules examples: URL/Domain Category filter](suricata-examples.md#suricata-example-rule-with-url-filter). 

**How URL and Domain Category filtering works**  


**aws\$1url\$1category keyword**
+ Supported protocol in rules: HTTP
+ Traffic handling:
  + **For HTTP traffic** - Evaluates complete URLs
  + **For HTTPS traffic** - Requires TLS inspection to evaluate URLs. Without TLS inspection, HTTPS traffic is treated as encrypted TLS traffic and cannot be evaluated
+ Performs evaluation in the following order:
  + Complete URL path evaluation (up to 30 recursive path lookups)
  + If no match is found, falls back to domain-level evaluation (up to 10 recursive subdomain lookups)
+ Matches against:
  + URI field from HTTP request headers (requires TLS inspection for HTTPS traffic)
  + Host field from HTTP request headers

**aws\$1domain\$1category keyword**
+ Supported protocols in rules: TLS, HTTP
+ Traffic handling:
  + **For HTTP traffic** - Evaluates domain from Host field
  + **For TLS traffic** - Evaluates domain from SNI field
  + No TLS inspection required
+ Performs domain-level evaluation:
  + Evaluates only domain-level information (up to 10 recursive subdomain lookups)
+ Matches against:
  + Server Name Indication (SNI) field from TLS handshake
  + Host field from HTTP request headers

**Supported Categories**  


```
"Abortion",
"Adult and Mature Content",
"Artificial Intelligence and Machine Learning",
"Arts and Culture",
"Business and Economy",
"Career and Job Search",
"Child Abuse",
"Command and Control",
"Criminal and Illegal Activities",
"Cryptocurrency",
"Dating",
"Education",
"Email",
"Entertainment",
"Family and Parenting",
"Fashion",
"Financial Services",
"Food and Dining",
"For Kids",
"Gambling",
"Government and Legal",
"Hacking",
"Health",
"Hobbies and Interest",
"Home and Garden",
"Lifestyle",
"Malicious",
"Malware",
"Marijuana",
"Military",
"News",
"Online Ads",
"Parked Domains",
"Pets",
"Phishing",
"Private IP Address",
"Proxy Avoidance",
"Real Estate",
"Redirect",
"Religion",
"Search Engines and Portals",
"Science",
"Shopping",
"Social Networking",
"Spam",
"Sports and Recreation",
"Technology and Internet",
"Translation",
"Travel",
"Vehicles",
"Violence and Hate Speech"
```

**Considerations**  

+ [TLS inspection](https://docs.aws.amazon.com/network-firewall/latest/developerguide/tls-inspection-configurations.html) must be enabled on your firewall to perform URL category filtering on HTTPS traffic
+ Without TLS inspection, only domain-level filtering is possible for encrypted traffic
+ A single URL may map to multiple categories
+ Category database is automatically maintained and updated
+ You can specify multiple categories in a single rule
+ You cannot combine URL/Domain category filtering keywords (`aws_url_category, aws_domain_category`) with geographic IP filtering (`geoip`) in the same rule. You must create separate rules if you want to filter traffic using both geographic IP filter and URL /Domain Category filter.
+ Using URL/Domain category filtering may increase traffic latency due to the additional category lookups performed for each connection matching the rule protocol and IP specifications.

# Working with stateful rule groups in AWS Network Firewall
<a name="stateful-rule-groups-ips"></a>

A stateful rule group is a rule group that uses Suricata compatible intrusion prevention system (IPS) specifications. Suricata is an open source network IPS that includes a standard rule-based language for stateful network traffic inspection. 

Stateful rule groups have a configurable top-level setting called `StatefulRuleOptions`, which contains the `RuleOrder` attribute. You can set this in the console when you create a rule group, or in the API under `StatefulRuleOptions`. You can't change the `RuleOrder` after the rule group is created. 

You can enter any stateful rule in Suricata compatible strings. For standard Suricata rules specifications and for domain list inspection, you can alternately provide specifications to Network Firewall and have Network Firewall create the Suricata compatible strings for you. 

As needed, depending on the rules that you provide, the stateful engine performs deep packet inspection (DPI) of your traffic flows. DPI inspects and processes the payload data within your packets, rather than just the header information. 

The rest of this section provides requirements and additional information for using Suricata compatible rules with Network Firewall. 

**Note**  
This section and others that describe Suricata-based concepts are not intended to replace or duplicate information from the Suricata documentation. For more Suricata-specific information, see the [Suricata documentation](https://docs.suricata.io/en/suricata-7.0.8/).

**Previous Suricata major version upgrade**  
When Network Firewall upgrades to a new major version of Suricata, related changes are tracked here.

Network Firewall upgraded from Suricata version 6.0.9 to 7.0 in November of 2024. For full information about the upgrade from version 6.0.9, see [Upgrading 6.0 to 7.0](https://docs.suricata.io/en/latest/upgrade.html#upgrading-6-0-to-7-0). 

The following are examples of the changes in that upgrade: 
+ PCRE 1 rule format is no longer supported, and has been replaced with PCRE2.
+ When you specify a sticky buffer in a rule, it needs to be immediately followed by the payload keywords. For example, keywords such as `dns.query` and `tls.sni` must be followed by a content modifier. 
+ Keywords that use ranges, such as `itype` now require the range to be specified with the format `min:max`. 

**Topics**
+ [

# Creating a stateful rule group
](rule-group-stateful-creating.md)
+ [

# Updating a stateful rule group
](rule-group-stateful-updating.md)
+ [

# Deleting a stateful rule group
](rule-group-stateful-deleting.md)
+ [

# Managing evaluation order for Suricata compatible rules in AWS Network Firewall
](suricata-rule-evaluation-order.md)
+ [

# Limitations and caveats for stateful rules in AWS Network Firewall
](suricata-limitations-caveats.md)
+ [

# Best practices for writing Suricata compatible rules for AWS Network Firewall
](suricata-best-practices.md)
+ [

# Examples of stateful rules for Network Firewall
](suricata-examples.md)

# Creating a stateful rule group
<a name="rule-group-stateful-creating"></a>

This section provides guidance for creating a stateful rule group.

**To create a stateful rule group**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. Choose **Create Network Firewall rule group**. 

1. Under **Choose rule group type**, for the **Rule group format**, choose **Stateful rule group**. 

   For **Rule evaluation order**, choose the way that your stateful rules are ordered for evaluation: 
   + Choose **Strict order** (recommended) to provide your rules in the order that you want them to be evaluated. You can then choose one or more default actions for packets that don't match any rules.
   + Choose **Action order** to have the stateful rules engine determine the evaluation order of your rules. The default action for this rule order is **Pass**, followed by **Drop**, **Reject**, and **Alert** actions. This option was previously named **Default** order.

   For more information about stateful default actions for rule groups, see [Action orderAction order](suricata-rule-evaluation-order.md#suricata-default-rule-evaluation-order).

   For more information about stateful rule groups, see [Working with stateful rule groups in AWS Network Firewall](stateful-rule-groups-ips.md). 

1. Choose **Next**.

1. Enter a **Name** to identify this rule group. 
**Note**  
You can't change the name after you create the rule group.

1. (Optional) Enter a **Description** for the rule group to help you identify ot among your other resources.

1. For **Capacity**, set the maximum capacity you want to allow for the stateful rule group, up to the maximum of 50,000. You can't change this setting after you create the rule group. For information about how to calculate this, see [Setting rule group capacity in AWS Network Firewall](nwfw-rule-group-capacity.md). For information about the maximum setting, see [AWS Network Firewall quotas](quotas.md). 

1. Choose **Next**.

1. Select the type of rule group that you want to add, from the **Stateful rule group options**. The rest of your rule group specifications depend on the option you choose.
**Note**  
If you need to specify options that aren't available through the console, you can use one of the APIs or AWS CloudFormation. For information, see [StatefulRule](https://docs.aws.amazon.com/network-firewall/latest/APIReference/API_StatefulRule.html) in the *AWS Network Firewall API Reference* and [AWS::NetworkFirewall::RuleGroup StatefulRule](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statefulrule.html) in the *AWS CloudFormation User Guide*.
   + (Option) **Standard stateful rule** – Entry form for a basic Suricata rule.

     For each rule that you want in your rule group, specify the following information and then choose **Add rule**. Your added rules are listed in the **Rules** list. 
     + Choose the protocol and source and destination settings for your rule. 
     + For **Traffic direction**, choose whether to apply the rule to any direction or only for traffic that flows forward, from the specified source to the specified destination.
**Note**  
Network Firewall doesn't automatically add the direction keyword `to_server`, and will inspect all the packets in the flow, irrespective of the flow state.
     + For **Action**, select the action that you want Network Firewall to take when a packet matches the rule settings. For information on these options, see [Actions for stateful rules](rule-action.md#rule-action-stateful). 

     To define IP sets and ports as variables that you can reference in your rules: 
     + In the **Rule variables** section, enter variables and values for **IP set variables** and **Port variables**.

     To add one or more references to IP set resources, such as Amazon VPC prefix lists, that you can use as variables in your rules: 
     + In the **IP set reference** section, enter a **IP set variable name** and select an **IP set reference ID**. The **IP set reference ID** corresponds to the resource ID of the IP set Amazon Resource Name (ARN) that you want to reference. Network Firewall currently supports Amazon VPC prefix lists and resource groups as IP set references. For more information about working with IP set references in Network Firewall, see [Referencing Amazon VPC prefix lists](rule-groups-ip-set-references.md#rule-groups-referencing-prefix-lists).

     For enhanced filtering options, you can specify the following:

     **Geographic IP filtering - **To filter traffic based on country:
     + Choose to enable **Geographic IP filtering** 
     + Select the matching option:
       + Match only selected countries
       + Match all but selected countries
     + Choose the **Geographic IP traffic direction** (source, destination, or any)
     + Choose the **Country codes** from the dropdown list 
     + For more information, see [Geographic IP filtering in Suricata compatible AWS Network Firewall rule groups](rule-groups-geo-ip-filtering.md)

     **URL and Domain Category filtering - **To filter traffic based on web content categories:
     + Choose to enable **URL and Domain Category filtering**
     + Select the matching option:
       + Match all selected categories
       + Match all unselected categories
     + Choose the **AWS category type:**
       + aws\$1url\$1category (for HTTP protocol, requires TLS inspection for HTTPS)
       + aws\$1domain\$1category (for TLS and HTTP protocols)
     + Choose the **categories** from the dropdown list 
     + For more information, see [URL and Domain Category Filtering in Suricata compatible AWS Network Firewall rule groups](rule-groups-url-filtering.md)

     For information about these rules, see [Standard stateful rule groups in AWS Network Firewall](stateful-rule-groups-basic.md).
   + (Option) **Domain list** – Specify the following information. 
**Note**  
You can create domain list rules from traffic analysis reports. For information, see [Creating stateful rule groups from reports](reporting.md#creating-stateful-rule-groups-from-reports). 
     + For **Domain name source**, enter the domain names that you want to inspect for, one name specification per line. Valid domain name specifications are the following: 
       + Explicit names. For example, `abc.example.com` matches only the domain `abc.example.com`.
       + Names that use a domain wildcard, which you indicate with an initial '`.`'. For example,`.example.com` matches `example.com` and matches all subdomains of `example.com`, such as `abc.example.com` and `www.example.com`. 
     + For **CIDR ranges**, choose whether to inspect default or custom ranges.
     + For **Protocols**, choose the protocols you want to inspect. 
     + For **Action**, select the list type that you are creating, either **Allow** or **Deny**. For information on these options, see [Actions for stateful rules](rule-action.md#rule-action-stateful). 

     For information about stateful domain name rules, see [Stateful domain list rule groups in AWS Network Firewall](stateful-rule-groups-domain-names.md).
   + (Option) **Suricata compatible rule string**

     To define IP sets and ports as variables that you can reference in your rules: 
     + In the **Rule variables** section, enter variables and values for **IP set variables** and **Port variables**.

     To add one or more references to IP set resources, such as Amazon VPC prefix lists, that you can use as variables in your rules: 
     + In the **IP set reference** section, enter a **IP set variable name** and select an **IP set reference ID**. The **IP set reference ID** corresponds to the resource ID of the IP set Amazon Resource Name (ARN) that you want to reference. Network Firewall currently supports Amazon VPC prefix lists and resource groups as IP set references. For more information about working with IP set references in Network Firewall, see [Referencing Amazon VPC prefix lists](rule-groups-ip-set-references.md#rule-groups-referencing-prefix-lists).

     Paste your rules into the text box.

1. Choose **Next**.

1. (Optional) On the **Configure advanced settings** page, under **Customer managed key**, toggle the **Customize encryption settings** option to configure your customer managed key. For more information about this option, see [Encryption at rest with AWS Key Management Service](kms-encryption-at-rest.md).

1. Choose **Next**.

1. (Optional) On the **Add tags** page, enter a key and optional value for any tag that you want added to this firewall policy. Tags help you organize and manage your AWS resources. For more information about tagging your resources, see [Tagging AWS Network Firewall resources](tagging.md). 

1. Choose **Next**.

1. Review the settings that you've provided for the rule group, then choose **Create stateful rule group**.

Your new rule group is added to the list in the **Network Firewall rule groups** page.

To use your rule group in a firewall policy, follow the procedures at [Managing your firewall policy](firewall-policy-managing.md).

# Updating a stateful rule group
<a name="rule-group-stateful-updating"></a>

To change your stateful rule group settings, use the following procedure.

**To update a stateful rule group**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. In the **Network Firewall rule groups** page, choose the name of the rule group that you want to update. The rule group's details page appears. 

1. In your rule group's details page, in the area that you want to change, choose **Edit**. Follow the prompts to make your updates. The interface varies according to the rule group type. When you're done editing an area, choose **Save** to save your changes in the rule group.

**How Network Firewall propagates your changes**  
When you make any changes to a firewall, including changes to any of the firewall's components, like rule groups, TLS inspection configurations, and firewall policies, Network Firewall propagates the changes everywhere that the firewall is used. Your changes are normally applied within minutes, but there might be a brief period of inconsistency when the changes have arrived in some places and not in others. For example, if you modify a rule group so that it drops an additional type of packet, for a firewall that uses the rule group, the new packet type might briefly be dropped by one firewall endpoint while still being allowed by another. 

This temporary inconsistency can occur when you first create a firewall and when you make changes to an existing firewall. Generally, any inconsistencies of this type last only a few seconds. 

When you add a TLS inspection configuration to an existing firewall, Network Firewall interrupts traffic flows that match the criteria defined by the TLS inspection configuration scope configuration. Network Firewall will begin SSL/TLS decryption and inspection for new connections to the firewall.

Changes to stateful rules are applied only to new traffic flows. Other firewall changes, including changes to stateless rules, are applied to all network packets. 

# Deleting a stateful rule group
<a name="rule-group-stateful-deleting"></a>

To delete a rule group, use the guidance in this section.

**Deleting a rule group, TLS inspection configuration, or firewall policy**  
When you delete a rule group, TLS inspection configuration, or a firewall policy, AWS Network Firewall checks to see if it's currently being referenced. A rule group and TLS inspection configuration can be referenced by a firewall policy, and a firewall policy can be referenced by a firewall. If Network Firewall determines that the resource is being referenced, it warns you. Network Firewall is almost always able to determine whether a resource is being referenced. However, in rare cases, it might not be able to do so. If you need to be sure that the resource that you want to delete isn't in use, check all of your firewalls or firewall policies before deleting it. Note that policies that have associations can't be deleted.

**To delete a stateful rule group**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. In the **Network Firewall rule groups** page, select the name of the rule group that you want to delete, and then choose **Delete**.

**How Network Firewall propagates your changes**  
When you make any changes to a firewall, including changes to any of the firewall's components, like rule groups, TLS inspection configurations, and firewall policies, Network Firewall propagates the changes everywhere that the firewall is used. Your changes are normally applied within minutes, but there might be a brief period of inconsistency when the changes have arrived in some places and not in others. For example, if you modify a rule group so that it drops an additional type of packet, for a firewall that uses the rule group, the new packet type might briefly be dropped by one firewall endpoint while still being allowed by another. 

This temporary inconsistency can occur when you first create a firewall and when you make changes to an existing firewall. Generally, any inconsistencies of this type last only a few seconds. 

Changes to stateful rules are applied only to new traffic flows. Other firewall changes, including changes to stateless rules, are applied to all network packets. 

# Managing evaluation order for Suricata compatible rules in AWS Network Firewall
<a name="suricata-rule-evaluation-order"></a>

You can configure and manage the evaluation order of the rules in your Suricata compatible stateful rule groups. 

All of your stateful rule groups are provided to the rule engine as Suricata compatible strings. Suricata can evaluate stateful rule groups by using the default rule group ordering method, or you can set an exact order using the *strict* ordering method. We recommend that you use strict order because it lets you specify the exact order that you'd like the stateful engine to evaluation your rules. The settings for your rule groups must match the settings for the firewall policy that they belong to.

## Action order
<a name="suricata-default-rule-evaluation-order"></a>

If your firewall policy is set up to use action order rule group ordering, the action order by which Suricata evaluates stateful rules is determined by the following settings, listed in order of precedence:

1. The Suricata `action` specification. This takes highest precedence. 

   Actions are processed in the following order:

   1. `pass`

   1. `drop`

   1. `reject`

   1. `alert`
**Note**  
If a packet within a flow matches a rule containing `pass` action, then Suricata doesn't scan the other packets in that flow and it passes the unscanned packets. 

   For more information about the action specification, see [Suricata.yaml: Action-order](https://docs.suricata.io/en/suricata-7.0.8/configuration/suricata-yaml.html?highlight=action+order#action-order) in the [Suricata User Guide](https://docs.suricata.io/en/suricata-7.0.8/index.html).

1. The Suricata `priority` keyword. Within a specific action group, you can use the priority setting to indicate the processing order. By default, Suricata processes from the lowest numbered priority setting on up. The `priority` keyword has a mandatory numeric value ranging from 1 to 65535. Note that the `priority` keyword is only valid using the default action order.

   For more information about priority, see [Suricata.yaml: Action-order](https://docs.suricata.io/en/suricata-7.0.8/rules/meta.html?highlight=priority#priority) in the [Suricata User Guide](https://docs.suricata.io/en/suricata-7.0.8/index.html).

For example, Suricata evaluates all `pass` rules before evaluating any `drop`, `reject`, or `alert` rules by default, regardless of the value of priority settings. Within all `pass` rules, if priority keywords are present, Suricata orders the processing according to them.

The protocol layer does not impact the rule evaluation order by default. If you want to avoid matching against lower-level protocol packets before higher-level application protocols can be identified, consider using the `flow` keyword in your rules. This is needed because, for example, a TCP rule might match on the first packet of a TCP handshake before the stateful engine can identify the application protocol. For information about the `flow` keyword, see [Flow Keywords](https://docs.suricata.io/en/suricata-7.0.8/rules/flow-keywords.html).

For examples of default rule order management, see [Stateful rules examples: manage rule evaluation order](suricata-examples.md#suricata-example-rule-ordering).

For additional information about evaluation order for stateful rules, see the following topics in the [Suricata User Guide](https://docs.suricata.io/en/suricata-7.0.8/):
+ [Suricata.yaml: Action-order](https://docs.suricata.io/en/suricata-7.0.8/configuration/suricata-yaml.html?highlight=action%20order#action-order)
+ [Meta Keywords: priority](https://docs.suricata.io/en/suricata-7.0.8/rules/meta.html?highlight=priority#priority)

## Strict evaluation order
<a name="suricata-strict-rule-evaluation-order"></a>

If your firewall policy is set up to use strict ordering, Network Firewall allows you the option to manually set a *strict* rule group order. With strict ordering, the rule groups are evaluated by order of priority, starting from the lowest number, and the rules in each rule group are processed in the order in which they're defined.

When configuring these actions, consider the following caveats:

1. For drop actions, you can choose either none or only one drop action.

1. For alert actions, you can choose none, one alert action, or **Alert all** plus any of the other two alert actions.

1. Some combinations of actions are invalid. If either **Drop established** or **Alert established** is selected, you cannot select **Application Layer drop established** or **Application Layer alert established**, and vice versa.

1. When you choose **Strict** for your rule order, you can choose one or more **Default actions**. Note that this does not refer to default action rule ordering, but rather, to the default actions that Network Firewall takes when following your strict, or exact, rule ordering.

The default actions are as follows:

### Drop actions
<a name="suricata-strict-rule-evaluation-order-drop-actions"></a>

If you have rules that match application layer data, such as those that evaluate HTTP headers, a default drop action might trigger earlier than you want. This can happen when the data that your rules match against spans multiple packets, because a default drop action can apply to a single packet. For this case, don't choose any default drop action and instead use drop rules that are specific to the application layer. 

*Choose none or one. You can't choose more than one.*
+ **Drop all** – Drops all packets.
+ **Drop established** – Drops only the packets that are in established connections from client to server. This allows the layer 3 and 4 connection establishment packets that are needed for the upper-layer connections to be established, while dropping the packets for connections that are already established. This allows application-layer *pass* rules to be written in a default-deny setup without the need to write additional rules to allow the lower-layer handshaking parts of the underlying protocols. Packets from established connections from the server to the client are passed to allow return traffic from established connections back to the client.

  Choose this option when using strict order for your own domain list rule groups because Network Firewall requires an established connection in order to evaluate whether to pass or drop the packets for domain lists.

  For other protocols, such as UDP, Network Firewall considers the connection established only after seeing traffic from both sides of the connection. For connectionless protocols, such as UDP and ICMP, the `drop` established action drops all packets. You must write specific rules to allow these packets as needed.
+ **Application Layer drop established** – Drops server-initiated banner packets and packets in established connections. It also provides enhanced support for segmented application layer traffic through the following behaviors:
  + Allows segmented TLS client hello packets until a `TLS.SNI` field is detected, then applies rules based on SNI.
  + Allows segmented HTTPS request packets until the `HTTP.HOST` field is detected, then applies rules based on host

**About the application layer drop established action**  
When you select the application layer drop established option, the firewall drops connections that have banner packets. After a connection is established, if the firewall sees a packet that no explicit pass rule allows, the firewall drops that packet and all subsequent packets in the connection. This behavior affects TCP flow control packets that occur after the TCP handshake but before a pass rule applies. 

Examples of TCP flow control packets that can result in such drops include: 
+ TCP window updates from either client or server, if seen immediately after the TCP handshake.
+ TCP keep-alives from either client or server, if seen immediately after the TCP handshake.
+ TCP resets from either client or server, if seen immediately after the TCP handshake.

To allow these packets in your environment you can add custom pass rules in a stateful rule group, for example:

To allow TCP window packets:

```
pass tcp any any -> any any (msg:"Allow all TCP Window Updates from server to client"; tcp.flags:A; dsize:0; window:!0; flow:established, to_client; sid:1000001;)
pass tcp any any -> any any (msg:"Allow all TCP Window Updates from client to server"; tcp.flags:A; dsize:0; window:!0; flow:established, to_server; sid:1000002;)
```

To allow TCP keep-alives (will pass all ACKs):

```
pass tcp any any -> any any (msg:"Allow TCP keep alives - all acks - from server to client"; tcp.flags:A; dsize:0; flow:established, to_client; sid:1000003;)
pass tcp any any -> any any (msg:"Allow TCP keep alives - all acks - from client to server"; tcp.flags:A; dsize:0; flow:established, to_server; sid:1000004;)
```

To allow TCP resets:

```
pass tcp any any -> any any (msg:"Allow TCP resets from server to client"; tcp.flags:+R; dsize:0; flow:established, to_client; sid:1000005;)
pass tcp any any -> any any (msg:"Allow TCP resets from client to server"; tcp.flags:+R; dsize:0; flow:established, to_server; sid:1000006;)
```

### Alert actions
<a name="suricata-strict-rule-evaluation-order-drop-actions"></a>

*Choose none, one, or all.*
+ **Alert all** - Logs an `ALERT` message on all packets. This does not drop packets, but alerts you to what would be dropped if you were to choose **Drop all**.
+ **Alert established** - Logs an `ALERT` message on only the packets that are in established connections. This does not drop packets, but alerts you to what would be dropped if you were to choose **Drop established**.
+ **Application Layer alert established** – Logs an `ALERT` message on only the packets that are in established connections, with enhanced support for segmented application layer traffic.
**Tip**  
You can use these logged messages to better understand the impact that the Application Layer Drop Established action has on firewall behavior.

For more information about logging network traffic, see [Logging network traffic from AWS Network Firewall](firewall-logging.md).

# Limitations and caveats for stateful rules in AWS Network Firewall
<a name="suricata-limitations-caveats"></a>

AWS Network Firewall stateful rules are Suricata compatible. Most Suricata rules work out of the box with Network Firewall. Your use of Suricata rules with Network Firewall has the restrictions and caveats listed in this section. 

## Suricata features that Network Firewall doesn't support
<a name="suricata-not-supported"></a>

The following Suricata features are not supported by Network Firewall:
+ Datasets. The keywords `dataset` and `datarep` aren't allowed.
+ ENIP/CIP keywords. 
+ File extraction. File keywords aren't allowed. 
+ FTP-data protocol detection.
+ IP reputation. The `iprep` keyword is not allowed. 
+ Lua scripting.
+ Rules actions except for pass, drop, reject, and alert. Pass, drop, reject, and alert are supported. For additional information about stateful rule actions, see [Actions for stateful rules](rule-action.md#rule-action-stateful).
+ SCTP protocol.
+ Thresholding.
+ IKEv2 protocol.
+ IP-in-IP protocol.
+ HTTP/2 overloading.

## Suricata features that Network Firewall supports with caveats
<a name="suricata-supported-with-caveats"></a>

The following Suricata features have caveats for use with Network Firewall:
+ If you want a rule group to use settings for `HOME_NET` and `EXTERNAL_NET` that are different from those that are set for the firewall policy, you must explicitly set both of these variables. 
  + In a firewall policy's variables, you can set a custom value for `HOME_NET`. The default `HOME_NET` setting is the CIDR of the inspection VPC. The policy's `EXTERNAL_NET` setting is always the negation of the policy's `HOME_NET` setting. For example, if the `HOME_NET` is `11.0.0.0`, the `EXTERNAL_NET` is set to `!11.0.0.0`.
  + In a rule group's variables, you can set custom values for both `HOME_NET` and `EXTERNAL_NET`. If you explicitly set rule group variables, those are used. Otherwise, rule group variables inherit their settings from the corresponding policy variables. 

    This means that, if you don't specify the rule group's `EXTERNAL_NET`, it inherits the setting from the policy's `EXTERNAL_NET` setting, regardless of the value of the rule group's `HOME_NET` setting. 

    For example, say you set the rule group's `HOME_NET` to `10.0.0.0`, and the firewall policy's `HOME_NET` to `11.0.0.0`. If you don't set the rule group's `EXTERNAL_NET`, then Network Firewall sets it to `!11.0.0.0`, based on the policy's `HOME_NET` setting. 
+ The AWS Network Firewall stateful inspection engine supports inspecting inner packets for tunneling protocols such as Generic Routing Encapsulation (GRE). If you want to block the tunneled traffic, you can write rules against the tunnel layer itself or against the inner packet. Due to the service inspecting the different layers, you might see flows and alerts for the packets within the tunnel.
+ To create a rule that requires a variable, you must specify the variable in the rule group. Without the required variables, the rule group isn't valid. For an example of a rule group that's configured with variables, see [Stateful rules examples: rule variables](suricata-examples.md#suricata-example-rule-with-variables).
+ In payload keywords, the `pcre` keyword is only allowed with `content`, `tls.sni`, `http.host`, and `dns.query` keywords.
+ The `priority` keyword is not supported for rule groups that evaluate rules using strict evaluation order.
+ When matching TLS based rules in a TLS inspection-enabled configuration, alert logs capture http host information and not the SNI upon rule match
+ When you use a stateful rule with a layer 3 or 4 protocol such as IP or TCP, and you don't include any flow state context, for example `"flow:not_established"`, then Suricata treats this rule as an IP-only rule. Suricata only evaluates IP-only rules for the first packet in each direction of the flow. For example, Suricata will process the following rule as an IP-only rule:

  ```
  pass tcp $HOME_NET any -> [10.0.0.0/8] $HTTPS_PORTS (sid: 44444; rev:2;)
  ```

  However, if the destination IP contains a `!`, then Suricata treats this as per the protocol specified in the rule. Suricata will process the following rule as a TCP rule.

  ```
  pass tcp $HOME_NET any -> [!10.0.0.0/16] $HTTPS_PORTS (sid: 44444; rev:2;)
  ```
+ To match HTTP/2 application traffic under a TLS inspection-enabled configuration, add http2 protocol rules to your rule set in addition to your existing HTTP rules. For example, if you used this rule to match HTTP traffic:

  ```
  drop http $HOME_NET any -> $EXTERNAL_NET any (msg:"example rule"; flow:to_server,established; http.host; content:"example.com"; sid:1; rev:1;)
  ```

  You should add an http2 application rule to your ruleset:

  ```
  drop http $HOME_NET any -> $EXTERNAL_NET any (msg:"example rule"; flow:to_server,established; http.host; content:"example.com"; sid:1; rev:1;)
  drop http2 $HOME_NET any -> $EXTERNAL_NET any (msg:"example rule"; flow:to_server,established; http.request_header; content:"authority|3a 20|example.com"; sid:2; rev:1;)
  ```

# Best practices for writing Suricata compatible rules for AWS Network Firewall
<a name="suricata-best-practices"></a>

A stateful rule group is a rule group that uses Suricata compatible intrusion prevention system (IPS) specifications. Suricata is an open source network IPS that includes a standard rule-based language for stateful network traffic inspection. You can enter any stateful rule in Suricata compatible strings. 

When you write your stateful rules, verify the configuration of the firewall policy where you intend to use them, to make sure that all of your rules evaluate as you want them to. For information about how AWS Network Firewall handles network traffic and when it sends it to the stateful engine, see [How AWS Network Firewall filters network traffic](firewall-policy-processing.md). 

For example, many stateful rules rely on seeing a complete bidirectional traffic flow for correct evaluation, such as rules with options like `flow: established`. To use rules like this, you must configure your stateless rules and default actions to ensure forwarding of traffic for both directions to the stateful engine. For information about these action options, see [Defining rule actions in AWS Network Firewall](rule-action.md). 

# Examples of stateful rules for Network Firewall
<a name="suricata-examples"></a>

This section lists examples of Suricata compatible rules that could be used with AWS Network Firewall. 

**Note**  
Examples are not intended to be used in your Network Firewall configuration exactly as they are listed.  
The examples provide general information and sample rule specifications for common use cases. Before using any rule from these examples or elsewhere, test and adjust it carefully to be sure that it fits your needs. It's your responsibility to ensure that each rule that you use is suited to your specific use case and functioning the way that you want it to. 

## Stateful rules examples: allow traffic
<a name="suricata-example-allow-rules"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The examples in this section contain examples that allow specified traffic.

**Allow access to any `ssm.` Server Name Indication (SNI) ending with `.amazonaws.com`**  
Allows access to any domain that begins with `ssm.` and ends with `.amazonaws.com` (http://amazonaws.com/).

```
pass tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; content:"ssm."; startswith; content:".amazonaws.com"; endswith; nocase; flow: to_server; sid:202308311;)
```

**JA3 hash**  
This rule allows outbound access using a specific JA3 hash

```
pass tls $HOME_NET any -> $EXTERNAL_NET any (msg:"Only allow Curl 7.79.1 JA3"; ja3.hash; content:"27e9c7cc45ae47dc50f51400db8a4099"; sid:12820009;)
```

**Outbound requests to `checkip.amazonaws.com`**  
These rules only allow outbound requests to the SNI `checkip.amazonaws.com` (http://checkip.amazonaws.com/) if the server certificate issuer is also Amazon. Requires that your firewall policy uses strict order rule evaluation order.

```
alert tls $HOME_NET any -> $EXTERNAL_NET 443 (ssl_state:client_hello; tls.sni; content:"checkip.amazonaws.com"; endswith; nocase; xbits:set, allowed_sni_destination_ips, track ip_dst, expire 3600; noalert; sid:238745;)
pass tcp $HOME_NET any -> $EXTERNAL_NET 443 (xbits:isset, allowed_sni_destination_ips, track ip_dst; flow: stateless; sid:89207006;)
pass tls $EXTERNAL_NET 443 -> $HOME_NET any (tls.cert_issuer; content:"Amazon"; msg:"Pass rules do not alert"; xbits:isset, allowed_sni_destination_ips, track ip_src; sid:29822;)
reject tls $EXTERNAL_NET 443 -> $HOME_NET any (tls.cert_issuer; content:"="; nocase; msg:"Block all other cert issuers not allowed by sid:29822"; sid:897972;)
```

**Outbound SSH/SFTP servers with `AWS_SFTP` banner**  
These rules only allow outbound access to SSH/SFTP servers that have a banner that includes `AWS_SFTP`, which is the banner for AWS Transfer Family servers. To check for a different banner, replace `AWS_SFTP` with the banner you want to check for.

```
pass tcp $HOME_NET any -> $EXTERNAL_NET 22 (flow:stateless; sid:2221382;)
pass ssh $EXTERNAL_NET 22 -> $HOME_NET any (ssh.software; content:"AWS_SFTP"; flow:from_server; sid:217872;)
drop ssh $EXTERNAL_NET 22 -> $HOME_NET any (ssh.software; content:!"@"; pcre:"/[a-z]/i"; msg:"Block unauthorized SFTP/SSH."; flow: from_server; sid:999217872;)
```

**Send DNS query including `.amazonaws.com` to external DNS servers**  
This rule allows any DNS query for domain names ending in `.amazonaws.com` (http://amazonaws.com/) to be sent to external DNS servers.

```
pass dns $HOME_NET any -> $EXTERNAL_NET any (dns.query; dotprefix; content:".amazonaws.com"; endswith; nocase; msg:"Pass rules do not alert"; sid:118947;)
```

## Stateful rules examples: block traffic
<a name="suricata-example-block-rules"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The examples in this section contain examples that block specified traffic.

**Connections using TLS versions 1.0 or 1.1**  
This rule blocks connections using TLS version 1.0 or 1.1.

```
reject tls any any -> any any (msg:"TLS 1.0 or 1.1"; ssl_version:tls1.0,tls1.1; sid:2023070518;)
```

**Multiple CIDR ranges**  
This rule blocks outbound access to multiple CIDR ranges in a single rule.

```
drop ip $HOME_NET any-> [10.10.0.0/16,10.11.0.0/16,10.12.0.0/16] (msg:"Block traffic to multiple CIDRs"; sid:278970;)
```

**Multiple SNIs**  
This rule blocks multiple SNIs with a single rule.

```
reject tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; pcre:"/(example1\.com|example2\.com)$/i"; flow: to_server; msg:"Domain blocked"; sid:1457;)
```

**Multiple high-risk destination outbound ports**  
This rule blocks multiple high-risk destination outbound ports in a single rule.

```
drop ip $HOME_NET any -> $EXTERNAL_NET [1389,53,4444,445,135,139,389,3389] (msg:"Deny List High Risk Destination Ports"; sid:278670;)
```

**Outbound HTTP HOST**  
This rule blocks outbound HTTP connections that have an IP address in the HTTP `HOST` header.

```
reject http $HOME_NET any -> $EXTERNAL_NET any (http.host; content:"."; pcre:"/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/"; msg:"IP in HTTP HOST Header (direct to IP, likely no DNS resolution first)"; flow:to_server; sid:1239847;)
```

**Outbound TLS with IP in SNI**  
This rule blocks outbound TLS connections with an IP address in the SNI.

```
reject tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; content:"."; pcre:"/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/"; msg:"IP in TLS SNI (direct to IP, likely no DNS resolution first)"; flow:to_server; sid:1239848;)
```

**Any IP protocols other than TCP, UDP, and ICMP**  
This rule silently blocks any IP protocols other than TCP, UDP, and ICMP.

```
drop ip any any-> any any (noalert; ip_proto:!TCP; ip_proto:!UDP; ip_proto:!ICMP; sid:21801620;)
```

**SSH non-standard ports**  
This rule blocks the use of the SSH protocol on non-standard ports.

```
reject ssh $HOME_NET any -> $EXTERNAL_NET !22 (msg:"Block use of SSH protocol on non-standard port"; flow: to_server; sid:2171010;)
```

**TCP/22 servers non-SSH**  
This rule blocks the use of TCP/22 servers that aren't using the SSH protocol.

```
reject tcp $HOME_NET any -> $EXTERNAL_NET 22 (msg:"Block TCP/22 servers that are not SSH protocol"; flow: to_server; app-layer-protocol:!ssh; sid:2171009;)
```

## Stateful rules examples: log traffic
<a name="suricata-example-logging"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The examples in this section demonstrate ways to log traffic. To log traffic, you must configure logging for your firewall. For information about logging Network Firewall traffic, see [Logging and monitoring in AWS Network Firewall](logging-monitoring.md).

**Log traffic direction in default-deny policy**  
Can be used at the end of a default-deny policy to accurately log the direction of denied traffic. These rules help you to make it clear in the logs who the client is and who the server is in the connection.

```
reject tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"Default Egress TCP block to server"; flow:to_server; sid:202308171;)
drop udp $HOME_NET any -> $EXTERNAL_NET any (msg:"Default Egress UDP block";sid:202308172;)
drop icmp $HOME_NET any -> $EXTERNAL_NET any (msg:"Default Egress ICMP block";sid:202308177;)
drop tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"Default Ingress block to server"; flow:to_server; sid:20230813;)
drop udp $EXTERNAL_NET any -> $HOME_NET any (msg:"Default Ingress UDP block"; sid:202308174;)
drop icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"Default Ingress ICMP block"; sid:202308179;)
```

**Log traffic to an allowed SNI**  
The `alert` keyword can be used in the pass rule to generate alert logs for all matches. This rule logs all passed traffic to an allowed SNI.

```
pass tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; content:".example.com"; dotprefix; endswith; nocase; alert; sid:202307052;)
```

## Stateful rules examples: rule variables
<a name="suricata-example-rule-with-variables"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The following JSON defines an example Suricata compatible rule group that uses the variables `HTTP_SERVERS` and `HTTP_PORTS`, with the variable definitions provided in the rule group declaration. 

```
{
"RuleVariables": {
    "IPSets": {
        "HTTP_SERVERS": {
            "Definition": [
                "10.0.2.0/24",
                "10.0.1.19"
            ]
        }
    },
    "PortSets": {
        "HTTP_PORTS": {
            "Definition": ["80", "8080"]
        }
    }
},
"RulesSource": {
    "RulesString": "alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:\".htpasswd access attempt\"; flow:to_server,established; content:\".htpasswd\"; nocase; sid:210503; rev:1;)"
}
}
```

The variable `EXTERNAL_NET` is a Suricata standard variable that represents the traffic destination. For more Suricata-specific information, see the [Suricata documentation](https://docs.suricata.io/en/suricata-7.0.8/).

## Stateful rules examples: IP set reference
<a name="suricata-example-rule-with-ip-set-reference"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

To reference a prefix list in your rule group, specify a IP set variable name and associate it with the prefix list's Amazon Resource Name (ARN). Then, specify the variable in one or more of your rules, prefacing the variable with `@`, such as `@IP_Set_Variable`. The variable represents the IPv4 prefix list that you are referencing. For more information about using IP set references, see [Referencing Amazon VPC prefix lists](rule-groups-ip-set-references.md#rule-groups-referencing-prefix-lists).

The following example shows a Suricata compatible rule that uses an IP set reference variable `@BETA` as the source port in `RulesString`. To use an IP set reference in your rule, you must use an `@` in front of the IP set variable name, such as `@My_IP_set_variable_name`.

```
{
   "RuleVariables":{
      "IPSets":{
         "HTTP_SERVERS":{
            "Definition":[
               "10.0.2.0/24",
               "10.0.1.19"
            ]
         }
      },
      "PortSets":{
         "HTTP_PORTS":{
            "Definition":[
               "80",
               "8080"
            ]
         }
      }
   },
   "ReferenceSets":{
      "IPSetReferences":{
         "BETA":{
            "ReferenceArn":"arn:aws:ec2:us-east-1:555555555555:prefix-list/pl-1111111111111111111_beta"
         }
      }
   },
   "RulesSource":{
      "RulesString":"drop tcp @BETA any -> any any (sid:1;)"
   }
}
```

## Stateful rules examples: Geographic IP filter
<a name="suricata-example-rule-with-geo-ip-filter"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

For information about Geographic IP filtering in Network Firewall, see [Geographic IP filtering in Suricata compatible AWS Network Firewall rule groups](rule-groups-geo-ip-filtering.md).

The following shows an example Suricata rule string that generates an alert for traffic to or from Russia: 

```
alert ip any any -> any any (msg:"Geographic IP is from RU, Russia"; geoip:any,RU; sid:55555555; rev:1;)
```

The following shows an example standard stateful rule group that drops traffic unless it originates from the United States or the United Kingdom: 

```
{
    "RulesSource": {
      "StatefulRules": [
        {
          "Action": "DROP",
          "Header": {
            "DestinationPort": "ANY",
            "Direction": "FORWARD",
            "Destination": "ANY",
            "Source": "ANY",
            "SourcePort": "ANY",
            "Protocol": "IP"
          },
          "RuleOptions": [
            {
              "Settings": [
                "1"
              ],
              "Keyword": "sid"
            },
            {
              "Settings": [
                "src,!US,UK"
              ],
              "Keyword": "geoip"
            }
          ]
        }
      ]
    },
    "StatefulRuleOptions": {
       "RuleOrder": "STRICT_ORDER"
     }
 }
```

## Stateful rules examples: URL/Domain Category filter
<a name="suricata-example-rule-with-url-filter"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

For information about URL and Domain Category filtering in Network Firewall, see [URL and Domain Category Filtering in Suricata compatible AWS Network Firewall rule groups](rule-groups-url-filtering.md).

aws\$1url\$1category evaluates complete URLs (with TLS inspection) and domains, while aws\$1domain\$1category evaluates only domain information from TLS SNI or HTTP host headers.

The following shows an example Suricata rule string that generates an alert for traffic categorized as malicious:

```
alert http any any -> any any (msg:"URL Category is Malicious"; aws_url_category:Malicious; sid:55555555; rev:1;)
```

The following shows an example that blocks traffic categorized under gambling and social networking categories:

```
drop http any any -> any any (msg:"Block gambling and social sites"; aws_url_category:Gambling,Social Networking; sid:55555556; rev:1;)
```

The following shows an example standard stateful rule group that drops traffic to malware and phishing sites using `aws_url_category`: 

```
{
    "RulesSource": {
      "StatefulRules": [
        {
          "Action": "DROP",
          "Header": {
            "DestinationPort": "ANY",
            "Direction": "FORWARD",
            "Destination": "ANY",
            "Source": "ANY",
            "SourcePort": "ANY",
            "Protocol": "HTTP"
          },
          "RuleOptions": [
            {
              "Settings": [
                "1"
              ],
              "Keyword": "sid"
            },
            {
              "Settings": [
                "Malware,Phishing"
              ],
              "Keyword": "aws_url_category"
            }
          ]
        }
      ]
    },
    "StatefulRuleOptions": {
      "RuleOrder": "STRICT_ORDER"
    }
}
```

The following shows an example using domain-level filtering that generates an alert for traffic categorized as cryptocurrency:

```
alert tls any any -> any any (msg:"Domain Category is Cryptocurrency"; aws_domain_category:Cryptocurrency; sid:55555557; rev:1;)
```

The following shows an example standard stateful rule group that drops traffic to malware and phishing sites using `aws_domain_category`:

```
{
    "RulesSource": {
      "StatefulRules": [
        {
          "Action": "DROP",
          "Header": {
            "DestinationPort": "ANY",
            "Direction": "FORWARD",
            "Destination": "ANY",
            "Source": "ANY",
            "SourcePort": "ANY",
            "Protocol": "HTTP"
          },
          "RuleOptions": [
            {
              "Settings": [
                "1"
              ],
              "Keyword": "sid"
            },
            {
              "Settings": [
                "Malware,Phishing"
              ],
              "Keyword": "aws_domain_category"
            }
          ]
        }
      ]
    },
    "StatefulRuleOptions": {
      "RuleOrder": "STRICT_ORDER"
    }
}
```

## Stateful rules examples: manage rule evaluation order
<a name="suricata-example-rule-ordering"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The examples in this section demonstrate ways to modify evaluation behavior by modifying rule evaluation order in Suricata compatible rules. Network Firewall recommends using strict order so that you can have control over the way your rules are processed for evaulation. For information about managing rule evaluation order, see [Managing evaluation order for Suricata compatible rules in AWS Network Firewall](suricata-rule-evaluation-order.md).

Allow HTTP traffic to specific domains:

**Default action order**

```
drop tcp $HOME_NET any -> $EXTERNAL_NET 80 (msg:"Drop established TCP:80"; flow: from_client,established; sid:172190; priority:5; rev:1;)
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Allowed HTTP domain"; priority:10; sid:172191; rev:1;)
pass tcp $HOME_NET any -> $EXTERNAL_NET 22 (msg:"Allow TCP 22"; sid:172192; rev:1;)
drop tcp $HOME_NET any -> $EXTERNAL_NET !80 (msg:"Drop All non-TCP:80";  sid:172193; priority:2; rev:1;)
```

**Strict order**

```
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Allowed HTTP domain"; sid:172191; rev:1;)
pass tcp $HOME_NET any -> $EXTERNAL_NET 22 (msg:"Allow TCP 22"; sid:172192; rev:1;)
```

Allow HTTP traffic to specific domains only:

**Default action order**

```
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Allowed HTTP domain"; priority:1; sid:102120; rev:1;)
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".mydomain.test"; endswith; msg:"Allowed HTTP domain"; priority:1; sid:102121; rev:1;)
drop http $HOME_NET any -> $EXTERNAL_NET 80 (msg:"Drop HTTP traffic"; priority:1; sid:102122; rev:1;)
```

**Strict order**

```
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Allowed HTTP domain"; sid:102120; rev:1;)
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".mydomain.test"; endswith; msg:"Allowed HTTP domain"; sid:102121; rev:1;)
```

Allow HTTP traffic to specific domains only and deny all other IP traffic:

**Default action order**

```
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Allowed HTTP domain"; priority:1; sid:892120; rev:1;)
drop tcp $HOME_NET any -> $EXTERNAL_NET 80 (msg:"Drop established non-HTTP to TCP:80"; flow: from_client,established; sid:892191; priority:5; rev:1;)
drop ip $HOME_NET any <> $EXTERNAL_NET any (msg: "Drop non-TCP traffic."; ip_proto:!TCP;sid:892192; rev:1;)
drop tcp $HOME_NET any -> $EXTERNAL_NET !80 (msg:"Drop All non-TCP:80"; sid:892193; priority:2; rev:1;)
```

**Strict order**

```
pass http $HOME_NET any -> $EXTERNAL_NET 80 (http.host; dotprefix; content:".example.com"; endswith; msg:"Allowed HTTP domain"; sid:892120; rev:1;)
pass tcp $HOME_NET any <> $EXTERNAL_NET 80 (flow:not_established; sid:892191; rev:1;)
```

## Stateful rules examples: domain list rules
<a name="suricata-example-domain-filtering"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

**Deny list example JSON, rule group creation, and generated Suricata rules**  
The following JSON shows an example rule definition for a Network Firewall domain list rule group that specifies a deny list.

```
{
    "RulesSource": {
        "RulesSourceList": {
            "Targets": [
                "evil.com"
            ],
            "TargetTypes": [
                 "TLS_SNI",
                 "HTTP_HOST"
             ],
             "GeneratedRulesType": "DENYLIST"
        }
    }
}
```

To use the Network Firewall rule specification, we save the JSON to a local file `domainblock.example.json`, and then create the rule group in the following CLI command: 

```
aws network-firewall create-rule-group --rule-group-name "RuleGroupName" --type STATEFUL --rule-group file://domainblock.example.json --capacity 1000
```

The following Suricata rules listing shows the rules that Network Firewall creates for the above deny list specification.

```
drop tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; content:"evil.com"; startswith; nocase; endswith; msg:"matching TLS denylisted FQDNs"; priority:1; flow:to_server, established; sid:1; rev:1;)
drop http $HOME_NET any -> $EXTERNAL_NET any (http.host; content:"evil.com"; startswith; endswith; msg:"matching HTTP denylisted FQDNs"; priority:1; flow:to_server, established; sid:2; rev:1;)
```

**HTTP allow list example JSON and generated Suricata rules**  
The following JSON shows an example rule definition for a Network Firewall domain list rule group that specifies an HTTP allow list. The `.` before the domain name in `.amazon.com` is the wildcard indicator in Suricata.

```
{
    "RulesSource": {
        "RulesSourceList": {
            "Targets": [
                ".amazon.com",
                "example.com"
            ],
            "TargetTypes": [
                "HTTP_HOST"
            ],
            "GeneratedRulesType": "ALLOWLIST"
        }
    }
}
```

The following Suricata rules listing shows the rules that Network Firewall creates for the above allow list specification.

```
pass http $HOME_NET any -> $EXTERNAL_NET any (http.host; dotprefix; content:".amazon.com"; endswith; msg:"matching HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:1; rev:1;)
pass http $HOME_NET any -> $EXTERNAL_NET any (http.host; content:"example.com"; startswith; endswith; msg:"matching HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:2; rev:1;)
drop http $HOME_NET any -> $EXTERNAL_NET any (http.header_names; content:"|0d 0a|"; startswith; msg:"not matching any HTTP allowlisted FQDNs"; priority:1; flow:to_server, established; sid:3; rev:1;)
```

**TLS allow list example JSON and generated Suricata rules**  
The following JSON shows an example rule definition for a Network Firewall domain list rule group that specifies a TLS allow list.

```
{
    "RulesSource": {
        "RulesSourceList": {
            "Targets": [
                ".amazon.com",
                "example.com"
            ],
            "TargetTypes": [
                "TLS_SNI"
            ],
            "GeneratedRulesType": "ALLOWLIST"
        }
    }
}
```

The following Suricata rules listing shows the rules that Network Firewall creates for the above allow list specification.

```
pass tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; dotprefix; content:".amazon.com"; nocase; endswith; msg:"matching TLS allowlisted FQDNs"; priority:1; flow:to_server, established; sid:1; rev:1;)
pass tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; content:"example.com"; startswith; nocase; endswith; msg:"matching TLS allowlisted FQDNs"; priority:1; flow:to_server, established; sid:2; rev:1;)
drop tls $HOME_NET any -> $EXTERNAL_NET any (msg:"not matching any TLS allowlisted FQDNs"; priority:1; ssl_state:client_hello; flow:to_server, established; sid:3; rev:1;)
```

**Block traffic from `$EXTERNAL_NET` to `$HOME_NET`, allow outbound domain filtering**  
These rules block all unsolicited traffic from `$EXTERNAL_NET` to `$HOME_NET` while still allowing outbound domain filtering.

```
reject tls any any -> any any (msg:"Vulnerable versions of TLS"; ssl_version:tls1.0,tls1.1; sid:2023070518;)
```

## Stateful rules examples: standard stateful rule groups
<a name="suricata-example-basic"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The following JSON shows an example rule definition for a Network Firewall basic stateful rule group. 

```
{
    "RulesSource": {
        "StatefulRules": [
          {
            "Action": "DROP",
            "Header": {
                "Protocol": "HTTP",
                "Source": "$HOME_NET",
                "SourcePort": "ANY",
                "Direction": "ANY",
                "Destination": "$EXTERNAL_NET",
                "DestinationPort": "ANY"
            },
            "RuleOptions": [ {
                    "Keyword": "msg",
                    "Settings": [ "\"this is a stateful drop rule\""
                    ]
                },
                {
                    "Keyword": "sid",
                    "Settings": [ "1234"
                    ]
                }
            ]
        }
      ]
    }
}
```

The following Suricata rules listing shows the rules that Network Firewall generates for the above deny list specification.

```
drop http $HOME_NET ANY <> $EXTERNAL_NET ANY (msg:this is a stateful drop rule; sid:1234;)
```

## Stateful rules example: allow traffic to a domain using its SNI
<a name="suricata-example-allow-one-domain-strict"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The following set of rules will allow traffic to a domain using its SNI, while blocking traffic to all other domains in a strict order action policy.

```
# Drop all established to_server traffic (even TLS) from $HOME_NET to $EXTERNAL_NET 
drop tcp $HOME_NET any -> $EXTERNAL_NET any (flow: to_server, established; sid:1;)

# This rule does not allow the traffic because it is already dropped by sid:1, but it does keep the dropped traffic from touching any other rules in the ruleset
pass tcp $HOME_NET any -> $EXTERNAL_NET any (flow: to_server, established; sid:11;)

# Allow all TLS from anywhere to anywhere if it's SNI is example.com
pass tls $HOME_NET any -> $EXTERNAL_NET any (ssl_state:client_hello; tls.sni; content:"example.com"; dotprefix; nocase; flow: to_server, established; sid:2;)
```

## Stateful rules example: filter domains on http2
<a name="suricata-example-http2-domain-filter"></a>

**Note**  
Before using any example rule, test and adapt it to your needs.

The following set of rules will allow http2 traffic to `https://example.com` and block all other http2 traffic.

```
# Pass the domain with an http2 based rule
pass http2 $HOME_NET any -> $EXTERNAL_NET any (http.request_header; content:"authority|3a 20|example.com"; sid:1; rev:1;)

# Reject traffic for non-allowed TCP except http2
reject tcp $HOME_NET any -> $EXTERNAL_NET any (app-layer-protocol:!http2; flow:to_server, established; sid:2; rev:1;)

# Drop all other http2 decrypted traffic
drop http2 $HOME_NET any -> $EXTERNAL_NET any (flow:established, to_server; http2.header_name; content:"authority"; sid:3; rev:1;)
```

# Working with stateless rule groups in AWS Network Firewall
<a name="stateless-rule-groups-standard"></a>

For stateless rule groups, the AWS Network Firewall stateless rules engine examines each packet in isolation. Network Firewall doesn't consider context such as traffic direction or other related packets. 

Network Firewall supports standard network connection identifiers (source IP address, source port, destination IP address, destination port, and protocol) for network traffic inspection. When Network Firewall finds a match between a rule's inspection criteria and a packet, we say that the packet matches the rule and its rule group, and Network Firewall applies the rule's specified action to the packet. 

You can add multiple stateless rules to your stateless rule group.

All rule groups have the common settings that are defined at [Common rule group settings in AWS Network Firewall](rule-group-settings.md).

**General settings**  
A stateless rule has the following general settings.
+ **Priority** – Number that indicates the processing order of the stateless rule within the rule group. This must be unique within the stateless rule group and it must be a positive integer. Network Firewall processes the rules starting from the lowest numbered priority setting. When you plan the rules in your rule group, provide priority settings with space in between, to leave yourself room to add rules later. For example, you might start by using priority settings that are multiples of 100.
+ **Actions** – Defines how Network Firewall handles a packet that matches the rule match settings. You assign one standard setting, from among pass, drop, and forward to stateful. You can optionally add a custom setting, for example, to send metrics for the rule match to Amazon CloudWatch metrics. For more information about actions, see [Defining rule actions in AWS Network Firewall](rule-action.md).

**Match settings**  
A stateless rule has the following match settings. These specify what the Network Firewall stateless rules engine looks for in a packet. To be a match, a packet must satisfy all of the match settings in the rule. 
+ **Protocol** – Valid settings include `ALL` and specific protocol settings, like `UDP` and `TCP`. You can choose more than one specific setting.
+ **Source IP** – Source IP addresses and ranges. If specified, a packet must come from a source address that's included in this list in order to match.
+ **Source port range** – Source ports and port ranges. If specified, a packet must have a source port that's included in this list in order to match.
+ **Destination IP** – Destination IP addresses and ranges. If specified, a packet must have a destination address that's included in this list in order to match.
+ **Destination port range** – Destination ports and port ranges. If specified, a packet must have a destination port that's included in this list in order to match.
+ **Optional TCP flags** – Optional, standard TCP flag settings, which indicate which flags to inspect and the values to inspect for. Each flag can be either enabled or disabled. You indicate the flags that you want to inspect in a masks setting, and then you indicate which of those flags must be enabled in the flags setting in order to match. The flags that you specify in the masks setting and don't specify in the flags setting must be unset in order to match. 

**Example**  
To create a very simple stateless rule group that passes all traffic from two CIDR blocks, you could provide the following stateless rule settings in a single rule: 
+ **Priority** – `100`
+ **Action** – `PASS`
+ **Protocol** – `ALL`
+ **Source** – `192.0.2.0/8`, `198.51.100.0/16`

To block all other traffic, you would set the firewall policy's stateless default actions to `Drop`. For more information, see [Firewall policy settings in AWS Network Firewall](firewall-policy-settings.md).

# Creating a stateless rule group
<a name="rule-group-stateless-creating"></a>

Follow the guidance in this section to create a stateless rule group through the Network Firewall console.

**To create a stateless rule group**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. Choose **Create Network Firewall rule group**. 

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. Choose **Create Network Firewall rule group**. 

1. Under **Choose rule group type**, for the **Rule group format**, choose **Stateless rule group**. 

1. Choose **Next**.

1. Enter a name and description for the rule group. You'll use these to identify the rule group when you manage it and use it. 
**Note**  
You can't change the name after you create the rule group.

1. For **Capacity**, set the maximum capacity you want to allow for the stateless rule group, up to the maximum of 30,000. You can't change this setting after you create the rule group. For information about how to calculate this, see [Setting rule group capacity in AWS Network Firewall](nwfw-rule-group-capacity.md). For information about the maximum setting, see [AWS Network Firewall quotas](quotas.md). 

1. Choose **Next**.

1. Review the rules that you want to add to the stateless rule group. Determine roughly what order you want Network Firewall to process them within the rule group. You need to provide unique, positive integer priority settings for your rules to indicate the processing order. Network Firewall processes from the lowest number up. We recommend using numbers with room in between, to allow for future insertions within the list of rules. For example, you might start with rule priorities numbered 100, 200, and so on. 

1. Add each rule to the rule group as follows: 

   1. For **Priority**, provide the priority to set the processing order of your rule. 

   1. Choose the protocol and the source and destination settings for your rule. 

   1. (Optional) For **TCP flags** provide the masks and flags that you want to inspect for. In **Masks**, indicate the flags that you want to inspect. In **Flags**, indicate which of the flags that you selected in **Masks** must be set. The other flags that you selected in **Masks** must be unset. 

   1. For **Actions**, do the following: 

      1. For **Action**, select the standard action that you want Network Firewall to take when a packet matches the rule settings. 

      1. (Optional) For **Publish metrics**, add a new named custom action or select one that you've already created in the rule group. This option sends an Amazon CloudWatch metric dimension named `CustomAction` with a value that you specify. 

      For additional information on these options, see [Actions for stateless rules](rule-action.md#rule-action-stateless). 

   1. Choose **Add rule**. Your rule is added to the **Rules** list for the rule group, ordered by priority.

1. Choose **Next**.

1. (Optional) On the **Configure advanced settings** page, configure a customer managed AWS Key Management Service customer managed key to encrypt and decrypt your resources instead of the default key.

1. Under **Customer managed key**, toggle the **Customize encryption settings** option to configure your customer managed key. For more information about this option, see [Encryption at rest with AWS Key Management Service](kms-encryption-at-rest.md).

1. Choose **Next**.

1. (Optional) On the **Add tags** page, enter a key and optional value for any tag that you want added to this firewall policy. Tags help you organize and manage your AWS resources. For more information about tagging your resources, see [Tagging AWS Network Firewall resources](tagging.md). 

1. Choose **Next**.

1. Review the settings for the rule group, then choose **Create stateless rule group**. 

Your new rule group is added to the list in the **Network Firewall rule groups** page.

To use your rule group in a firewall policy, follow the procedures at [Managing your firewall policy](firewall-policy-managing.md).

# Updating a stateless rule group
<a name="rule-group-updating"></a>

Follow the guidance in this section to change your rule group settings through the Network Firewall console.

**To update a stateless rule group**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. In the **Network Firewall rule groups** page, choose the name of the rule group that you want to update. The rule group's details page appears. 

1. In your rule group's details page, in the area that you want to change, choose **Edit**. Follow the prompts to make your updates. The interface varies according to the rule group type. When you're done editing an area, choose **Save** to save your changes in the rule group.

**How Network Firewall propagates your changes**  
When you make any changes to a firewall, including changes to any of the firewall's components, like rule groups, TLS inspection configurations, and firewall policies, Network Firewall propagates the changes everywhere that the firewall is used. Your changes are normally applied within minutes, but there might be a brief period of inconsistency when the changes have arrived in some places and not in others. For example, if you modify a rule group so that it drops an additional type of packet, for a firewall that uses the rule group, the new packet type might briefly be dropped by one firewall endpoint while still being allowed by another. 

This temporary inconsistency can occur when you first create a firewall and when you make changes to an existing firewall. Generally, any inconsistencies of this type last only a few seconds. 

When you add a TLS inspection configuration to an existing firewall, Network Firewall interrupts traffic flows that match the criteria defined by the TLS inspection configuration scope configuration. Network Firewall will begin SSL/TLS decryption and inspection for new connections to the firewall.

Changes to stateful rules are applied only to new traffic flows. Other firewall changes, including changes to stateless rules, are applied to all network packets. 

# Deleting a stateless rule group
<a name="rule-group-deleting"></a>

Follow the guidance in this section to delete a rule group through the Network Firewall console.

**Deleting a rule group, TLS inspection configuration, or firewall policy**  
When you delete a rule group, TLS inspection configuration, or a firewall policy, AWS Network Firewall checks to see if it's currently being referenced. A rule group and TLS inspection configuration can be referenced by a firewall policy, and a firewall policy can be referenced by a firewall. If Network Firewall determines that the resource is being referenced, it warns you. Network Firewall is almost always able to determine whether a resource is being referenced. However, in rare cases, it might not be able to do so. If you need to be sure that the resource that you want to delete isn't in use, check all of your firewalls or firewall policies before deleting it. Note that policies that have associations can't be deleted.

**To delete a rule group**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. In the **Network Firewall rule groups** page, select the name of the rule group that you want to delete, and then choose **Delete**.

**How Network Firewall propagates your changes**  
When you make any changes to a firewall, including changes to any of the firewall's components, like rule groups, TLS inspection configurations, and firewall policies, Network Firewall propagates the changes everywhere that the firewall is used. Your changes are normally applied within minutes, but there might be a brief period of inconsistency when the changes have arrived in some places and not in others. For example, if you modify a rule group so that it drops an additional type of packet, for a firewall that uses the rule group, the new packet type might briefly be dropped by one firewall endpoint while still being allowed by another. 

This temporary inconsistency can occur when you first create a firewall and when you make changes to an existing firewall. Generally, any inconsistencies of this type last only a few seconds. 

Changes to stateful rules are applied only to new traffic flows. Other firewall changes, including changes to stateless rules, are applied to all network packets. 

# Analyzing stateless rule groups in AWS Network Firewall
<a name="stateless-rule-group-analyzer"></a>

Network Firewall can analzye stateless rule groups for rules that might adversely effect your firewall's functionality. For example, Network Firewall can identify rules that route traffic asymmetrically, which can impact the service's ability to properly process traffic. During analysis, the service includes any identfied rules in a list of analysis results. You can analyze your stateless rule groups and view the analysis results using the console or API.

------
#### [ Console ]

**To analyze a stateless rule group**

1. Sign in to the AWS Management Console and open the Amazon VPC console at [https://console.aws.amazon.com/vpc/](https://console.aws.amazon.com/vpc/).

1. In the navigation pane, under **Network Firewall**, choose **Network Firewall rule groups**.

1. During stateless rule group creation, after you add one or more rules to the rule group, if you select **Analyze**, Network Firewall analyzes the rules in the rule group. If the service determines that any of the rules have the behavior outlined in the following section, Network Firewall displays the identified rule's priority number and the type of identified behavior.

------
#### [ API ]

Include `AnalyzeRuleGroup` in your [CreateRuleGroupRequest](https://docs.aws.amazon.com/network-firewall/latest/APIReference/API_CreateRuleGroup.html), [DescribeRuleGroup](https://docs.aws.amazon.com/network-firewall/latest/APIReference/API_DescribeRuleGroup.html), or [UpdateRuleGroupRequest](https://docs.aws.amazon.com/network-firewall/latest/APIReference/API_DescribeRuleGroup.html) request. Network Firewall lists the results in `AnalysisResults` in the response.

To analyze the rule group without creating, describing, or updating the rule group, use the `DryRun` parameter.

------
#### [ CLI ]

Include `--analyze-rule-group` in your [create-rule-group](https://docs.aws.amazon.com/cli/latest/reference/network-firewall/create-rule-group.html), [describe-rule-group](https://docs.aws.amazon.com/cli/latest/reference/network-firewall/describe-rule-group.html), or [update-rule-group](https://docs.aws.amazon.com/cli/latest/reference/network-firewall/update-rule-group.html) request. Network Firewall lists the results in `AnalysisResults` in the response.

To analyze the rule group without creating, describing, or updating the rule group, use the `--dry-run` parameter.

------

The following table lists the types of rule behavior that Network Firewall analyzes your rule groups for, as well as the details about the cause and solution.


| Rule behavior | Cause | Mitigation | 
| --- | --- | --- | 
| Forwarding asymmetrically |  One or more stateless rules with the action `pass` or `forward` are forwarding traffic asymmetrically. Specifically, the rule's set of source IP addresses or their associated port numbers, don't match the set of destination IP addresses or their associated port numbers.  |  Make sure that there's an existing return path. For example, if the rule allows traffic from source 10.1.0.0/24 to destination 20.1.0.0/24, you should allow return traffic from source 20.1.0.0/24 to destination 10.1.0.0/24.  | 
| Contains TCP flags |  At least one stateless rule with the action `pass` or `forward` contains TCP flags that are inconsistent in the forward and return directions.  |  Prevent asymmetric routing issues caused by TCP flags by following these actions: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/network-firewall/latest/developerguide/stateless-rule-group-analyzer.html)  | 

# Defining rule actions in AWS Network Firewall
<a name="rule-action"></a>

The rule action setting tells AWS Network Firewall how to handle a packet that matches the rule's match criteria.

## Actions for stateless rules
<a name="rule-action-stateless"></a>

The action options for stateless rules are the same as for the firewall policy's default stateless rule actions. 

You are required to specify one of the following options: 
+ **Pass** – Discontinue all inspection of the packet and permit it to go to its intended destination. 
+ **Drop** – Discontinue all inspection of the packet and block it from going to its intended destination.
+ **Forward to stateful rules** – Discontinue stateless inspection of the packet and forward it to the stateful rule engine for inspection. 

Additionally, you can optionally specify a named custom action to apply. For this action, Network Firewall assigns a dimension to Amazon CloudWatch metrics with the name set to `CustomAction` and a value that you specify. For more information, see [AWS Network Firewall metrics in Amazon CloudWatch](monitoring-cloudwatch.md).

After you define a named custom action, you can use it by name in the same context as where you defined it. You can reuse a custom action setting among the rules in a rule group and you can reuse a custom action setting between the two default stateless custom action settings for a firewall policy. 

## Actions for stateful rules
<a name="rule-action-stateful"></a>

The actions that you specify for your stateful rules help determine the order in which the Suricata stateful rules engine processes them. Network Firewall supports the Suricata rule actions pass, drop, reject, and alert. By default, the engine processes rules in the order of pass action, drop action, reject action, and then finally alert action. Within each action, you can set a priority to indicate processing order. For more information, see [Managing evaluation order for Suricata compatible rules in AWS Network Firewall](suricata-rule-evaluation-order.md). 

Stateful rules can send alerts to the firewall's logs, if you have logging configured. To see the alerts, you must enable logging for the firewalls that use the rules. Logging incurs additional costs. For more information, see [Logging network traffic from AWS Network Firewall](firewall-logging.md). 

The options for stateful action settings vary by rule type. 

**Standard rules and Suricata compatible strings**  
You specify one of the following action options for both the rules that you provide in Suricata compatible strings and the rules that you specify using the standard stateless rules interface in Network Firewall. These options are a subset of the action options that are defined by Suricata. For more information, see [Working with stateful rule groups in AWS Network Firewall](stateful-rule-groups-ips.md).
+ **Pass** – Discontinue inspection of the matching packet and permit it to go to its intended destination. Rules with pass action are evaluated before rules with other action settings. 
+ **Drop** or **Alert**– Evaluate the packet against all rules with drop or alert action settings. If the firewall has alert logging configured, send a message to the firewall's alert logs for each matching rule. The first log entry for the packet will be for the first rule that matched the packet. 

  After all rules have been evaluated, handle the packet according to the the action setting in the first rule that matched the packet. If the first rule has a drop action, block the packet. If it has an alert action, continue evaluation.
+ **Reject** – Drop traffic that matches the conditions of the stateful rule and send a TCP reset packet back to sender of the packet. A TCP reset packet is a packet with no payload and a `RST` bit contained in the TCP header flags. `Reject` is available only for TCP traffic. This option doesn't support FTP and IMAP protocols.

**Note**  
Matching a `drop` or `alert` rule for a packet doesn't necessarily mean the end of rule processing for that packet. The engine continues evaluating other rules for matches. For example, if there's a `drop` match that drops a packet, the packet can still go on to match an `alert` rule that generates alert logs. Matching an `alert` rule also doesn't imply a `pass`. The packet can go on to match a `drop` rule, and drop the packet after it's previously matched an `alert` rule.

For information about what you can do to manage the evaluation order of your stateful rules, see [Managing evaluation order for Suricata compatible rules in AWS Network Firewall](suricata-rule-evaluation-order.md). 

**Domain lists**  
The domain list rule group has one action setting at the rule group level. You specify one of the following options: 
+ **Allow** – Indicates that the domain name list is to be used as an allow list for all traffic that matches the specified protocols. For matching packets, discontinue inspection of the packet and permit it to pass to its intended destination. For non-matching packets, discontinue inspection of the packet, block it from going to its intended destination, and send a message to the firewall's alert logs if the firewall has alert logging configured. 
+ **Deny** – Indicates that the domain name list is to be used as a deny list for traffic that matches the specified protocols. For matching packets, discontinue inspection of the packet, block it from going to its intended destination, and send a message to the firewall's alert logs if the firewall has alert logging configured. For non-matching packets, take no action. 

# Setting rule group capacity in AWS Network Firewall
<a name="nwfw-rule-group-capacity"></a>

AWS Network Firewall uses capacity settings to calculate and manage the processing requirements for its rules groups and firewall policies. Each rule group must have a capacity setting that's fixed at creation. When you reference a rule group from a firewall policy, Network Firewall reserves the rule group's capacity in the policy, increasing the total capacity that's used by the policy. 

Using the **consumed capacity** fields in the console, you can also describe a rule group or a policy to find out how much of the rule group or policy capacity is currently in use. 

For information about the maximum capacity settings for rule groups and firewall policies, see [AWS Network Firewall quotas](quotas.md). 

You can't change or exceed a rule group's capacity when you make changes to it, so when you set the rule group's capacity, leave room for it to grow. 

**Important**  
Network Firewall active threat defense managed rule groups have rule capacity limits that differ from the rule capacity limits that apply to other rule groups. For information, see [AWS active threat defense for AWS Network Firewall](aws-managed-rule-groups-atd.md)

## Stateless rule group capacity
<a name="nwfw-rule-group-capacity-stateless"></a>

Estimate a stateless rule group's capacity as the sum of the capacities of the rules that you expect to have in it. 

The capacity required for a single rule is the product of the complexity values of all of its match settings. 
+ A match setting with no criteria specified has a complexity value of 1. Through the console, the **All** and **Any** settings are equivalent to providing no criteria, and they have a complexity value of 1. 
+ A match setting with criteria specifications has a complexity value equal to the number of specifications in the setting. For example, a protocol specification set to `UDP` and a source specification set to `10.0.0.0/24` each have a value of 1. A protocol set to `UDP`, `TCP` has a value of 2 and a source set to `10.0.0.0/24`, `10.0.1.0/24`, `10.0.2.0/24` has a value of 3.

The following lists example calculations of stateless rule capacity requirements. 
+ A rule with protocol that specifies the two settings `UDP`, `TCP` and source with the three settings `10.0.0.0/24`, `10.0.1.0/24`, `10.0.2.0/24` and single or no specifications for the other match settings has a capacity requirement of 6. 
+ A rule with a protocol that specifies 30 different protocols, a source with 3 settings, and single or no specifications for the other match settings has a capacity requirement of 90.
+ A rule with a protocol that specifies 30 different protocols, a source with 3 settings, a destination with 5 settings, and single or no specifications for the other match settings has a capacity requirement of (30\$13\$15) = 450.

To calculate the capacity of a rule group, add the capacity requirements of all rules that you expect to have in the rule group during its lifetime. You can't change this setting after you create the rule group.

The maximum capacity setting for a stateless rule group is 30,000.

## Stateful rule group capacity
<a name="nwfw-rule-group-capacity-stateful"></a>

Estimate a stateful rule group's capacity as the number of rules that you expect to have in it during its lifetime. You can't change this setting after you create the rule group.

The maximum capacity setting for a stateful rule group is 30,000.