Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have several servers that need to connect to a remote service. These servers are ec2 instances under my control. The remote service is run on a server managed by my company, but not my department, and I'm not sure where it is hosted. For security reasons, the remote service will only allow a single IP address (it's an AWS elastic IP) on a specific port to access the service, so all the requests will have to be through the proxy. I've looked up several examples of how to accomplish this, and tried many different alterations, and none seem to work. I tried to create the rules based on my knowledge of iptables, and came up with exactly what I already had (which still doesn't work). I hope someone can help me get this working quickly.

$ cat /proc/sys/net/ipv4/ip_forward


-A PREROUTING -d $proxy_ip/32 -p tcp -m tcp --dport $remote_server_port -j DNAT --to-destination $remote_server_ip:$remote_server_port
-A POSTROUTING -d $remote_server_ip/32 -p tcp -m tcp --dport $remote_server_port -j SNAT --to-source $proxy_ip
# Completed on Mon Sep 17 17:28:07 2012
# Generated by iptables-save v1.4.12 on Mon Sep 17 17:28:07 2012
:OUTPUT ACCEPT [1376:205512]
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 3 --name DEFAULT --rsource -j DROP
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -p tcp -m tcp --dport $remote_server_port -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
# Completed on Mon Sep 17 17:28:07 2012

Bonus points for anyone that can tell me what is wrong with my two rate limit rules on ssh, which also aren't working.

share|improve this question
The rules on your forward chain seem to be devoid of an state tracking, are you sure you shouldn't also have bits to permit stateful traffic? – Zoredache Sep 19 '12 at 17:59
I figured for now I would leave it less restrictive and just allow anything on that port regardless of state. But I'm not an expert with iptables. I tried changing it to -A FORWARD -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT but that didn't help. – Brandon Sep 19 '12 at 19:47
up vote 0 down vote accepted

So I feel kind of stupid now, but I know what my problem was. I'll share it here for historical purposes.

These rules actually work, it's just my testing methodology was broken. I'm forwarding MS SQL from a cluster to a remote DB. But I can't actually test it's working because the only IP address allowed to hit the remote DB is being used by a single server that isn't proxying other requests, and it's in production. So I've been trying to use curl to hit another web server through the proxy and see if I get a response. Then I could just switch the IP addresses and ports around and it would hopefully work.

But my problem was the rule

-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT

was catching all the responses coming in and not forwarding them. Once I realized that, I commented out this rule and everything worked. And since in production, it will be a completely different port, this rule wont negatively effect the proxy.

Thanks to anyone that spent any time trying to figure out my mistake.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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