Skip to content

Instantly share code, notes, and snippets.

@nborwankar
Forked from kentbrew/node-on-ec2-port-80.md
Created March 27, 2011 22:25
Show Gist options
  • Save nborwankar/889705 to your computer and use it in GitHub Desktop.
Save nborwankar/889705 to your computer and use it in GitHub Desktop.
THE PROBLEM:
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.)
THE TEMPTINGLY EASY BUT TOTALLY WRONG SOLUTION:
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.)
ONE POSSIBLE RIGHT WAY:
Add a port forwarding rule via iptables.
OH DEAR FAMILIAR FEELING YOU ARE A TOTAL N00B AND KNOW NOT ONE THING ABOUT 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
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
[ec2-user@ip-10-205-14-7 ~]$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
REDIRECT tcp -- anywhere anywhere tcp dpt:http redir ports 8000
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
I checked my Node script, which was running on port 8000, and (yes!) it was responding on port 80.
During my early fumbling 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.
FINAL NOTE: I DID NOT DO THIS MYSELF BUT I HAVE A VERY STRONG FEELING I SHOULD BE VERY CAREFUL NOT TO SCREW UP PORT 22, WHICH IS MY ONLY WAY IN.
Thanks to @rckenned, @jrconlin, and @spullara ... see also http://iptables.rlworkman.net/chunkyhtml for a pretty definitive-looking iptables tutorial from @frozentux.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment