Centos – Configuring CentOS 6 iptables to use port 80 for NodeJS app running on port 3000

centoscentos6iptablesnode.js

I'm running a fresh instance of CentOS 6 using AWS. There is something in iptables that is blocking my nodejs app.

Here is my nodejs app:

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!');
});

var server = app.listen(3000, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});

By following this guide, I tried to add an entry for my app with the following command:

sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000

When I run the node.js app and try to access it in my browser by going to ec2-XXX-XXX-XXX-XXX.YYY.compute.amazonaws.com, my browser just hangs.

I have confirmed that iptables is not doing what I want it to do, because whenever I run the command service iptables stop and go to the address ec2-XXX-XXX-XXX-XXX.YYY.compute.amazonaws.com:3000 the app gets served. However, I'm guessing it's not a good idea to not run iptables.

Node.js is running and listening, here is the output of netstat -tulpn:

Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      -
tcp        0      0 0.0.0.0:3000                0.0.0.0:*                   LISTEN      1364/node
tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      -
tcp        0      0 :::22                       :::*                        LISTEN      -
tcp        0      0 ::1:25                      :::*                        LISTEN      -
udp        0      0 0.0.0.0:68                  0.0.0.0:*                               -

And here is what I get when I run the command iptables -L:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Best Answer

Remember to actually open up port 80 to the world too.

Full list of commands needed:

sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3000

Do also remember to save the iptables config. This should be done with the following command:

sudo iptables-save > /etc/sysconfig/iptables

You can also try and see if it is indeed iptables that are bugging you by opening up port 3000 in the firewall but still having it active:

sudo iptables -I INPUT 1 -p tcp --dport 3000 -j ACCEPT