I'm trying to transparently route traffic of one Xen VM through another, like so:
------- 192.168.250.4 192.168.250.3 ---------
| VM1 | <-----------------bridged----------------> | VM2 | <-----> Internet
------- | with |
| squid |
| proxy |
---------
Don't ask why, just experimenting with iptables. I'm able to successfully route HTTP traffic through VM2's Squid proxy (transparent mode) with
iptables -t nat -A PREROUTING -p tcp --dport 80 –s ! 192.168.250.3 -j REDIRECT --to-port 3128
but how can I simply pass through all other traffic? Already tried this config but it gives me "Connection refused" errors when trying to access the Internet from VM1 (192.168.250.4
):
vm2:~# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
# route outgoing udp traffic
DNAT udp -- !192.168.250.3 0.0.0.0/0 udp dpt:!80 to:192.168.250.3
# route outgoing tcp traffic
DNAT tcp -- !192.168.250.3 0.0.0.0/0 tcp dpt:!80 to:192.168.250.3
# this is the working squid rule
REDIRECT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 redir ports 3128
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
# route incoming traffic
SNAT all -- 0.0.0.0/0 192.168.250.3 to:192.168.250.4
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
What is wrong here? I already read lots of tutorials but most don't work properly... (BTW: /proc/sys/net/ipv4/ip_forward
is 1)
Rather than using REDIRECT, try DNAT and SNAT. Try this:
iptables -t nat -I PREROUTING -d 192.168.250.3 -j DNAT --to-destination 192.168.250.4 iptables -t nat -I POSTROUTING -s 192.168.250.4 -j SNAT --to-source 192.168.250.3
I finally found the correct way to do it:
NAT-ing outgoing connections (VM1 --> Internet/intranet) works with source rewriting (SNAT):
where
192.168.2.125
is the current external IP of VM2 (must not be the internal address). As that IP is assigned by DHCP in my case, the rule must be changed to do SNAT on the dynamic IP. This is done by the MASQUERADE command:The final iptables config now looks like this (other tables/chains are empty):