2

The following picture shows the topology of my network. Schmatic I now want to route all http traffic from 10.8.0.15 via 10.8.0.42 to the outside world, using wlan0. Unfortunately, I am a noob when it comes to iptables and routing. Can anyone point me into the right direction?

Edit: So far I executed the following commands on 10.8.0.15

sudo ip rule add fwmark 2 table 3
sudo ip route add default via 10.8.0.42 table 3
sudo ip route flush cache
sudo iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 2
sudo iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 10.8.0.15
sudo sysctl -w net.ipv4.conf.eth0.rp_filter=2
sudo iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination 10.8.0.42

and the following on 10.8.0.42

sudo iptables -I FORWARD -i eth0 -o wlan0 -s 10.8.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -I FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo sysctl -w net.ipv4.ip_forward=1

when I now want to test the connection on 10.8.0.15 I get the following

curl http://freegeoip.net/json/
curl: (7) Failed to connect to freegeoip.net port 80: Connection refused

and a tcpdump on 10.8.0.42 shows

sudo tcpdump -n -i eth0 -s 0 src or dst port 80
10:05:18.552329 IP 10.8.0.15.36186 > 10.8.0.42.80: Flags [S], seq 460236380, win 29200, options [mss 1308,sackOK,TS val 22927 ecr 0,nop,wscale 6], length 0
10:05:18.552612 IP 10.8.0.42.80 > 10.8.0.15.36186: Flags [R.], seq 0, ack 460236381, win 0, length 0
10:05:19.068397 IP 10.8.0.15.50052 > 10.8.0.42.80: Flags [S], seq 2824330189, win 29200, options [mss 1308,sackOK,TS val 22969 ecr 0,nop,wscale 6], length 0
10:05:19.068674 IP 10.8.0.42.80 > 10.8.0.15.50052: Flags [R.], seq 0, ack 2824330190, win 0, length 0

The purpose of this setup is to use an arbitrary client within the network as internet gateway. While in the diagram there is only 10.8.0.42, there are potentially multiple such clients each with their own dedicated internet access which might be used by other clients.

Update: I now tested the following configuration as suggested below.

box0:

sudo ip route add default via 10.8.0.42 dev tun0 table 3
sudo ip rule add fwmark 2 table 3
sudo ip route flush cache
sudo iptables -A OUTPUT -t mangle -p tcp --dport 80 -j MARK --set-mark 2
sudo sysctl -w net.ipv4.conf.eth0.rp_filter=0
sudo iptables -A POSTROUTING -t nat -o eth0 -p tcp --dport 80 -j SNAT --to-source 10.8.0.15
sudo iptables -A POSTROUTING -t nat -o eth0 -p tcp --dport 443 -j SNAT --to-source 10.8.0.15

box1:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A POSTROUTING -t nat -s 10.8.0.0/24 -p tcp --dport 80 -j SNAT --to-source 192.168.0.2
sudo iptables -A POSTROUTING -t nat -s 10.8.0.0/24 -p tcp --dport 443 -j SNAT --to-source 192.168.0.2

The tcpdump output on box1 remains the same:

12:24:05.788127 IP 10.8.0.15.45844 > 10.8.0.42.80: Flags [S], seq 4169666416, win 29200, options [mss 1308,sackOK,TS val 15420789 ecr 0,nop,wscale 6], length 0
12:24:05.788414 IP 10.8.0.42.80 > 10.8.0.15.45844: Flags [R.], seq 0, ack 4169666417, win 0, length 0
12:24:06.786406 IP 10.8.0.15.45844 > 10.8.0.42.80: Flags [S], seq 4169666416, win 29200, options [mss 1308,sackOK,TS val 15420889 ecr 0,nop,wscale 6], length 0
12:24:06.786694 IP 10.8.0.42.80 > 10.8.0.15.45844: Flags [R.], seq 0, ack 1, win 0, length 0
12:24:08.789821 IP 10.8.0.15.45844 > 10.8.0.42.80: Flags [S], seq 4169666416, win 29200, options [mss 1308,sackOK,TS val 15421089 ecr 0,nop,wscale 6], length 0
12:24:08.790111 IP 10.8.0.42.80 > 10.8.0.15.45844: Flags [R.], seq 0, ack 1, win 0, length 0

The tcpdump output on box0:

11:26:14.220391 IP 10.8.0.15.33420 > 158.69.242.138.80: Flags [S], seq 2659446178, win 29200, options [mss 1460,sackOK,TS val 15433635 ecr 0,nop,wscale 6], length 0
11:26:14.308915 IP 10.8.0.42.80 > 10.8.0.15.33420: Flags [R.], seq 0, ack 2659446179, win 0, length 0
11:26:15.211761 IP 10.8.0.15.33420 > 158.69.242.138.80: Flags [S], seq 2659446178, win 29200, options [mss 1460,sackOK,TS val 15433735 ecr 0,nop,wscale 6], length 0
11:26:15.337652 IP 10.8.0.42.80 > 10.8.0.15.33420: Flags [R.], seq 0, ack 1, win 0, length 0

