iptables nat port redirect loses POST parameters

October 24, 2014 1.8k views

I have a Grails application deployed on glassfish on a droplet running Ubuntu Server. In order to make the domain work with the default http and https ports, I had to redirect the port 80 to 8080 and 443 to 8181 using iptables.

Unfortunately, something strange happens: on login, the username and password are correctly POST'ed by the client but they don't reach the server application. Instead, the application redirects to the port 8181 and then everything works fine.

The problem seems therefore to be with the port forwarding somehow losing the POST parameters. I have no idea why this could happen.

Here is the script that I use to redirect the ports:

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

iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8181

Any ideas why this happens and how I could fix it?

Thanks!

1 comment
  • Thanks for your answer.

    The reason I have to do that is because in Linux, ports numbered under 1024 are considered privileged. This means that only users with specific rights can access them.

    I have found three options to accomplish this:

    • run glassfish with a privileged user
    • redirect ports with iptables
    • install apache in front of glassfish to deal with this redirect

    The first means adding unnecessary privileges to the whole glassfish server process (or domain, I'm not sure). The third means managing another piece of software, again unnecessarily. I favor therefore the second option, but I'm having the issue mentioned above.

2 Answers

Not sure I know the answer to your question unfortunately. Though I might have a different solution to your problem. Is there a specific reason why you don't change the port directly through Glassfish?

You can do this in the admin interface by going to Configurations -> server-config -> Network Config -> Network Listeners

You can accomplish the same thing on the command line. For instance, to bind http-listener-1 to port 80 run:

asadmin delete-network-listener http-listener-1
asadmin delete-protocol http-listener-1
asadmin create-http-listener --default-virtual-server server --listenerport 8081 --listeneraddress 0.0.0.0 http-listener-1
  • Thanks for your answer.

    The reason I have to do that is because in Linux, ports numbered under 1024 are considered privileged. This means that only users with specific rights can access them.

    I have found three options to accomplish this:

    • run glassfish with a privileged user
    • redirect ports with iptables
    • install apache in front of glassfish to deal with this redirect

    The first means adding unnecessary privileges to the whole glassfish server process (or domain, I'm not sure). The third means managing another piece of software, again unnecessarily. I favor therefore the second option, but I'm having the issue mentioned above.

I finally fixed the problem by using authbind instead.

Here's the script:

user=user

touch  /etc/authbind/byport/80
chmod 500 /etc/authbind/byport/80 
chown $user /etc/authbind/byport/80 
touch /etc/authbind/byport/443
chown $user /etc/authbind/byport/443
chmod 500 /etc/authbind/byport/443

To work, you need to start the domain with:

authbind --deep asadmin start-domain domain

Have another answer? Share your knowledge.