Tools: Self-Signed SSL Certificate for Nginx — Step-by-Step Guide - Complete Guide

Tools: Self-Signed SSL Certificate for Nginx — Step-by-Step Guide - Complete Guide

Self-Signed SSL Certificate for Nginx

Step 1: Generate the Certificate

Step 2: Install the Files

Step 3: Configure the Server Block

Step 4: Test and Reload

Step 5: Verify HTTPS is Working

Troubleshooting

Browser shows "Your connection is not private"

Nginx won't start with "cannot load certificate"

Certificate errors despite the correct CN

Further Reading A practical step-by-step guide. Generates a working HTTPS setup in under five minutes. Self-signed certificates are perfect for local development, staging servers, internal tools, and learning how TLS works. Browsers will display a warning because the certificate isn't signed by a trusted CA, but the traffic itself is encrypted the same way as with a Let's Encrypt cert. The fastest way is to use cert-depot.com — enter your domain, click generate, and download the ZIP. You'll get two files: certificate.pem and private-key.pem. If you prefer the command line with OpenSSL: Important: Always include a Subject Alternative Name (SAN). Modern browsers (Chrome 58+, released 2017) ignore the Common Name field and will reject certificates without a matching SAN, even if the CN is correct. Place the certificate and key somewhere Nginx can read them. A common convention is /etc/nginx/ssl/: The chmod 600 on the private key is critical — it should not be readable by any user other than root. Edit your site configuration (typically /etc/nginx/sites-available/default or a file under /etc/nginx/conf.d/): Always test the configuration before reloading Nginx to avoid downtime: If nginx -t reports errors, fix them before reloading. Common issues: typo in file paths, missing file, or wrong file permissions. Use curl to confirm the certificate is being served (the -k flag tells curl to ignore the untrusted-certificate warning): You should see the certificate details in the output. To inspect exactly what's being served: Or paste the certificate into our PEM decoder to see its details in a friendlier format. This is expected with a self-signed certificate. In Chrome, click "Advanced" and then "Proceed to example.local (unsafe)". To avoid the warning entirely, you need to trust the certificate in your system's certificate store. Check that the certificate file exists and Nginx can read it. Run sudo ls -la /etc/nginx/ssl/ and verify the paths in your config match exactly. This almost always means your certificate doesn't have a matching Subject Alternative Name. Regenerate it including the hostname as a SAN — see Step 1. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Code Block

Copy

openssl req -x509 -newkey rsa:2048 -nodes \ -keyout private-key.pem -out certificate.pem \ -days 365 \ -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,DNS:example.local,IP:127.0.0.1" openssl req -x509 -newkey rsa:2048 -nodes \ -keyout private-key.pem -out certificate.pem \ -days 365 \ -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,DNS:example.local,IP:127.0.0.1" openssl req -x509 -newkey rsa:2048 -nodes \ -keyout private-key.pem -out certificate.pem \ -days 365 \ -subj "/CN=localhost" \ -addext "subjectAltName=DNS:localhost,DNS:example.local,IP:127.0.0.1" sudo mkdir -p /etc/nginx/ssl sudo cp certificate.pem /etc/nginx/ssl/ sudo cp private-key.pem /etc/nginx/ssl/ sudo chmod 600 /etc/nginx/ssl/private-key.pem sudo chown root:root /etc/nginx/ssl/* sudo mkdir -p /etc/nginx/ssl sudo cp certificate.pem /etc/nginx/ssl/ sudo cp private-key.pem /etc/nginx/ssl/ sudo chmod 600 /etc/nginx/ssl/private-key.pem sudo chown root:root /etc/nginx/ssl/* sudo mkdir -p /etc/nginx/ssl sudo cp certificate.pem /etc/nginx/ssl/ sudo cp private-key.pem /etc/nginx/ssl/ sudo chmod 600 /etc/nginx/ssl/private-key.pem sudo chown root:root /etc/nginx/ssl/* server { listen 443 ssl; server_name example.local; ssl_certificate /etc/nginx/ssl/certificate.pem; ssl_certificate_key /etc/nginx/ssl/private-key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root /var/www/html; index index.html; } } # Optional: redirect HTTP to HTTPS server { listen 80; server_name example.local; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name example.local; ssl_certificate /etc/nginx/ssl/certificate.pem; ssl_certificate_key /etc/nginx/ssl/private-key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root /var/www/html; index index.html; } } # Optional: redirect HTTP to HTTPS server { listen 80; server_name example.local; return 301 https://$server_name$request_uri; } server { listen 443 ssl; server_name example.local; ssl_certificate /etc/nginx/ssl/certificate.pem; ssl_certificate_key /etc/nginx/ssl/private-key.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { root /var/www/html; index index.html; } } # Optional: redirect HTTP to HTTPS server { listen 80; server_name example.local; return 301 https://$server_name$request_uri; } sudo nginx -t sudo systemctl reload nginx sudo nginx -t sudo systemctl reload nginx sudo nginx -t sudo systemctl reload nginx curl -kvI https://example.local/ curl -kvI https://example.local/ curl -kvI https://example.local/ openssl s_client -connect example.local:443 -servername example.local \ </dev/null 2>/dev/null | openssl x509 -text -noout openssl s_client -connect example.local:443 -servername example.local \ </dev/null 2>/dev/null | openssl x509 -text -noout openssl s_client -connect example.local:443 -servername example.local \ </dev/null 2>/dev/null | openssl x509 -text -noout - How to trust a self-signed certificate in Chrome - Self-signed certificate for Apache - RSA vs ECDSA: which to choose for self-signed certificates