Standard practices say no non-root process gets to talk to the Internet on a port less than 1024. How, then, could I get Node talking on port 80 on EC2? (I wanted it to go as fast as possible and use the smallest possible share of my teeny tiny little micro-instance's resources, so proxying through nginx or Apache seemed suboptimal.)
Alter the port the script talks to from 8000 to 80:
}).listen(80);
.. and run it as root:
sudo /usr/local/bin/node foo.js
This is a Bad Idea, for all the standard reasons. (Here's one: if Node has access to the filesystem for any reason, you're hosed.)
Add a port forwarding rule via iptables
.
First, I listed the rules currently running on the NAT (Network Address Translation) table:
[ec2-user@ip-XX-XXX-XX-X ~]$ sudo iptables -t nat -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
I saw nothing, so I felt free to add a rule forwarding packets sent to external port 80 to internal port 8000:
[ec2-user@ip-XX-XXX-XX-X ~]$ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8000
When I listed again, I saw a new PREROUTING chain:
[ec2-user@ip-XX-XXX-XX-X ~]$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8000
I checked my Node script, which was running on port 8000, and (yes!) it was responding on port 80.
The above steps go over how to setup a PREROUTING, but all of the settings will be lost after the system restarts. If you want to have your iptables PREROUTING saved everytime you reboot, use one of these two options.
-
First option (recomended)
It is how the official ipttable's documentation teach us. See here
Add these two lines in /etc/network/interfaces:
pre-up iptables-restore < /etc/iptables.rules
post-down iptables-save > /etc/iptables.rules
The line "post-down iptables-save > /etc/iptables.rules" will save the rules to be used on the next boot. -
Second option
You can add those PREROUTING commands to/etc/rc.local
, so it will be executed automatically after reboot.
It is not recomended since firewall rules should never go intorc.local script
. Therc.local
is the last thing to be executed. If a block rule has been placed into rc.local there is a small time frame where an attacker can exploit a rule not being in place.
While it probably doesn't matter with this situation, it is still best to not get into a bad habit that may bite you later. (Take from here)
During my early attempts I screwed up a bunch of times. I removed busted rules by specifying the right table, the right chain, and the right line number, like so:
[ec2-user@ip-XX-XXX-XX-X ~]$ sudo iptables -t nat -D PREROUTING 1
This removed the first line from the PREROUTING
chain in my nat table.
I did not do this myself but throughout this process I had a very strong feeling I should be very careful not to screw up port 22, which was my only way in.
- @rckenned,
- @jrconlin,
- @spullara,
- @frozentux for http://iptables.rlworkman.net/chunkyhtml, which is a pretty definitive iptables tutorial.
My EC2 instance (Amazon Linux) doesn't seem to have an
/etc/network/interfaces
file, or even the directory. I just see /etc/networks (file).