How to setup tls termination for your website in Ubuntu 20.04 server

Main reference:

https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04

1/ Install nginx and certbot

sudo apt install nginx
sudo ufw app list
sudo ufw status
sudo systemctl restart nginx

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

2/ Enable the firewalls and app (optional but strongly recommended)

sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
sudo ufw allow 'OpenSSH'
sudo ufw allow 'Nginx Full'
sudo ufw app list

3/ Register your domain with hosting service

  • Go to the hosting service (eg: godaddy)
  • Add A record with the server IP address
  • TTL = Time to live, in seconds (if the this value is short → the record is quickly updated/refresh. Otherwise, it takes long time to change and retrieve the actual address again)
    • Example command to check remaining time in answer section.
$ dig vthily.com

; <<>> DiG 9.10.6 <<>> vthily.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 20576
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;vthily.com.			IN	A

;; ANSWER SECTION:
vthily.com.		2119	IN	A	160.153.0.173

;; Query time: 5 msec
;; SERVER: 192.168.50.1#53(192.168.50.1)
;; WHEN: Tue Feb 28 06:32:46 +08 2023
;; MSG SIZE  rcvd: 55

Hosting with A records, in some case, the TTL default = 14400 (seconds) = 4 hours

4/ Obtaining the certificate (SSL or TLS)

  • SSL is the old name
  • TLS is the newer version.
sudo certbot --nginx -d vthily.com -d www.vthily.com

If this fails, you can try again, maximum 5 times per hour.

5/ Setup the nginx config

This nginx config is to

  • serve wss at the root: meaning wss://example.com.sg
  • https server at basepath=https://example.com.sg/path1
    • Other endpoints at relative path to the basepath
    • Eg:
      • https://example.com.sg/path1/health (GET)
      • https://example.com.sg/path1 (POST)
$ touch /etc/nginx/conf.d/example.conf 
$ cat /etc/nginx/conf.d/example.conf 
server {
  server_name example.com.sg;

  location / {
    proxy_pass http://localhost:8001/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

  location /path1 {
    proxy_pass http://localhost:8000/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com.sg/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com.sg/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = example.com.sg) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

  listen 80;
  listen [::]:80;
  server_name example.com.sg;
    return 404; # managed by Certbot

}

Thats it. You should now serve the secured websocket server at wss://example.com.sg, and the webserver at https://example.com.sg/path1.

You can verify the websocket on web browser with the addon: Simple Websocket client, or websocat on the command line

Simple Websocket Client addon.

https://github.com/vi/websocat

Comment Disabled for this post!