Forward http traffic to another ip address with iptables
We want to forward all http traffic to another IP address on an Amazon EC2 stock Linux machine (CentOS based). I know how to do this with proxy rules and apache, but I was assuming iptables would be a much faster solution (perhaps not!)
Commands
sudo iptables -P INPUT ACCEPT sudo iptables -F sudo iptables -A PREROUTING -t nat -p tcp -i eth0 --dport 80 -j DNAT --to 208.68.208.81:80 sudo iptables -A FORWARD -p tcp -d 208.68.208.81 --dport 80 -j ACCEPT
iptables -t nat -L -v -n
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- eth0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:208.68.208.81:80 Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 11 packets, 820 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 11 packets, 820 bytes) pkts bytes target prot opt in out source destination
iptables -L -v -n
Chain INPUT (policy ACCEPT 202 packets, 15705 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 208.68.208.81 tcp dpt:80 Chain OUTPUT (policy ACCEPT 145 packets, 13747 bytes) pkts bytes target prot opt in out source destination
http://208.68.208.81 into a web browser works, but when I try the ip address of the EC2 machine with this config I get a timeout. I do see some packets show up with watch -d iptables -t nat -L -v -n
Help!
Update: added -i eth0
to PREROUTING rule
Solution 1:
There are three potential problems I see (contary to the other answer I don't see anything that would cause a "loop" even in the unedited version of your question).
- IP forwarding must be enabled.
- After being natted and placed back on the network the packet may fall victim to source address filtering as it looks very much like a spoofed packet.
- Responses to packets that go through a NAT must go through the same NAT so the reverse translation can be performed. Otherwise the client will get a response with the wrong source IP/port which it is likely to drop (if it has not already been dropped by reverse path filtering).
You can work arround points 2 and 3 by using a SNAT or MASQURADE rule in addition to the DNAT but if you do that then you lose the original source IP of the traffic. That will make abuse control very difficult.
Another soloution to points 2 and 3 would be to set up a VPN between the two servers. Then use DNAT to forward traffic over the VPN and source IP based routing to bring the replies back to the NAT.
Solution 2:
You may use rinetd to simply forward your ip traffic.
Solution 3:
You have created a loop. Make sure you add the in interface to the PREROUTING
rule (eg. -i eth1
or whatever).
You may also need a rule like this:
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
45M 3723M MASQUERADE all -- * WAN_IF 0.0.0.0/0 0.0.0.0/0
Otherwise the packets will go directly from the machine they were forwarded to back to the client, I think, which will not be expecting them from that host.