---
title: 'Tutorial: Managing nftables Settings in Access Server'
canonical: https://openvpn.net/as-docs/v3/tutorials/tutorial--managing-nftables/
product: Access Server Docs
description: 'How to manage the nftables settings in Access Server: configure custom nftables rules.'
---

# Tutorial: Managing nftables Settings in Access Server

## Overview

This tutorial explains how to manage custom nftables rules alongside the firewall rules automatically generated by Access Server 3.1.0 and newer. It's intended for experienced Linux administrators who need behavior beyond what's configurable in the Admin Web UI.

Access Server uses nftables to manage packet filtering, NAT, and routing. While the default rules are sufficient for most deployments, advanced environments may require custom nftables tables or chains.

> **Important**
>
> This guide assumes your Access Server is configured to use nftables, which is the default for fresh installations as of version 3.1.0; however, you may have an older configuration that still uses iptables. If so, you may choose to switch to nftables by setting xtables=nftables in the as.conf configuration.

## Prerequisites

- An installed Access Server 3.1.0 or later.
- Console access and the ability to get root access.
- Basic knowledge of nftables and the Linux command line.

> **Note**
>
> In our documentation, we use example IPv4 addresses and subnets [reserved for documentation](https://en.wikipedia.org/wiki/Reserved_IP_addresses#IPv4), such as `192.0.2.0/24`, `198.51.100.0/24`, and `203.0.113.0/24`.
>
> Ensure you replace them with valid IPv4 addresses and subnets for your network(s).

## Step 1: Understand Access Server nftables behavior

When using **iptables**, Access Server prepends its rules to existing rules. Access Server places its generated rules before the existing iptables rules. With **nftables**, rule order is controlled via hooks and priorities defined on base chains.

By default, Access Server creates several nftables tables and base chains attached to Netfilter hooks with predefined priorities.

### Default Access Server nftables tables and chains

| **Table** | **Family** | **Chain** | **Type** | **Hook** | **Priority** |
| --- | --- | --- | --- | --- | --- |
| as\_filter | ip / ip6 | FORWARD | filter | forward | 0 |
|  |  | INPUT | filter | input | 0 |
|  |  | OUTPUT | filter | output | 0 |
| as\_nat | ip / ip6 | PREROUTING | nat | prerouting | -100 |
|  |  | POSTROUTING | nat | postrouting | 100 |
| as\_mangle | ip / ip6 | PREROUTING | filter | prerouting | -150 |
|  |  | POSTROUTING | filter | postrouting | -150 |

## Step 2: View existing nftables rules

1. Connect to the console and get root privilege.
2. List the full nftables ruleset:

   ```
   nft --numeric list ruleset
   ```
3. List a specific table (for example, the `as_filter` table):

   ```
   nft --numeric list table ip as_filter
   ```
4. List a specific chain (for example, the `FORWARD` chain under `as_filter`):

   ```
   nft --numeric list chain ip as_filter FORWARD
   ```

## Step 3: Create a custom nftables table and chain (recommended approach)

If you want to add custom nftables rules, the recommended approach is to create your own table and chain, using a hook and priority that determine when your rules are evaluated relative to Access Server’s rules.

> **Important**
>
> - Custom table and chain names must not conflict with Access Server–generated names.
> - Custom tables must use the `ip` or `ip6` family. Other families aren't supported.
> - Choose priorities carefully to avoid unexpected rule ordering.

For our example, we create a custom FORWARD rule evaluated before Access Server rules. Traffic destined for `192.0.2.5` is accepted before Access Server's `FORWARD` rules by configuring it with a priority lower than the default (such as 0).

1. Connect to the server and get root privileges.
2. Create a custom table:

   ```
   nft add table ip brandonfilter
   ```
3. Create a base chain with an earlier priority:

   ```
   nft add chain ip brandonfilter FORWARD_EARLY '{ type filter hook forward priority -100; policy accept; }'
   ```

   > **Tip**
   >
   > This creates a chain called `FORWARD_EARLY` under the `brandonfilter` table with `hook` `forward` and `priority` -100.
4. Add a rule to the chain:

   ```
   nft add rule ip brandonfilter FORWARD_EARLY ip daddr 192.0.2.5 counter accept
   ```
5. Verify the configuration:

   ```
   nft --numeric list table ip brandonfilter
   nft --numeric list chain ip brandonfilter FORWARD_EARLY
   ```

   - Example output:

     ```
     root@openvpnas:~# nft --numeric list table ip brandonfilter
     table ip brandonfilter {
             chain FORWARD_EARLY {
                     type filter hook forward priority -100; policy accept;
                     ip daddr 192.0.2.5 counter packets 0 bytes 0 accept
             }
     }
     root@openvpnas:~#
     root@openvpnas:~#
     root@openvpnas:~# nft -n list chain ip brandonfilter FORWARD_EARLY
     table ip brandonfilter {
             chain FORWARD_EARLY {
                     type filter hook forward priority -100; policy accept;
                     ip daddr 192.0.2.5 counter packets 0 bytes 0 accept
             }
     }
     ```

## Understanding chain priority and rule evaluation

- If a packet is accepted, and another base chain with the same hook but a later priority exists, the packet continues to traverse subsequent chains.
- A drop verdict takes immediate effect and stops further evaluation.
- An accept verdict in an earlier chain can be overridden by a later drop rule in another chain.

For more information, refer to [nftables chain priority](https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains#Base_chain_priority).

### Example: Accept overridden by a later drop

If a packet is accepted by a rule and there is another base chain within the same hook with a later priority that matches and drops the packet, the packet is dropped.

```
root@openvpnas:~# nft --numeric list table ip brandonfilter
table ip brandonfilter {
        chain FORWARD_EARLY {
                type filter hook forward priority -100; policy accept;
                ip daddr 192.0.2.5 counter packets 15 bytes 900 accept
        }

        chain FORWARD_LATER {
                type filter hook forward priority 100; policy accept;
                ip daddr 192.0.2.0/24 counter packets 4 bytes 240 drop
        }
}
```

In this case, traffic to `192.0.2.5` is still dropped due to the later chain.

### Correct approach: Order rules within the same chain

In this example, you allow `192.0.2.5` and deny the rest of the traffic from `192.0.2.0/24`. Configure the drop rule within the same chain as the accept rule:

```
root@openvpnas:~# nft --numeric list table ip brandonfilter
table ip brandonfilter {
        chain FORWARD_EARLY {
                type filter hook forward priority -100; policy accept;
                ip daddr 192.0.2.5 counter packets 11 bytes 660 accept
                ip daddr 192.0.2.0/24 counter packets 0 bytes 0 drop
```

## Adding custom rules to Access Server-generated tables (not recommended)

Although not recommended, it's possible to insert custom rules directly into tables and chains created by Access Server.

> **Warning**
>
> Custom rules inside Access Server-generated rulesets may be overwritten or affected by upgrades and service restarts.

**Example: Add a custom rule to the Access Server FORWARD chain:**

1. Connect to the console and get root privileges.
2. Stop Access Server services:

   ```
   systemctl stop openvpnas
   ```
3. Recreate the table and chain:

   ```
   nft add table ip as_filter
   nft add chain ip as_filter FORWARD '{ type filter hook forward priority 0; policy accept; }'
   ```
4. Add the custom rule to allow `192.0.2.10`:

   ```
   nft add rule ip as_filter FORWARD ip daddr 192.0.2.10 counter accept
   ```
5. Verify the rule:

   ```
   nft list chain as_filter FORWARD
   ```

   - Example output:

     ```
     root@openvpnas:~# nft list chain as_filter FORWARD
     table ip as_filter {
             chain FORWARD {
                     type filter hook forward priority 0; policy accept;
                     ip daddr 192.0.2.10 counter packets 0 bytes 0 accept
             }
     }
     ```
6. Start Access Server services:

   ```
   systemctl start openvpnas
   ```
7. Confirm rules after restart:

   ```
   nft list chain as_filter FORWARD
   ```

   > **Tip**
   >
   > Ensure that both your custom rule and the Access Server-generated rules are present.

   - Example output:

     ```
     root@openvpnas:~# nft list chain as_filter FORWARD
     table ip as_filter {
             chain FORWARD {
                     type filter hook forward priority filter; policy accept;
                     ip daddr 192.0.2.10 counter packets 0 bytes 0 accept
                     counter packets 3663 bytes 1369591 ct state established,related jump AS_ACCEPT
                     counter packets 206 bytes 86602 meta mark & 0x02000000 == 0x02000000 jump AS_IN_PRE
                     counter packets 0 bytes 0 oifname "as0t*" jump AS_OUT_S2C
             }
     }
     ```

## Summary

- Access Server uses nftables hooks and priorities to control rule evaluation.
- Creating custom tables and chains is the safest and recommended approach.
- Direct modification of Access Server-generated rulesets should be avoided unless absolutely necessary.
- Always verify rule behavior carefully, especially when mixing accept and drop rules across priorities.

---

Prev: [Tutorial: Setting Up Zero Trust Network Access (ZTNA) with Access Server](https://openvpn.net/as-docs/v3/tutorials/tutorial--zero-trust-network-access--ztna.md)
Next: [Cloud and Multi-VPC Networking](https://openvpn.net/as-docs/v3/tutorials/cloud-and-multi-vpc-networking.md)
Index: https://openvpn.net/as-docs/llms.txt
