Okay. The hardest part is getting the right files from the certificate provider and knowing which is which. I’m assuming you’ve got a SSL certificate (for guzz.io
) and so you have three files available that correspond to:
ssl.pem
ssl.key
trusted.pem
If you have those right, the rest should be easy enough.
By way of reference, ssl.pem
should have:
-----BEGIN CERTIFICATE-----
<LOTS OF RANDOM LETTERS AND NUMBERS>
-----END CERTIFICATE-----
with possibly one or two of these in the middle of the random letters and numbers:
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(i.e. it might be several certificates concatenated together)
trusted.pem
should be similar, but just a single certificate, i.e.:
-----BEGIN CERTIFICATE-----
<LOTS OF RANDOM LETTERS AND NUMBERS>
-----END CERTIFICATE-----
ssl.key
should be something like this:
-----BEGIN PRIVATE KEY-----
<LOTS OF RANDOM LETTERS AND NUMBERS>
-----END PRIVATE KEY-----
Now, here are the commands to issue on the (Ubuntu 16) server as a user with sudo
privileges:
1. Installing nginx
sudo apt-get update
sudo apt-get install nginx
And, if /var/log/nginx
is not already a directory:
sudo mkdir /var/log/nginx
2. Puttting the certificates in the right place
sudo mkdir /etc/nginx/ssl/guzz
Now we need to get the certificate and key files (listed above) onto the server in the /etc/nginx/ssl/guzz
directory we’ve just created. For simplicity’s sake, you can get the text of the .pem
and .key
files (open them in a text editor) and copy and paste it into files you create by issuing each of these commands:
sudo pico /etc/nginx/ssl/guzz/ssl.pem
sudo pico /etc/nginx/ssl/guzz/ssl.key
sudo pico /etc/nginx/ssl/guzz/trusted.pem
(Not sure if you’ve used the pico
text editor before. It’s CTRL+X
then Y
then ENTER
to save changes.)
3. The nginx
config file
Now we need an nginx
config file that supports SSL for your app in the /etc/nginx/sites-available
directory:
sudo pico /etc/nginx/sites-available/guzz.io
Paste this in to the new file we’ve just created/opened for editing:
upstream node_server {
server 127.0.0.1:3000 fail_timeout=0;
# if you need multiple instances of the app running on the same server (e.g. if you have multiple server cores available):
# server 127.0.0.1:3001 fail_timeout=0;
# server 127.0.0.1:3002 fail_timeout=0;
# server 127.0.0.1:3003 fail_timeout=0;
}
server {
listen 80;
server_name guzz.io;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name guzz.io;
access_log /var/log/nginx/app.access.log;
error_log /var/log/nginx/app.error.log;
ssl_certificate /etc/nginx/ssl/guzz/ssl.pem;
ssl_certificate_key /etc/nginx/ssl/guzz/ssl.key;
ssl_trusted_certificate /etc/nginx/ssl/guzz/trusted.pem;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
add_header Strict-Transport-Security "max-age=31536000";
location / {
proxy_pass http://node_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header X-Forwarded-For $remote_addr;
}
}
I won’t go into the details of all the parts of the nginx
config file (partly because I’m a bit shaky on some of the finer details), but basically the upstream node_server
block tells nginx
which port(s) your app instance(s) is(are) running on, and the server
blocks are telling nginx
which ports requests from the internet will be coming from.
Notice that traffic on port 80 (the http
port) is redirected to port 443 (the https
port) and it’s that server block that has all the SSL cert stuff, along with the location
block (which ensures we get sticky sessions).
Now we need this nginx
config file represented in /etc/nginx/sites-enabled
, so we symlink to the file with this command:
sudo ln –s /etc/nginx/sites-available/guzz.io /etc/nginx/sites-enabled
Remove the default nginx
config from /etc/nginx/sites-enabled
:
sudo rm /etc/nginx/sites-enabled/default
4. Starting nginx
:
Let nginx
traffic through the firewall, if it has been set up:
sudo ufw allow 'Nginx Full'
Then start nginx
:
sudo systemctl start nginx
Hopefully, you now have SSL termination courtesy of nginx
and can pm2-meteor deploy
new versions of your app (make sure the pm2-meteor
config file has port: 3000
set, as that’s the port where nginx
expects there to be a running app instance).