How to setup tls termination for your website in Ubuntu 20.04 server
Main reference:
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
$ 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