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 Encrypt. HTTPS helps prevent intruders from tempering the 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 the path /opt/letsencrypt
sudo git clone [https://github.com/letsencrypt/letsencrypt](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 you 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 the command:
sudo nginx -t
If it is running okay, restart Nginx:
sudo service nginx stop
sudo service nginx start
Last but not 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 :)