Enable HTTPS on AWS EC2 instance with Node.js and Nginx on Ubuntu server

I have an AWS EC2 instance running with NodeJS and Nginx on a Ubuntu 16.04 server. I am going to show you how to enable HTTPS instead of HTTP for your website using Let’s Encrpyt. HTTPS helps prevent intruders from tempering communication between your website and your users’ browsers. It is encrypted with Transport Layer Security (TLS) Certification. Let’s Encrypt is a certificate authority that provides free X.509 certificates.

First of all, ssh into your EC2 instance:

ssh -i <keyfile.pem> ubuntu@<public-ip-address>

Secondly, clone the Let’s encrypt repository into path /opt/letsencrypt

sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

Thirdly, check if there is any application listening to port 80 by running:

netstat -na | grep ':80.*LISTEN'

Kill any process running if it returns. For example, if you already have nginx server running at port 80, then you may need to stop it via:

sudo systemctl stop nginx

Fourthly, cd /opt/letencrypt to your repository and then run to get the certificates:

./letsencrypt-auto certonly --standalone --email <your@email.com> -d <domain.com> -d <subdomain.domain.com>

If your encounter an error

OSError: Command /opt/eff.org/certbot/venv/bin/python2.7 - setuptools pkg_resources pip wheel failed with error code 1

Then export below before you run the script in the shell:

export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"

Follow the instructions in the command prompt and you should now get your certs at the path /etc/letsencrypt/live/<domain.com>.

Fifth, config the Nginx config to redirect your HTTP traffic to HTTPS by edit the file:

sudo vi /etc/nginx/sites-available/default

And the content looks like this, remember to replace the <YourDomain.com> with your own one as well as the root path for your website:

server {
listen 443 ssl;
server_name <YourDomain.com>;
ssl_certificate /etc/letsencrypt/live/<YourDomain.com>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<YourDomain.com>/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
  root /var/www/yourPath
index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
  location / {
proxy_pass http://localhost:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forward-Proto http;
proxy_set_header X-Nginx-Proxy true;
proxy_redirect off;
}
}
server {
listen 80;
server_name <domain.com>;
return 301 https://$host$request_uri;
}

You can test your config for any error by running command:

sudo nginx -t

If it is running okay, restart ngnix:

sudo service nginx stop
sudo service nginx start

Last but not the least, go to AWS console and make sure your security group has port 443 open for HTTPS:


Done! Go to your https of your domain to verify it is working. If you encounter something like 502 Bad Gateway, make sure your NodeJS application is running correctly and I am using PM2 to keep it alive. Let‘s make the internet more secure 🙂

victorleungtw

Years of experience delivering enterprise projects with global stakeholders in banking, airline and gaming industries involving a broad range of technologies. Provide consulting services at both executive and operational levels, including strategy and data analysis. Lead web and mobile app development team with hands-on coding implementation. Manage projects as Certified Scrum Master with Agile techniques. Qualification with master degree in Computer Science and pursuing MBA degree in Finance.

Leave a Reply

Close Menu