BLOG POSTS
    MangoHost Blog / How to Create a Self-Signed SSL Certificate for Nginx in Ubuntu 24
How to Create a Self-Signed SSL Certificate for Nginx in Ubuntu 24

How to Create a Self-Signed SSL Certificate for Nginx in Ubuntu 24

Setting up a self-signed SSL certificate for Nginx on Ubuntu 24 is a common requirement for development environments, internal applications, or testing scenarios where purchasing commercial certificates isn’t practical. While self-signed certificates won’t be trusted by browsers without manual intervention, they provide the same level of encryption as commercial certificates and are perfect for securing local development environments or internal services. This guide walks you through creating self-signed SSL certificates, configuring Nginx to use them, and addressing the common issues you’ll encounter along the way.

How Self-Signed SSL Certificates Work

Self-signed certificates function identically to commercial SSL certificates in terms of encryption, but they lack validation from a trusted Certificate Authority (CA). When you create a self-signed certificate, you’re acting as your own CA, which means browsers will display security warnings until you manually trust the certificate.

The process involves generating a private key and using it to create a certificate signing request (CSR), then signing that request with your own private key instead of sending it to a commercial CA. The resulting certificate contains your server’s public key and identifying information, enabling encrypted communication between clients and your server.

Prerequisites and System Preparation

Before diving into certificate creation, ensure your Ubuntu 24 system has the necessary tools installed. OpenSSL comes pre-installed on most Ubuntu distributions, but verify its availability:

openssl version -a

If OpenSSL isn’t installed, grab it with:

sudo apt update
sudo apt install openssl

You’ll also need Nginx installed and running. Install it if you haven’t already:

sudo apt install nginx
sudo systemctl start nginx
sudo systemctl enable nginx

Step-by-Step Certificate Creation

Creating a self-signed certificate involves generating a private key and certificate in one command. Navigate to Nginx’s SSL directory first:

sudo mkdir -p /etc/nginx/ssl
cd /etc/nginx/ssl

Generate both the private key and certificate simultaneously:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/ssl/server.key \
    -out /etc/nginx/ssl/server.crt

This command will prompt you for several pieces of information. Here’s what each field means and suggested values for development:

  • Country Name: Your two-letter country code (US, CA, UK, etc.)
  • State/Province: Full state or province name
  • City/Locality: Your city name
  • Organization Name: Your company or personal name
  • Organizational Unit: Department name (optional, can press Enter)
  • Common Name: Most important – use your domain name or server IP
  • Email Address: Your email (optional)

For automated generation without prompts, use this one-liner:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/ssl/server.key \
    -out /etc/nginx/ssl/server.crt \
    -subj "/C=US/ST=YourState/L=YourCity/O=YourOrg/CN=yourdomain.com"

Set appropriate permissions on your certificate files:

sudo chmod 600 /etc/nginx/ssl/server.key
sudo chmod 644 /etc/nginx/ssl/server.crt

Nginx Configuration for SSL

With certificates generated, configure Nginx to use them. Create a new server block or modify an existing one. Here’s a complete configuration example:

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

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;

    # SSL Configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    # HSTS (Optional)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

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

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

Save this configuration to /etc/nginx/sites-available/your-site and create a symbolic link:

sudo ln -s /etc/nginx/sites-available/your-site /etc/nginx/sites-enabled/

Test the configuration and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Advanced Certificate Options

For production-like development environments, consider creating certificates with Subject Alternative Names (SAN) to support multiple domains:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout /etc/nginx/ssl/server.key \
    -out /etc/nginx/ssl/server.crt \
    -config <(
    echo '[distinguished_name]'
    echo 'CN=yourdomain.com'
    echo '[req]'
    echo 'distinguished_name=distinguished_name'
    echo '[v3_req]'
    echo 'keyUsage=keyEncipherment,dataEncipherment'
    echo 'extendedKeyUsage=serverAuth'
    echo 'subjectAltName=@alt_names'
    echo '[alt_names]'
    echo 'DNS.1=yourdomain.com'
    echo 'DNS.2=www.yourdomain.com'
    echo 'DNS.3=localhost'
    echo 'IP.1=127.0.0.1'
    ) -extensions v3_req

For stronger security, generate 4096-bit keys instead of 2048-bit:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 \
    -keyout /etc/nginx/ssl/server.key \
    -out /etc/nginx/ssl/server.crt

Real-World Use Cases and Examples

Self-signed certificates excel in several scenarios where commercial certificates are unnecessary or impractical:

  • Development Environments: Testing HTTPS functionality locally without purchasing certificates
  • Internal Applications: Securing intranet applications where all users can trust the certificate manually
  • API Testing: Developing applications that require HTTPS endpoints for webhooks or integrations
  • Docker Containers: Containerized applications that need SSL termination at the application level
  • Load Balancer Backend: Encrypting traffic between load balancers and backend servers

For development teams, consider creating a local Certificate Authority to issue certificates that can be trusted across team environments. This approach involves creating a root CA certificate and then issuing certificates signed by that CA.

Troubleshooting Common Issues

Several issues commonly arise when implementing self-signed certificates. Browser warnings are expected behavior - modern browsers display "Not Secure" or similar warnings for self-signed certificates. To bypass these warnings during development, you can:

  • Add certificate exceptions in your browser
  • Import the certificate into your system's trusted root store
  • Use browser flags like --ignore-certificate-errors for Chrome during testing

If Nginx fails to start after SSL configuration, check the error logs:

sudo journalctl -u nginx -f
sudo tail -f /var/log/nginx/error.log

Common configuration errors include incorrect file paths, permission issues, or syntax errors in the SSL configuration. Verify certificate files exist and have correct permissions:

sudo ls -la /etc/nginx/ssl/
sudo nginx -t

For "SSL: error:0200100D:system library:fopen:Permission denied" errors, ensure the nginx user can read the certificate files:

sudo chown root:root /etc/nginx/ssl/server.*
sudo chmod 644 /etc/nginx/ssl/server.crt
sudo chmod 600 /etc/nginx/ssl/server.key

Self-Signed vs Commercial Certificates Comparison

Feature Self-Signed Commercial
Cost Free $10-$1000+ annually
Browser Trust Manual trust required Automatic trust
Encryption Level Same as commercial Same as self-signed
Setup Time Minutes Hours to days
Validation None Domain/Organization/Extended
Expiration Management Manual renewal Automated with tools like Certbot
Use Case Development/Internal Production/Public

Performance and Security Considerations

Self-signed certificates don't impact performance differently than commercial certificates - the encryption overhead remains identical. However, consider these optimization strategies for SSL performance:

  • Enable HTTP/2 to reduce connection overhead
  • Configure SSL session caching to avoid repeated handshakes
  • Use modern cipher suites for better performance and security
  • Consider ECDSA certificates for better performance on mobile devices

The SSL configuration provided earlier includes performance optimizations like session caching and modern protocol support. Monitor SSL performance using tools like SSL Labs' SSL Test or OpenSSL's built-in speed testing:

openssl speed rsa2048
openssl speed ecdsa

Integration with Development Workflows

Incorporating self-signed certificates into development workflows streamlines HTTPS testing. Create a simple script to generate certificates for new projects:

#!/bin/bash
DOMAIN=$1
SSL_DIR="/etc/nginx/ssl"

if [ -z "$DOMAIN" ]; then
    echo "Usage: $0 domain.com"
    exit 1
fi

sudo mkdir -p $SSL_DIR

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
    -keyout $SSL_DIR/$DOMAIN.key \
    -out $SSL_DIR/$DOMAIN.crt \
    -subj "/C=US/ST=Dev/L=Local/O=Development/CN=$DOMAIN"

sudo chmod 600 $SSL_DIR/$DOMAIN.key
sudo chmod 644 $SSL_DIR/$DOMAIN.crt

echo "Certificate created for $DOMAIN"
echo "Key: $SSL_DIR/$DOMAIN.key"
echo "Certificate: $SSL_DIR/$DOMAIN.crt"

For teams working with container environments, consider mounting certificate volumes or using init containers to generate certificates automatically. This approach works particularly well with Docker Compose setups where multiple services need SSL certificates.

When working with modern development frameworks that require HTTPS for certain features (like service workers or secure cookies), self-signed certificates enable full feature testing without the complexity of obtaining commercial certificates for every development instance.

For more robust hosting solutions that can handle production SSL certificates and high-traffic applications, consider upgrading to dedicated infrastructure through VPS hosting or dedicated servers that provide the performance and reliability needed for production environments.

Self-signed certificates serve as an excellent stepping stone for understanding SSL/TLS concepts before moving to production environments with commercial certificates. The skills learned here translate directly to managing Let's Encrypt certificates, commercial SSL certificates, and enterprise PKI implementations.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked