nftables NAT
Finally getting around to writing the continuation of this howto. Now lets take a look at a basic router firewall.
Basic ruleset configuration is described here.
This ruleset only sets up ipv4 nating, no filtering is set up (that will be covered later)
The following is an nft configuration file. To be loaded with nft -f.
On the first line, I define the $if_wan variable to the output interface which is used throughout the ruleset. Note that it is used alongside "iif", which matches interfaces based on interface indexes (as oposed to iifname, which matches by comparing with the name string). This implies that by using iif, the interface has to exist before I load the rules (when using iifname, the interface can be created later).
Then I define an ipv4 specific table (the "ip" part in the table definition means ipv4).
Then I define two maps, which will be used for forwarding ports to hosts, all of which can be specified at runtime. One for UDP, one for TCP.
Next up is the basic input chain, where I accept all ICMP (to not break the internet - like when MTU clamping is needed) and all packets related to outgoing connections.
Finally I declare the prerouting and postrouting chains, which take care of all NAT related things.
Are two rules for NAT forwarding, the first being set statically (ports 222, 280 and 243 redirected to 172.18.0.5. This could also be rewritten like
creates a dynamic natting rule, meaning port forwarding can be added without reloading the ruleset.
Dynamically adding NAT forwarding can be done with
Big thanks to those who wrote the nftables wiki content.
Basic ruleset configuration is described here.
This ruleset only sets up ipv4 nating, no filtering is set up (that will be covered later)
The following is an nft configuration file. To be loaded with nft -f.
Code:
define if_wan = eth0 table ip filter { map tcp_nat_map {type inet_service : ipv4_addr;} map udp_nat_map {type inet_service : ipv4_addr;} chain input { type filter hook input priority 2; ip protocol icmp accept comment "Accept all icmp" } chain prerouting { type nat hook prerouting priority -100; iif $if_wan dnat tcp dport map {50001 : 172.18.0.5, 50932 :172.18.0.5, 56764 :172.18.0.5 } iif $if_wan dnat tcp dport map @tcp_nat_map iif $if_wan dnat udp dport map @udp_nat_map } chain postrouting { type nat hook postrouting priority -100; oif $if_wan masquerade random #NAT only on WAN interface } }
Then I define an ipv4 specific table (the "ip" part in the table definition means ipv4).
Then I define two maps, which will be used for forwarding ports to hosts, all of which can be specified at runtime. One for UDP, one for TCP.
Next up is the basic input chain, where I accept all ICMP (to not break the internet - like when MTU clamping is needed) and all packets related to outgoing connections.
Finally I declare the prerouting and postrouting chains, which take care of all NAT related things.
Code:
iif $if_wan dnat tcp dport map { 222 : 172.18.0.5, 280 : 172.18.0.5, 243 : 172.18.0.5}
Code:
iif $if_wan tcp dport {222, 280, 243 } dnat 172.18.0.5
Code:
iif $if_wan dnat tcp dport map @tcp_nat_map
Dynamically adding NAT forwarding can be done with
Code:
nft add element ip filter tcp_nat_map { $PORT : $ADDRESS }
Total Comments 0