I'm trying to transparently route traffic of one Xen VM through another, like so:

-------     ---------
| 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 ! -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 (

vm2:~# iptables -t nat -L -n
target     prot opt source               destination
# route outgoing udp traffic
DNAT       udp  -- !           udp dpt:!80 to:
# route outgoing tcp traffic
DNAT       tcp  -- !           tcp dpt:!80 to:
# this is the working squid rule
REDIRECT   tcp  --             tcp dpt:80 redir ports 3128

target     prot opt source               destination
# route incoming traffic
SNAT       all  --         to: 

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 -j DNAT --to-destination iptables -t nat -I POSTROUTING -s -j SNAT --to-source

  • Makes perfect sense, but that didn't work. VM1 still cannot connect to any IP/port outside 192.168.250.* - not even ping. I added a "-j LOG" rule and when doing wget from VM1, VM2's stdout says IN= OUT=eth0 SRC= DST= LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=50447 DF PROTO=TCP SPT=2133 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0. Looks like the outgoing SYN - but no other packets (like incoming packets) get logged. Do I need anything else than /proc/sys/net/ipv4/ip_forward = 1?? – AndiDog Jan 26 '10 at 10:05
  • OK I answered my own question. The problem about your solution was that SNAT must rewrite the source IP to the external IP, not the internal IP ( Thanks for the help, +1 – AndiDog Jan 26 '10 at 13:47
  • Great, glad you got it working. – Scott Forsyth - MVP Jan 26 '10 at 14:18

I finally found the correct way to do it:

NAT-ing outgoing connections (VM1 --> Internet/intranet) works with source rewriting (SNAT):

iptables -t nat -A POSTROUTING -s -j SNAT --to-source

where 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:

iptables -t nat -A POSTROUTING -s -j MASQUERADE

The final iptables config now looks like this (other tables/chains are empty):

target     prot opt source               destination

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.