Skip to content

Instantly share code, notes, and snippets.

Last active July 27, 2023 23:50
Star You must be signed in to star a gist
What would you like to do?
How I Got Node.js Talking on EC2's Port 80

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 ultimately wrong solution:

Alter the port the script talks to from 8000 to 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 possibly-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

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.


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.

Careful, now....

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.


Copy link

Thanks! Very handy.

Copy link

FoxxMD commented Jun 19, 2017

Thanks @JustinWinthers classic ELB is exactly what I needed 👍

Copy link

When I use the below command, I am able to redirect from port 443 to port 8000, but I also want to redirect my port 80 to 8000 .

sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8000

Copy link

awesome! thx a lot

Copy link

imZEH commented Sep 12, 2017

Is there a command that rerouting port from 8000 to 80 upon restart the instance ?
some says use UFW ?


Copy link

sombek commented Sep 19, 2017

Thank you it's really helpful.
spent the last night searching for this problem!

Copy link

sombek commented Sep 19, 2017

Why you don't use the elastic IP instead?

Copy link

DecentM commented Sep 20, 2017

I usually just give the node binary permission to open a service port with sudo setcap 'cap_net_bind_service=+ep' $(which node)
(or replace $(which node) with wherever your node binary is if that returns a symlink)

Copy link

marwanmakm commented Nov 16, 2020

Excellent bro, It works perfectly!!. Now I can access without problems to my Node.js Server running in my EC2 instance and configure a Domain.

Thank you

Copy link

Works even in 2021. You're a legend!

Copy link

You saved me a ton of time thank you!!!

Copy link

to save the change in ubuntu
sudo /sbin/iptables-save

Copy link

jonbel16 commented Oct 7, 2022

Works in 2022. Thank you

Copy link

Very nice! Is still relevant!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment