>_
EngineeringNotes
Module 07

Certificate Management

The journey from HTTP to HTTPS. Securing your application.

01

HTTP vs HTTPS

By default, all traffic on the web is sent as Plain Text (HTTP). This means if you send a password, anyone sitting between you and the server (like a hacker at a coffee shop or a rogue ISP) can read it properly.

HTTP (Unsecure)

GET /login HTTP/1.1
Host: example.com
password: "secret123"

Anyone can sniff this packet and see the password.

HTTPS (Secure)

GET /login HTTP/1.1
Host: example.com
Wait... it's all encrypted garbage.

Only the server with the Private Key can decrypt this.

Deep Dive: The "Handshake"

How do the Client (Browser) and Server agree on a secret code without sending it over the unsecured network? This is called the TLS Handshake.

Step 1

Client Hello

Browser: "I want to talk safely. I support these encryption algorithms..."

Step 2

Server Hello

Server: "Let's use this algorithm. Here is myPublic Certificate (Identity) so you know I'm real."

Step 3

Verification

Browser: "Let me check with the Authority (Let's Encrypt) if this certificate is valid... Looks good."

Step 4

Key Exchange

Browser creates a random "Session Key", encrypts it with the Server's Public Key, and sends it.

The Magic

Only the Server has the Private Key to decrypt that message. Now both have the same Session Key! They start talking using that key.

02

Implementation Guide

Many learners think they need to add complex SSL code inside their Node.js or Python app.
Good News: In a DevOps environment (using Nginx), your app code stays simple! You don't touch the code. Nginx handles Security.

1. The Application Code

Notice: It's just a standard HTTP server listening on port 3000. No SSL certificates here!

server.js
javascript
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello Secure World!');
});

// We listen on HTTP Port 3000
app.listen(3000, () => {
  console.log('App running on http://localhost:3000');
});
03

Setting up LetsEncrypt

We will use a tool called Certbot. It talks to Let's Encrypt, proves you own the domain, gets the certificate, and automatically installs it into Nginx.

Phase 1: Installation (Snap)

Follow these exact steps to install Certbot using Snap (the recommended way).

Step 2Install Snapd
Terminal
bash
sudo apt update && sudo apt install snapd -y
Step 3Remove old Certbot
Terminal
bash
sudo apt-get remove certbot
Note: This only removes the older application. It does not delete your existing certificates (stored in /etc/letsencrypt). Your sites will stay secure during this switch.
Step 4Install Certbot
Terminal
bash
sudo snap install --classic certbot
Step 5Prepare Command
Terminal
bash
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Phase 2: Use Certbot

Run the nginx plugin. It will scan your configuration and ask which domains to secure.

Terminal
bash
sudo certbot --nginx
Terminal Output Simulation
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
1: sellshoes.com
2: sellclothes.com
3: sellbooks.com
...
9: sellphones.com
...
Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel): 9
Requesting a certificate for sellphones.com
Successfully received certificate.
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default

What did Certbot change?

Certbot automatically edited your /etc/nginx/sites-available/default file. Here is the difference:

Before (HTTP)
.../sites-available/default
nginx
server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
        # ... proxy settings
    }
}
After (HTTPS)
.../sites-available/default
nginx
server {
    server_name example.com;

    location / {
        proxy_pass http://localhost:3000;
        # ... proxy settings
    }

    # Certbot added these!
    listen 443 ssl; 
    ssl_certificate /etc/letsencrypt/...fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/...privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
}

# Redirect Block (Forces HTTPS)
server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    }
    listen 80;
    server_name example.com;
    return 404;
}

Phase 3: Verify Auto-Renewal

Let's Encrypt certs last 90 days. Certbot installs a timer to renew them automatically. Test it:

Terminal
bash
sudo certbot renew --dry-run