Write Your OWN SSL Certificate for NGINX with Sockets - Discourse or Generic

Lets Encrypt is GREAT for convenience! Do I trust it? Not one bit. No particular reason for that, other than I don’t trust anything 3rd party, knowing what I know now…

Good news. You can write your OWN SSL! And though I don’t really trust ‘Elliptic Curve Cryptography’ either, I think it’s a good foundation for getting started with building out your own secure SSL, too. So, without further adieu, here go:

Create a self-signed certificate:

sudo openssl req -x509 -nodes -days 7 -newkey rsa:2048 \
-keyout /etc/ssl/private/WEBSITE-selfsigned.key \
-out /etc/ssl/certs/WEBSITE-selfsigned.crt

Edit Your NGINX Configuration

Open your NGINX config file:

sudo nano /etc/nginx/sites-available/default

Or, if using a different config:

sudo nano /etc/nginx/sites-available/WEBSITE.COM

Here’s my sample config for discourse. Scroll down for the same generic config file:

server {
    listen 80;
    server_name WEBSITE.COM;
    return 301 https://WEBSITE.COM$request_uri;
}

server {
    listen 443 ssl;
    server_name WEBSITE.COM;

    ssl_certificate /etc/ssl/certs/WEBSITE-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/WEBSITE-selfsigned.key;

    location / {
        proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
    }
}









Move the NGINX config

sudo ln -s /etc/nginx/sites-available/WEBSITE.COM /etc/nginx/sites-enabled/

Verify everything is correct:

sudo nginx -t

Restart NGINX

sudo systemctl restart nginx

Now, your self-signed SSL should work! :rocket:
You might get a browser warning (you shouldn’t because discourse installs its own SSL), but you can bypass it and access your site securely.

Other Useful Configurations

1. Generic Website Configuration

This configuration redirects all HTTP traffic to HTTPS and serves static files from /var/www/html or a custom directory.

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate /etc/ssl/certs/example-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/example-selfsigned.key;

    root /var/www/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

2. WordPress Website Configuration

This setup includes rules for WordPress, such as handling permalinks and restricting access to sensitive files.

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate /etc/ssl/certs/example-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/example-selfsigned.key;

    root /var/www/wordpress;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf|eot)$ {
        expires max;
        log_not_found off;
    }

    # Block access to .htaccess and other hidden files
    location ~ /\. {
        deny all;
    }
}