Set up SSL for Yarkon Server

While the recommended way to set up SSL to Yarkon Server is to follow the AWS best practice and place the instance behind and ELB/ALB that would terminate SSL traffic, under some circumstances you might prefer to install the SSL certs directly on the instance. Follow this guide to get it done.

Step 1 - SSH to the instance

Note that the root user name for Yarkon Server instance when deployed from the standard AMI is ubuntu, as is the case for any default Ubuntu unix server. Make sure to use this name instead of the default ec2-user (which won't work).

Step 2 - Verify that it is running

The standard Yarkon Server AMI uses pm2 as its process manager. To check the current status of the application use:

~$ pm2 list
│ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem        │ user   │ watching │
│ aphek    │ 0  │ N/A     │ fork │ 988 │ online │ 0       │ 22m    │ 0%  │ 102.2 MB   │ ubuntu │ disabled │

Note that the code name for the server side application running the Yarkon service is aphek.

Step 3 - Curl to the application

By default, Yarkon Server listens on port 80, the default http port. We want to change that to port 443 for https, but before we do, we want to verify that the default set up is correct. An end point that is always available and does not require any parameters is version. Use it like so:

~$ curl localhost:80/version/

Step 4 - Go to the application folder

Yarkon Server is installed by default in the folder /var/app/current/. Change directory into this folder:

~$ cd /var/app/current/

Step 5 - Make a folder for the keys

/var/app/current$ mkdir ssl
/var/app/current$ cd ssl

Step 6 - Install the keys

Since this is a sample guide, we'd be using a self signed cert. This cert would suffice to illustrate the process, but you won't be able to use it for the actual production system, so after you finish this guide and it is all operational, make sure to replace the self signed cert with your production cert.

In the following steps we generate a self signed cert and make sure the output files are what is required:

/var/app/current/ssl$ openssl genrsa -out key.pem
Generating RSA private key, 2048 bit long modulus (2 primes)
e is 65537 (0x010001)

/var/app/current/ssl$ openssl req -new -key key.pem -out csr.pem
Can't load /home/ubuntu/.rnd into RNG
139660067926464:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/home/ubuntu/.rnd
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

/var/app/current/ssl$ openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
Signature ok
subject=C = AU, ST = Some-State, O = Internet Widgits Pty Ltd
Getting Private key

/var/app/current/ssl$ rm csr.pem
/var/app/current/ssl$ ls
cert.pem  key.pem

Step 7 - Update the config file

Yarkon Server gets it ENV variables from the config file used by pm2, the process manager.

Before making any changes there, take a backup. Then, open the file in your favorite editor, and change the env section to look like the below. Basically, we tell it to run on port 443 for https, and use the certs we just created:

/var/app/current/ssl$ cd ..
/var/app/current$ cp yarkon-server.pm2.json yarkon-server.pm2.json.bak

$ cat yarkon-server.pm2.json
        "apps": [{
                "name": "aphek",
                "script": "./aphek",
                "watch": false,
                "env": {
                        "PORT": 443,
                        "TLS_KEY": "./ssl/key.pem",
                        "TLS_CERT": "./ssl/cert.pem"

Step 8 - Reload and verify

Using pm2, we reload the application to get it to use the new ENV variables. The following commands show how to reload and inspect the process:

/var/app/current$ pm2 reload yarkon-server.pm2.json --update-env
[PM2] Applying action reloadProcessId on app [aphek](ids: 0)
[PM2] [aphek](0) ✓

ubuntu@ip-172-31-34-13:/var/app/current$ pm2 env 0
TLS_CERT: ./ssl/cert.pem
TLS_KEY: ./ssl/key.pem
script: ./aphek
updateEnv: true

Step 9 - Verify that SSL works

It is time to check out work. First, we verify that http traffic on port 80 is no longer working. Then, we verify that https traffic on port 443 is operational. Again, we use curl. Note the parameter -k used telling curl to ignore the self signed cert:

/var/app/current$ curl http://localhost/version/
curl: (7) Failed to connect to localhost port 80: Connection refused
/var/app/current$ curl -k https://localhost/version/

Step 10 - Save your work

To make sure our work survives a reboot, we have to save it. We will do so now, and verify that after a reboot all is still fine. Do it like so:

/var/app/current$ pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/ubuntu/.pm2/dump.pm2

/var/app/current$ sudo reboot

~$ pm2 env 0
updateEnv: true
script: ./aphek
TLS_KEY: ./ssl/key.pem
TLS_CERT: ./ssl/cert.pem

~$ curl -k https://localhost/version/

At this point the set up is complete - your Yarkon Server is now using SSL. You can go ahead and replace the self signed certs with your production certs.

Last tip: if you get your certs as a bundle from your cert authority and you are unsure which file is which, simply open them in an editor and compare to the self signed files you generated above. The files are just text files and each includes a header that specifies what the file actually is.