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
-nodesflag, which causesopensslto prompt for a passphrase, makingnginxunable to start without manual input. - Incorrect file permissions on the private key, which should be readable only by root or the
nginxuser. - Forgetting to reload or restart
nginxafter 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 -nodesto avoid passphrase prompts. - Store private keys securely with restricted permissions.
- Configure
nginxwithssl_certificateandssl_certificate_keydirectives. - Redirect HTTP to HTTPS for better security.
- Test configuration with
nginx -tbefore 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.