Redirection with IPTABLES while hiding the original port

So, I have my Glassfish server is listening on port 8080.
However, I want to have my requests at port 80 while hiding 8080,
so that people think my server really runs at 80.

How can I do it with iptables? I have tried the following rule:

iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

but it's not what I want, because I have to open both 80 and 8080 for it to work.

Any ideas?


Update: I've changed my rules' file to look like:

iptables -F

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

iptables -A INPUT -j DROP

#REDIRECTION RULES
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT  \
         --to-destination 127.0.0.1:8080

But still doesn't work. I have /proc/sys/net/ipv4/ip_forward set to 1.
Nor http://myserver:8080 neither http://myserver:80 work. The packets are dropped.


Solution 1:

Use DNAT.

iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination your.ip.address:8080

Something like that should work. :)

EDIT after your own edit: I think this line is too early in your rule set:

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Thanks to that your server does not accept any NEW connections, right? Try to move it right before your iptables -A INPUT -j DROP line.

Solution 2:

I had exactly the same question and found the answer with help of this community. Here is the link:

Port redirection with iptables to localhost / blocking the destination port

I solved the problem by marking the packets incoming on 8080 and filtering them afterwards:

iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 8080 -j MARK --set-mark 1
iptables -A INPUT -m mark --mark 1 -j DROP

The last rule to drop the marked packets could be the very first rule in your INPUT chain.

DNAT did not work for me with localhost. I think this is because localhost is treated specially in the kernel.