Connection Tracking and UDP DNS with nftables

I’m working with nftables lately, here’s an example for disabling connection tracking of UDP DNS packets with it. Nftables is a replacement for iptables, ip6tables, arptables and ebtables – and once you get used to it does a pretty nice job.

Creating the tables and chains

In nftables you have to create the tables first. Unlike with iptables which does come with basic tables and chains pre-created. For the following I am assuming that you do have a table filter and raw. The raw table contains the chains prerouting and output, the filter table contains the chain input.

#!/usr/sbin/nft -f
 
#
# create tables
#
 
add table inet raw
add table inet filter
 
#
# create chains
#
 
add chain inet raw prerouting { type filter hook prerouting priority -300; policy accept; }
add chain inet raw output { type filter hook output priority -300; policy accept; }
add chain inet filter input { type filter hook input priority 0; policy accept; }

Creating the rules

The rules to accomplish the same I did with iptables are:

#
# Bypassing connection tracking for UDP DNS
#
 
add rule inet raw prerouting udp dport 53 notrack
add rule inet raw prerouting udp sport 53 notrack
add rule inet raw output udp dport 53 notrack
add rule inet raw output udp sport 53 notrack

To accept these packets the input chain will need a rule like this:

add rule inet filter input ct state untracked counter accept

Alternatively you might want to be more restrictive and instead of the above rule you just allow port 53 udp packets:

add rule inet filter input udp dport 53 counter accept

If you continue to use connection tracking for your TCP DNS packets:

add rule inet filter input tcp dport 53 ct state new counter accept

By the way: I do assume that the input chain has a drop policy, though that requires additional rules. So to actually enforce the above rule you’ll need to drop / reject further packets to port 53:

add rule inet filter input udp dport 53 counter drop
add rule inet filter input tcp dport 53 counter drop

Full example

Putting it altogether it might look like this:

#!/usr/sbin/nft -f
 
flush ruleset
 
#
# setting up the tables
#
 
add table inet raw
add table inet filter
 
#
# setting up the chains
#
 
add chain inet raw prerouting { type filter hook prerouting priority -300; policy accept; }
add chain inet raw output { type filter hook output priority -300; policy accept; }
# don't use drop here except you absolutely know what you're doing.
add chain inet filter input { type filter hook input priority 0; policy accept; }
 
#
# Bypassing connection tracking for UDP DNS
#
 
add rule inet raw prerouting udp dport 53 notrack
add rule inet raw prerouting udp sport 53 notrack
add rule inet raw output udp dport 53 notrack
add rule inet raw output udp sport 53 notrack
 
#
# inbound rules
#
 
# accept localhost in general
add rule inet filter input iif lo accept
 
# generic connection tracking rules
add rule inet filter input ct state related,established counter accept
add rule inet filter input ct state invalid counter drop
 
# dns
add rule inet filter input udp dport 53 counter accept
add rule inet filter input udp sport 53 counter accept
add rule inet filter input tcp dport 53 ct state new counter accept
add rule inet filter input tcp sport 53 ct state new counter accept
add rule inet filter input udp dport 53 counter reject
add rule inet filter input tcp dport 53 counter reject
 
# allow access to port 22
add rule inet filter input tcp dport 22 ct state new counter accept
add rule inet filter input tcp dport 22 counter reject

In case nftables is not for you, take a look at iptables here

No Comments

Post a Comment