revisiting nat statelessness

stateless-nat | dmz-no-gateway

descr

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

setup

host config

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

guest skeleton

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>

guest network setup

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

inbound & outbound traffic with states OK

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

inbound traffic without states OK

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

outbound traffic without states NOK

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

resources

https://pub.nethence.com/network/netfilter.nat ==> casual nat settings

https://pub.nethence.com/network/learn-nat-part2 ==> previous diy-dnat,snat attempts

HOME | GUIDES | PLAYBOOKS | LECTURES | LAB | CONTACT | HTML | CSS
Licensed as MIT