Port forwarding for iptables (DMZ)

Posted by Steve on Fri 7 Jan 2005 at 10:52

If you have a network gateway which is running Linux you might sometimes want to allow access to machines behind it from the internet.

This is simple enough to do with iptables, which you will probably be using for the gateway's normal operation anyway.

Normally you'd deny all incoming connections to a gateway machine as opening up services and ports could be a security risk.

If you have a gateway machine and wish to forward connections on port 80 to an internal machine then you'd create the following rules:

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 192.168.1.50:80
iptables -A INPUT -p tcp -m state --state NEW --dport 80 -i eth1 -j ACCEPT

These two rules are fairly simple - the first says that all incoming tcp connections arriving destined for port 80 should be sent to the internal machine 192.168.1.50 (also on port 80).

This rule alone doesn't do the job though, we also have to accept the incoming connection. This is the job of the second rule which says that new connections on port 80 should be accepted on the external device eth1.

To increase security you could limit this forwarding to only work when connections are coming from a particular address with the use of the "--source" flag:

iptables -A PREROUTING -t nat -i eth1 -p tcp --source 11.22.33.44 \
--dport 80 -j DNAT --to 192.168.1.50:80

 

 


Posted by aphid7 (81.168.xx.xx) on Mon 7 Feb 2005 at 19:11
After the first iptable rule, connection to gatewy on port 80 is rerouted and sent to FORWARD, not to INPUT on gateway machine. The second rule must be: iptables -A FORWARD -p tcp -m state --state NEW -d 192.168.1.50 --dport 80 -j ACCEPT

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Mon 7 Feb 2005 at 19:20
[ View Steve's Scratchpad | View Weblogs ]
Strange, as the rules work as described above...

Steve
-- Steve.org.uk

[ Parent | Reply to this comment ]

Posted by wschee (146.6.xx.xx) on Fri 4 Nov 2005 at 16:07
I think that was because your default policy for FORWARD was ACCEPT.
If you try rc.firewall from http://iptables-tutorial.frozentux.net/iptables-tutorial.html#RCF IREWALLFILE,
you will see the difference, where the default policy for FORWARD is DROP instead of FORWARD.

[ Parent | Reply to this comment ]

Posted by Anonymous (217.147.xx.xx) on Sun 26 Nov 2006 at 00:18
This is definately true.... I suggest you update the article to say the correct thing.

[ Parent | Reply to this comment ]

Posted by Anonymous (149.5.xx.xx) on Tue 31 Aug 2010 at 13:26
I've not tested this but think both FORWARD and INPUT will be correct depending on the destination of the packet which is given by the IP address in the first rule. If the IP is to a different machine then the packet goes to the FORWARD chain. If the IP specifies the local machine then it will be presented to the INPUT chain.

[ Parent | Reply to this comment ]

Posted by Anonymous (64.134.xx.xx) on Wed 13 Oct 2010 at 04:03
Clearly FORWARD and INPUT were correct for the case Steve tested. But the problem is, as shown by the many responses in this thread, it just doesn't work in the most general case. Steve made special (undocumented) assumptions about what else the firewall/NAT was doing. Others may need to use PREROUTING either instead of INPUT or in addition to it, depending on what policy they have set up. PREROUTING is, after all, for any packet arriving (to the local machine, the one running the firewall) via ANY interface. FORWARD is only for packets being ROUTED through the box.

Even in the case you mention it is not guaranteed, since Steve never DID specify (in his article) that any and all packets will have the IP address of the local machine. On the contrary: the whole point of his rule is to take anything directed to port 80 and point it to the IP address of the local machine. But what will it do, for example, to packets coming from another machine inside the firewall? Does such a machine always have to use only internal IP addresses? Again, it depends on the rest of the firewall configuration.

So unfortunately, this article is just not as helpful as it seems at first.

[ Parent | Reply to this comment ]

Posted by Anonymous (122.168.xx.xx) on Tue 3 Apr 2007 at 15:02
very correct. the connection after DNATting do get rerouted to the FORWARD chain. Somebody correct this article..

[ Parent | Reply to this comment ]

Posted by RTB (82.41.xx.xx) on Tue 11 Oct 2005 at 23:01
[ View Weblogs ]
Hi,
first post:/

this may sound stupid!, but would this work with the openSSH,
as in replacing the port 80 to port 22-?, just that id like to be safe than sorry

this is a really good site for new Debian users like my self !!
keep up the good work gents!!

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Fri 4 Nov 2005 at 16:10
[ View Steve's Scratchpad | View Weblogs ]

Don't forget the ladies too!

Yes it should work for other ports too, so you have nothing to worry about.

Steve
--

[ Parent | Reply to this comment ]

Posted by Anonymous (24.197.xx.xx) on Tue 8 Nov 2005 at 03:43
Id like to be able to connect to 'tor' (on port 9050) from a PC on the LAN. Since tor only accpets connection from localhost, what command would i use to make 10.0.0.1 be able to access tor on port 9050? Ive tried a few combinations of the commands above, but no luck.

[ Parent | Reply to this comment ]

Posted by Steve (82.41.xx.xx) on Tue 8 Nov 2005 at 11:56
[ View Steve's Scratchpad | View Weblogs ]

It would make more sense to change the tor configuration to allow it to bind upon the external address - rather than using iptables for this.

Look at the configuration files under /etc/tor.

Steve
--

[ Parent | Reply to this comment ]

Posted by Anonymous (141.85.xx.xx) on Mon 12 Dec 2005 at 17:51
Hello...I have a small problem with debian as well.
I have a server with debian that holds an entire network.
I have an internal ip like everyone else,and only 1 ip for the server,that everyone else uses.
I want to open a port on the server so I can become conectable on trackers for torrents,can any1 help me?

[ Parent | Reply to this comment ]

Posted by Anonymous (82.211.xx.xx) on Fri 11 May 2007 at 12:33
No it should not.

Unless you stop explaining things before you understand how they work and correct your article.

Forwarded packets DON'T enter -t filter INPUT chain.

Please don't confuse people.

[ Parent | Reply to this comment ]

Posted by Anonymous (130.13.xx.xx) on Fri 15 Feb 2008 at 18:04
I've struggled for 5 days looking for information on how to forward ports through my Linux gateway and read almost every article about the subject. Beautiful articles but none of them worked. Suddenly, I copy the first two rules, change the internal IP and paste them into Putty, save and restart iptables et voila they worked like a charm. Therefore, I'd go with what works.

Thanks Steve, you're a life saver!

Martha

[ Parent | Reply to this comment ]

Posted by Anonymous (59.184.xx.xx) on Tue 20 Dec 2005 at 12:09
how to use ip from dmz (iptable)
how to config isa 2004 dmz

[ Parent | Reply to this comment ]

Posted by Sluggoman (68.147.xx.xx) on Sun 13 Aug 2006 at 00:55
hmmmm - not sure if I've missed something - I've tried this and it doesn't seem to work - is there anything else I need to do? restart networking? I have a front end Debian box doing NAT, DHCP, DNS, Apache etc. I am using ipmasq for the "natting". Inside the network I have three independant network camera's with internal IP addresses that I would like to forward traffic to from the external interface - so I need to use various non-standard ports externally and forward it to port 80 at the appropriate IP's on the inside - do I need a second rule to allow NAT traffic back out the internal interface?

ie. - what should the rule set be if I want to route external traffic received on port 8090 to the internal IP 10.0.1.211:80 to allow the webserver traffic back to a browser on the internet?

TIA

[ Parent | Reply to this comment ]

Posted by opk (89.48.xx.xx) on Mon 2 Mar 2009 at 22:30
In addition to the rules in the article, you need a POSTROUTING rule to enable masquerading if the redirection goes to another machine. For example:
iptables -t nat -A POSTROUTING -j MASQUERADE -o eth0
Otherwise, the response doesn't get back to the original machine and the connection appears to be filtered. At least this is what I found when trying to do forwarding. I appreciate that this is a few years too late to help but it might help someone else.

[ Parent | Reply to this comment ]

Posted by Anonymous (173.10.xx.xx) on Wed 1 Jul 2009 at 02:06
Glad you did, I've been struggling to figure out why it wouldn't work and then saw your post. You may be a little late to the conversation but you've saved at least 1 googler a lot of headache.

[ Parent | Reply to this comment ]

Posted by Anonymous (79.120.xx.xx) on Mon 13 Dec 2010 at 13:35
thank you, that worked!

[ Parent | Reply to this comment ]

Posted by Anonymous (12.218.xx.xx) on Sat 18 Nov 2006 at 05:13
My question is.. I see its either a TCP OR a UDP forward.. I need to know how to forward both.. I've tried making a seperate one for each, but it does not work.. Anyone able to offer any advise?

[ Parent | Reply to this comment ]

Posted by Anonymous (212.76.xx.xx) on Wed 6 Dec 2006 at 12:30
I second what has been mentioned earlier. The second rule should be FORWARD instead of INPUT. After the prerouting the FORWARD chain is invoked, this is particularly true of recent versions of iptables. So could someone please edit this article.

[ Parent | Reply to this comment ]

Posted by Anonymous (86.55.xx.xx) on Sun 24 Dec 2006 at 03:49
very useful and correct.

[ Parent | Reply to this comment ]

Posted by sgla1 (206.72.xx.xx) on Sun 16 Mar 2008 at 23:57

Hi Steve,

I know this is an old post but my experiments indicate you got something wrong that may frustrate people new to iptables firewalls.

is:

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 192.168.1.50:80
iptables -A INPUT -p tcp -m state --state NEW --dport 80 -i eth1 -j ACCEPT

should be:

iptables -A PREROUTING -t nat -i eth1 -p tcp --dport 80 -j DNAT --to 192.168.1.50:80
iptables -A FORWARD -p tcp -i eth1 -o eth0 -d 192.168.1.50 --dport 80 -j ACCEPT

Your packet is going to enter the nat table's PREROUTING chain, then pass to the input table's FORWARD chain so that it can be sent from eth1 to eth0 and to it's destination.

[ Parent | Reply to this comment ]

Posted by Anonymous (125.63.xx.xx) on Sun 16 Nov 2008 at 19:57
THANKS

BY HARISH
mailid harish.narang2000@gmail.com

[ Parent | Reply to this comment ]

Posted by Anonymous (123.231.xx.xx) on Tue 22 Mar 2011 at 10:11
supperb i got my system up and running

[ Parent | Reply to this comment ]

Posted by Anonymous (84.2.xx.xx) on Sat 22 Mar 2008 at 11:18
INPUT should be FORWARD.

The rest is ok.

[ Parent | Reply to this comment ]

Posted by Anonymous (79.42.xx.xx) on Mon 12 May 2008 at 11:13
It doesn't make any sence , there must be a ForWARD Chain not an Input ....

[ Parent | Reply to this comment ]

Posted by Anonymous (171.71.xx.xx) on Fri 19 Mar 2010 at 21:16
Hi,
Iam new to iptables. I would like to use it to forward the traffic on particular port to another port on the same host. what would be the rule to do so? Please let me know if this is possible at all.

Thanks in advance.

[ Parent | Reply to this comment ]

Posted by Anonymous (218.249.xx.xx) on Thu 25 Mar 2010 at 07:42
Hi,my name is ablo zhou from China.
my email is ablozhou # gmail.com

my eth0 has been set a public IP,like 210.211.xx.x,and eth1 is a inner IP
:192.168.12.10. my web site has an inner IP 192.168.12.50.

the below sets on Centos 5.2 will be work.
On the gateway machine set ipv4 forward:
vi /etc/sysctl.conf

net.ipv4.ip_forward = 1

sysctl -p

you should see:
net.ipv4.ip_forward = 1

then you will set iptables to forward the ip packages

#nat表,PREROUTING链,设置&#x 5BF9;eth0的目标端口是80ݨ 4;tcp协议,放到DNAT,forward& #x5230;192.168.12.50:80
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.12.50:80

#filter表,对接到的eth0ݨ 4;,从eth1转到192.168.12.50:80
iptables -A FORWARD -p tcp -i eth0 -o eth1 -d 192.168.12.50 --dport 80 -j ACCEPT

#但是,也要做nat变c 62;,维护一份映射ࢆ 8;,从eth1送出时采用&#x 5185;网地址,回来时 3D8;为公网地址。否R 19;外网会收不到回֐ D;。
iptables -t nat -A POSTROUTING -j MASQUERADE -o eth1

run
service iptables save

this will work well.

thanks.

[ Parent | Reply to this comment ]

Posted by Anonymous (2.101.xx.xx) on Sun 25 Mar 2012 at 23:33
sysctl.conf info saved my sanity. couldn't work out why the packets weren't nat'ing! thanks :-)

[ Parent | Reply to this comment ]

Posted by Anonymous (46.179.xx.xx) on Fri 18 May 2012 at 06:46
Hi,
great article & comments!
Still valid after all these years.

I struggled yesterday with exactly this same situation:
my test environment: Debian Testing (Wheezy) with kernel 3.2.0, iptables 1.4.13-1.1 it seems to be working only with the two lines PREROUNTING & FORWARD.

On production environment, after going through the code for Xth time & mad,
I just realized that I need to explicitely MASQUERADE/SNAT inbound packets for port forwarding to work.
This is actually what Zhou says - it seems to be omitted in all documentation I have found. Usually only the two lines for PREROUTING&FORWARD are mentioned, but not this.

Here is my code running on Debian Squeeze (kernel 2.6.32, iptables 1.4.8-3):
/etc/sysctl.conf: net.ipv4.ip_forward = 1
iptables -t nat -A POSTROUTING -o $INT_IFACE -j SNAT --to-source=$THISMACHINE_INT_IP
iptables -t nat -I PREROUTING -i $EXT_IFACE -p tcp --dport 80 -j DNAT --to-destination $LANWEBSRV_IP:80
iptables -A FORWARD -i $EXT_IFACE -o $INT_IFACE -d $LANWEBSRV_IP -p tcp --dport 80 -j ACCEPT


Cheers,
Matej

[ Parent | Reply to this comment ]

Posted by Anonymous (60.242.xx.xx) on Sun 28 Mar 2010 at 23:02
It would be handy having an example with the first destination port being different to the final destination port as it is a little confusing with the destination port in the FORWARD rule.

/sbin/iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 3389 -j ACCEPT
/sbin/iptables -A PREROUTING -t nat -p tcp -d 123.123.123.123 --dport 39145 -j DNAT --to 192.168.60.3:3389

[ Parent | Reply to this comment ]

Posted by Anonymous (24.106.xx.xx) on Thu 16 Sep 2010 at 03:16
Many thanks to the author for the hint. Soon all users will be happy. I may even get lunch out of this....

[ Parent | Reply to this comment ]

Posted by Anonymous (85.174.xx.xx) on Mon 4 Jul 2011 at 18:46
You aint need to specify INPUT chain (because your gateway passes traffic) either FORWARD chain with each DNAT entire, because you can only use conntrack module.

-A FORWARD -m conntrack --ctstate DNAT -j ACCEPT

[ Parent | Reply to this comment ]

Posted by Anonymous (213.16.xx.xx) on Tue 27 Sep 2011 at 12:54
Thanks for help.

[ Parent | Reply to this comment ]

Posted by Anonymous (89.75.xx.xx) on Fri 25 Jan 2013 at 20:33
ofc rules are wrong

[ Parent | Reply to this comment ]

Sign In

Username:

Password:

[Register|Advanced]

 

Flattr

 

Current Poll

What do you use for configuration management?








( 76 votes ~ 0 comments )