1

I have a raspberry pi with two interfaces:

  • wlan0
  • eth0

wlan0 is connected to my internal network 192.168.2.0/24. eth0 is connected to a network switch with a LAN network 10.0.0.0/8.

Currently I have all traffic in the LAN 10.0.0.0/8 able to use Internet via my wlan0 interface, and I am able to connect to any machines in the 10.0.0.0/8 network from the raspberry pi. E.g. ssh into 10.0.0.2.

  • The raspberry pi wlan0 interface has IP address 192.168.2.30.
  • The raspberry pi eth0 interface has IP address 10.0.0.1.

I have configured this by enabling IP forwarding with net.ipv4.ip_forward=1.

I then added the following iptables rules:

sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo iptables -A FORWARD -i wlan0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o wlan0 -j ACCEPT

However, I now need to be able to intercept traffic hitting the wlan0 interface on port 80 or port 443 (from the other side, (192.168.0.2/24) and route it directly to another IP address on the LAN that this raspberry pi is connected to (10.23.220.88).

This is my current iptables filter table:

pi@something:~ $ sudo iptables -L -n -v --line-numbers
Chain INPUT (policy ACCEPT 48847 packets, 20M bytes)
num   pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 157 packets, 9952 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     319K  467M ACCEPT     all  --  wlan0  eth0    0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
2     161K   12M ACCEPT     all  --  eth0   wlan0   0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 26150 packets, 18M bytes)
num   pkts bytes target     prot opt in     out     source               destination

and this is my iptables current NAT table:

pi@something:~ $ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

How can I achieve this without disturbing the fact that I am routing internet through this raspberry pi to my 10.0.0.0/8 network, and the fact that I can connect into the 10.0.0.0/8 network?

1

That one is easy. Just add:

iptables -t nat -A PREROUTING -p tcp -d 192.168.2.X --dport 80 -jDNAT --to-destination 10.23.220.88:80
iptables -t nat -A PREROUTING -p tcp -d 192.168.2.X --dport 443 -jDNAT --to-destination 10.23.220.88:443

Where X is last byte from your wlan0 IP.

If you want to have a specific source (somebody specific from your wlan0 network) you just add --source 192.168.2.Y where Y is the last byte from the IP of that machine in the network.

  • Thanks for this @Zatarra, it got me half way there, but I also needed a POSTROUTING rule to modify the packet's original source address to repoint it to my pi router performing the NAT. I've added the extra detail and rule I required as another answer below, but upvoted your answer for getting me half way there. Much appreciated. – Shogan yesterday
0

Zatarra's answer got me half of the way there, but after trying it out and having no luck, I went and did some refresh reading on how NAT works and realised that I still needed a POSTROUTING (SNAT) rule to make sure the source address of the packet is changed from the original HTTP client's address to the address of the raspberry pi router (which is performing the NAT).

This way the raspberry pi router receives the packet back from the 10.23.220.88 host on it's eth0 interface (10.0.0.1) and then knows that it should actually go back again from there via wlan0 to the original HTTP client on the 192.168.2.0/24 network.

So I needed the PREROUTING rule that Zatarra mentioned, but also needed the SNAT / POSTROUTING rule.

So the solution for me ended up being a combination:

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 10.23.220.88:80
sudo iptables -t nat -A POSTROUTING -p tcp -d 10.23.220.88 --dport 80 -j SNAT --to-source 10.0.0.1

Repeat of course for port 443 too.

I found these two articles great to explain the whole iptables process and refresh my memory on how NAT works:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.