I guess the main issue is that the destination for the tcp packets is 10.8.0.42 when it arrives at box1 instead of whatever the IP of the URL (here: 158.69.242.138) of the http request is. But I cannot see where this destination is altered.

Coxer
  • 187
  • 1
  • 14
  • Show us what you've tried thus far. – EEAA Oct 05 '16 at 12:42
  • I added my current configuration and some output – Coxer Oct 05 '16 at 13:07
  • You don't need any iptables configuration on `10.8.0.15`. You need to only make sure your route is set correctly. – Tero Kilkanen Oct 05 '16 at 13:16
  • Could you give me an example, how? – Coxer Oct 05 '16 at 13:18
  • Have you set `net.ipv4.ip_forward=1` on the 10.8.0.42 host? Without it, the host won't accept/route any traffic that isn't targeted at itself. That's why you're getting a connection refused response. – André Fernandes Oct 11 '16 at 16:07
  • It would help if you could tell us what the purpose of this setup is, do you have any special requirements so that a plain router/NAT or a proxy setup isn't desired? – André Fernandes Oct 11 '16 at 16:10
  • @AndréFernandes I clarified this bit in the above question and yes, ip_forwarding is enabled on 10.8.0.42 – Coxer Oct 11 '16 at 16:49
  • It seems you have two gateways, 10.8.0.1 and 10.8.0.42, and a client. And you want to make the routing decision on the client. It can be done but to me it does not "feel right", as you have to do this for every other client. Is my understanding right? – Fredi Oct 12 '16 at 16:42
  • What is the objective you are trying to achieve here? Are you trying to have a separate box do transparent HTTP caching/content filter? If so, are the machines direct wired as depicted in the diagram, or do you have them connected to a switch? – mdadm Oct 13 '16 at 03:09
  • @mdadm they are connected to a switch. The objective is to use box1's internet access instead of box2's for HTTP(S) traffic – Coxer Oct 13 '16 at 09:50

2 Answers2

1

To me it looks like you want the host with eth0 and wlan0 interface to do SNAT on http traffic originating from devices in the network where eth0 is connected to.

You can do it this way:

On host 10.8.0.15, you set up 10.8.0.42 as the default gateway:

ip route add default via 10.8.0.42 dev eth0

On host 10.8.0.42, you enable SNAT:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -p tcp --dport 80 -j SNAT --to-source 192.168.0.2
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -p tcp --dport 443 -j SNAT --to-source 192.168.0.2

This enables NAT for ports 80 and 443, that is http and https. You can add further ports. If you want DNS resolved via the same path, you need to add a rule for it etc.

If you want to get all traffic routed via that interface, you can simply use:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source 192.168.0.2

EDIT: Added info reflecting the updated question:

These lines from your question should make the client devices route http/https traffic to the other gateway:

sudo ip rule add fwmark 2 table 3
sudo ip route add default via 10.8.0.42 table 3
sudo ip route flush cache
sudo iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark 2

EDIT: The routing on the client device can be handled with instructions given in this answer: https://unix.stackexchange.com/questions/21093/output-traffic-on-different-interfaces-based-on-destination-port#21118

Basically it is the same as in your question, except for the last DNAT rule which isn't needed.

Tero Kilkanen
  • 36,796
  • 3
  • 41
  • 63
  • Is there a way to only route http and https traffic to 10.8.0.42? – Coxer Oct 12 '16 at 10:04
  • I assumed `10.8.0.42` to be the only gateway in your network, because you gave no other information on the network setup. Therefore you can only allow SNAT for those ports in the gateway. If your network setup is different, please update your question. – Tero Kilkanen Oct 12 '16 at 10:09
  • It reads at the bottom of the question, last paragraph. – Coxer Oct 12 '16 at 10:19
  • It doesn't tell if every device on the network has a default gateway other than the one you have in your picture. So, the question is: "Is there a default route in every device on the network?" – Tero Kilkanen Oct 12 '16 at 10:25
  • I updated the diagram in the question. – Coxer Oct 12 '16 at 10:38
  • I tested the configuration you suggested and it all makes sense, theoretically. I posted the outputs and the used configuration in an update on the original question. – Coxer Oct 14 '16 at 10:29
  • The tcpdump output on `box1` shows that the destination address for the packet is `box1` IP address. That is wrong, the address should be the original destination as shown in box0 tcpdump output. Are you sure there are no DNAT rules left in box0 configuration? – Tero Kilkanen Oct 14 '16 at 10:32
  • The iptables output chain is configured like this: `Chain OUTPUT (policy ACCEPT 15 packets, 966 bytes) pkts bytes target prot opt in out source destination` which means that there should not be a DNA, right? – Coxer Oct 14 '16 at 10:35
  • Okay, for some random reason, there was a non-persistent DNAT rule in place which was fixed by a simple reboot. Thanks! Your solution works like a charm! – Coxer Oct 14 '16 at 10:53
0

The Rule sudo iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination 10.8.0.42 will redirect all the http trafic to 10.8.0.42 (has destination), not through 10.8.0.42 (routing to). As you can see in the tcpdump, the server 10.8.0.42 don't accept connections on port 80.

You can remove this rule.

a0f3dd13
  • 101
  • 1