0
0
NginxHow-ToBeginner · 4 min read

Create Self-Signed Certificate for Nginx: Step-by-Step Guide

To create a self-signed certificate for nginx, use the openssl command to generate a private key and certificate. Then configure nginx to use these files in your server block with ssl_certificate and ssl_certificate_key directives.
📐

Syntax

Use the openssl command to generate a self-signed certificate and private key in one step. The basic syntax is:

  • openssl req -x509 -nodes -days <days> -newkey rsa:<keysize> -keyout <keyfile> -out <certfile>

Explanation:

  • req -x509: Create a self-signed certificate instead of a certificate request.
  • -nodes: Do not encrypt the private key (no passphrase).
  • -days <days>: Validity period of the certificate in days.
  • -newkey rsa:<keysize>: Generate a new RSA key with specified bits (e.g., 2048).
  • -keyout <keyfile>: Output file for the private key.
  • -out <certfile>: Output file for the certificate.

After generating the certificate, configure nginx server block with:

  • ssl_certificate <certfile>;
  • ssl_certificate_key <keyfile>;
bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
💻

Example

This example generates a self-signed certificate valid for 1 year with a 2048-bit RSA key, then shows how to configure nginx to use it.

bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt -subj "/C=US/ST=State/L=City/O=Organization/OU=Department/CN=localhost"

sudo tee /etc/nginx/snippets/self-signed.conf > /dev/null <<EOF
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
EOF

sudo tee /etc/nginx/snippets/ssl-params.conf > /dev/null <<EOF
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers HIGH:!aNULL:!MD5;
EOF

sudo tee /etc/nginx/sites-available/default > /dev/null <<EOF
server {
    listen 443 ssl default_server;
    listen [::]:443 ssl default_server;

    include snippets/self-signed.conf;
    include snippets/ssl-params.conf;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name localhost;

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

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name localhost;
    return 301 https://$host$request_uri;
}
EOF

sudo nginx -t && sudo systemctl reload nginx
Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
⚠️

Common Pitfalls

Common mistakes when creating self-signed certificates for nginx include:

  • Not specifying the -nodes flag, which causes openssl to prompt for a passphrase, making nginx unable to start without manual input.
  • Incorrect file permissions on the private key, which should be readable only by root or the nginx user.
  • Forgetting to reload or restart nginx after updating the configuration.
  • Not redirecting HTTP traffic to HTTPS, leaving unsecured access.

Example of wrong and right key generation:

bash
# Wrong: encrypted key (nginx will fail to start without passphrase)
openssl req -x509 -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx.key -out /etc/ssl/certs/nginx.crt

# Right: unencrypted key with -nodes
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx.key -out /etc/ssl/certs/nginx.crt
📊

Quick Reference

Summary tips for creating and using self-signed certificates with nginx:

  • Use openssl req -x509 -nodes to avoid passphrase prompts.
  • Store private keys securely with restricted permissions.
  • Configure nginx with ssl_certificate and ssl_certificate_key directives.
  • Redirect HTTP to HTTPS for better security.
  • Test configuration with nginx -t before reloading.

Key Takeaways

Generate a self-signed certificate using openssl with the -nodes flag to avoid passphrase prompts.
Configure nginx server blocks with ssl_certificate and ssl_certificate_key pointing to your certificate and key files.
Set proper permissions on private key files to keep them secure and readable only by nginx or root.
Always test nginx configuration with nginx -t before reloading to avoid downtime.
Redirect HTTP traffic to HTTPS to enforce secure connections.