stateless-nat | dmz-no-gateway
I wanted to check to what extend statelss nat can be used for inbound versus outbound initiated traffic, and for multiple internal hosts.
note we’re using kvm for this poc hence the 192.168.122.0/24 subnet instead of public addresses.
all the tests have been automated as an ansible playbook
we need two bridges for this poc. the default one is already up
brctl show virbr0 ifconfig virbr0
the internal one we need to build
brctl addbr dummybr0 ifconfig dummybr0 up
vi slack-1.xml <interface type='bridge'> <source bridge='dummybr0'/> <model type='virtio'/> </interface> vi slack-2.xml <interface type='bridge'> <source bridge='virbr0'/> <model type='virtio'/> </interface> <interface type='bridge'> <source bridge='dummybr0'/> <model type='virtio'/> </interface>
slack-1,3 (behind nat)
echo -n eth0 ... ifconfig eth0 10.1.1.1/24 up && echo done #ifconfig eth0 10.1.1.3/24 up && echo done echo -n default route 10.1.1.2 ... route add default gw 10.1.1.2 && echo done
slack-2 (nat gw)
echo -n eth0 ... ifconfig eth0 192.168.122.102/24 up && echo done echo -n eth1 ... ifconfig eth1 10.1.1.2/24 up && echo done echo -n default route ... route add default gw 192.168.122.1 && echo done # self-verbose sysctl -w net.ipv4.ip_forward=1 echo -n nftables ... nft -f /etc/nftables.conf && echo done
fail-safe test
eventually start-off with normal stateful DNAT and SNAT, just to check network settings
nothing fancy just yet – this is just the initial network settings acceptance
one-to-one see https://ansible.nethence.com/infra/test_stateless_nat/templates/nftables.casual.conf
one-to-many see https://ansible.nethence.com/infra/test_stateless_nat/templates/nftables.casual-many.conf
check inbound traffic
from workstation
nmap -p 22 192.168.122.102 ssh 192.168.122.102 -l root
we are not inherently interested in SNAT here, but we can take the chance to install tcpdump for that matter – check outbound traffic
from slack-1,3
ping 10.1.1.2 ping opendns.com slackpkg update slackpkg install tcpdump libcap-ng libpcap libnl3
the real deal
here’s the translation on the way in
1.2.3.4:1024 ==> 4.3.2.1:22 1.2.3.4:1024 ==> 10.1.1.1:22
and the answer goes
10.1.1.1:22 ==> 1.2.3.4:1024 4.3.2.1:22 ==> 1.2.3.4:1024
notice the src address isn’t mangled hence the target node needs a gateway (default route), in view to route its answer.
one-to-one see https://ansible.nethence.com/infra/test_stateless_nat/templates/nftables.stateless-nat.conf
check
from workstation
nmap -p 22 192.168.122.102 ssh 192.168.122.102 -l root
one-to-many see https://ansible.nethence.com/infra/test_stateless_nat/templates/nftables.stateless-nat-many.conf
check
from workstation
nmap -p 2201 192.168.122.102 nmap -p 2203 192.168.122.102 ssh 192.168.122.102 -l root -p 2201 ssh 192.168.122.102 -l root -p 2203
stateless-snat
here’s the translation on the way out (ICMP test is fine enough)
10.1.1.1 ==> 1.2.3.4 4.3.2.1 ==> 1.2.3.4
and the answer goes
1.2.3.4 ==> 4.3.2.1 10.1.1.2 ==> ???????
==> packet gets lost without a table to keep track of the originating internal source IP
https://pub.nethence.com/network/netfilter.nat ==> casual nat settings
https://pub.nethence.com/network/learn-nat-part2 ==> previous diy-dnat,snat attempts