Skip to main content
    Installation Guide

    How to Install SSL Certificate on Nginx

    Complete guide to installing and configuring SSL/TLS certificates on Nginx web server. Covers HTTPS setup, HTTP/2, security headers, and reverse proxy configuration.

    My-SSL Security Team
    December 15, 2025
    18 min read

    Introduction to Nginx SSL Installation

    Nginx (pronounced "engine-x") is one of the world's most popular web servers, known for its high performance, stability, and low resource consumption. Installing an SSL certificate on Nginx secures your website with HTTPS encryption, protecting data transmitted between your server and visitors.

    This comprehensive guide covers SSL certificate installation on all Nginx versions, whether you're running on Ubuntu, CentOS, Debian, or other Linux distributions. We'll walk through every step from CSR generation to advanced SSL optimization techniques.

    What you'll learn:

    • How to generate a CSR using OpenSSL or My-SSL CSR Generator
    • Preparing certificate files for Nginx
    • Configuring SSL in Nginx server blocks
    • Setting up HTTP to HTTPS redirects
    • Advanced SSL security settings (HSTS, OCSP Stapling, HTTP/2)
    • Troubleshooting common SSL configuration errors

    For a foundational understanding of SSL, see our guide on What is SSL and How SSL Works.


    Prerequisites Checklist

    Before starting the SSL installation, ensure you have:

    • Nginx installed - Version 1.0.0 or higher (check with nginx -v)
    • Root or sudo access - Required to modify Nginx configuration
    • Domain pointed to server - DNS A record pointing to your server's IP address
    • OpenSSL installed - For CSR generation (check with openssl version)
    • SSL certificate files - Your certificate (.crt), private key (.key), and CA bundle
    • Text editor - nano, vim, or your preferred editor
    • Firewall access - Port 443 must be open for HTTPS traffic

    Verify Nginx installation:

    nginx -v
    # Output: nginx version: nginx/1.24.0

    Check OpenSSL version:

    openssl version
    # Output: OpenSSL 3.0.2 15 Mar 2022

    Step 1: Generate a Certificate Signing Request (CSR)

    A CSR contains your domain and organization information, which the Certificate Authority uses to issue your SSL certificate. You have two options for CSR generation.

    The easiest method is using our free CSR Generator Tool:

    1. Navigate to My-SSL CSR Generator
    2. Enter your domain name (e.g., yourdomain.com)
    3. Fill in organization details (name, city, state, country)
    4. Add Subject Alternative Names (SANs) for additional domains if needed
    5. Click Generate CSR
    6. Save both the CSR and Private Key files securely

    Important: Store your private key in a secure location. You'll need it during installation, and it should never be shared.

    Option B: Using OpenSSL Command Line

    Generate a CSR and private key directly on your server:

    # Create a directory for SSL files
    sudo mkdir -p /etc/nginx/ssl/yourdomain.com
    cd /etc/nginx/ssl/yourdomain.com
    
    # Generate private key and CSR
    sudo openssl req -new -newkey rsa:2048 -nodes \
      -keyout yourdomain.com.key \
      -out yourdomain.com.csr

    You'll be prompted to enter certificate details:

    Country Name (2 letter code) [AU]: US
    State or Province Name []: California
    Locality Name []: San Francisco
    Organization Name []: Your Company Inc
    Organizational Unit Name []: IT Department
    Common Name []: yourdomain.com
    Email Address []: admin@yourdomain.com

    **Verify your CSR using our CSR Decoder** to ensure all details are correct before submitting to a Certificate Authority.


    Step 2: Order Your SSL Certificate

    With your CSR ready, order an SSL certificate:

    1. Choose the appropriate certificate type:

    - DV SSL - Domain validation, fastest issuance

    - OV SSL - Organization validation, business trust

    - EV SSL - Extended validation, highest trust

    1. Submit your CSR during the order process
    2. Complete domain validation (email, DNS, or HTTP file)
    3. Download your certificate files once issued

    You'll typically receive:

    • Primary certificate (yourdomain.crt)
    • Intermediate/CA Bundle (ca-bundle.crt or intermediate.crt)
    • Root certificate (optional, usually trusted by browsers)

    Learn more about SSL Certificate Types to choose the right option.


    Step 3: Prepare Certificate Files for Nginx

    Nginx requires the certificate and intermediate certificates combined into a single file. This is called a certificate chain or bundle.

    Create the Certificate Bundle

    Combine your certificate with the CA bundle (order matters - your certificate first):

    # Navigate to SSL directory
    cd /etc/nginx/ssl/yourdomain.com
    
    # Combine certificate and CA bundle
    cat yourdomain.crt ca-bundle.crt > yourdomain-fullchain.crt

    Alternative method using echo:

    cat yourdomain.crt > yourdomain-fullchain.crt
    cat ca-bundle.crt >> yourdomain-fullchain.crt

    Verify the Certificate Chain

    Ensure your certificate chain is valid:

    openssl verify -CAfile ca-bundle.crt yourdomain.crt
    # Expected output: yourdomain.crt: OK

    Or use our SSL Checker Tool after installation to verify the complete chain.

    Set Proper File Permissions

    Secure your private key with restricted permissions:

    # Set ownership
    sudo chown root:root /etc/nginx/ssl/yourdomain.com/*
    
    # Restrict private key permissions
    sudo chmod 600 /etc/nginx/ssl/yourdomain.com/yourdomain.com.key
    sudo chmod 644 /etc/nginx/ssl/yourdomain.com/yourdomain-fullchain.crt

    Step 4: Configure Nginx Server Block for SSL

    Now configure Nginx to use your SSL certificate. Edit your site's server block configuration.

    Locate Your Nginx Configuration

    Configuration files are typically in:

    • Ubuntu/Debian: /etc/nginx/sites-available/ or /etc/nginx/conf.d/
    • CentOS/RHEL: /etc/nginx/conf.d/
    • Main config: /etc/nginx/nginx.conf

    Basic SSL Server Block Configuration

    Create or edit your site configuration:

    sudo nano /etc/nginx/sites-available/yourdomain.com

    Add the following SSL configuration:

    # HTTP - Redirect to HTTPS
    server {
        listen 80;
        listen [::]:80;
        server_name yourdomain.com www.yourdomain.com;
        
        # Redirect all HTTP traffic to HTTPS
        return 301 https://$server_name$request_uri;
    }
    
    # HTTPS Server Block
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name yourdomain.com www.yourdomain.com;
        
        # SSL Certificate Files
        ssl_certificate /etc/nginx/ssl/yourdomain.com/yourdomain-fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/yourdomain.com/yourdomain.com.key;
        
        # SSL Configuration
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_prefer_server_ciphers off;
        
        # SSL Session Settings
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        
        # Root directory and index
        root /var/www/yourdomain.com/html;
        index index.html index.htm index.php;
        
        # Logging
        access_log /var/log/nginx/yourdomain.com.access.log;
        error_log /var/log/nginx/yourdomain.com.error.log;
        
        location / {
            try_files $uri $uri/ =404;
        }
    }

    Enable the Site (Ubuntu/Debian)

    If using sites-available/sites-enabled structure:

    # Create symbolic link to enable site
    sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
    
    # Remove default site if exists
    sudo rm /etc/nginx/sites-enabled/default

    Step 5: Test Configuration and Restart Nginx

    Before restarting Nginx, always test the configuration for syntax errors.

    Test Nginx Configuration

    sudo nginx -t

    Expected output:

    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    If you see errors, check the error message and fix the configuration before proceeding.

    Restart Nginx

    Apply the changes by restarting or reloading Nginx:

    # Reload (recommended - no downtime)
    sudo systemctl reload nginx
    
    # Or full restart
    sudo systemctl restart nginx
    
    # For older systems without systemd
    sudo service nginx reload

    Verify SSL Installation

    1. Browser test: Visit https://yourdomain.com and check for the padlock icon
    2. SSL Checker: Use our SSL Checker Tool to verify the complete certificate chain
    3. Command line test:
    openssl s_client -connect yourdomain.com:443 -servername yourdomain.com

    Step 6: Advanced SSL Security Settings

    Enhance your SSL configuration with additional security headers and optimizations.

    Enable HSTS (HTTP Strict Transport Security)

    HSTS tells browsers to always use HTTPS for your domain:

    # Add inside your HTTPS server block
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

    Warning: Only enable HSTS after confirming HTTPS works correctly. The preload directive is permanent.

    Enable OCSP Stapling

    OCSP Stapling improves SSL handshake performance:

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    
    # CA certificate for OCSP verification
    ssl_trusted_certificate /etc/nginx/ssl/yourdomain.com/ca-bundle.crt;
    
    # Resolver for OCSP
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    Additional Security Headers

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    Complete Optimized Configuration

    Here's a complete, production-ready SSL configuration:

    server {
        listen 80;
        listen [::]:80;
        server_name yourdomain.com www.yourdomain.com;
        return 301 https://$server_name$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name yourdomain.com www.yourdomain.com;
        
        # SSL Certificate
        ssl_certificate /etc/nginx/ssl/yourdomain.com/yourdomain-fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/yourdomain.com/yourdomain.com.key;
        
        # Modern SSL Configuration
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        ssl_prefer_server_ciphers off;
        
        # SSL Session
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets off;
        
        # OCSP Stapling
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/nginx/ssl/yourdomain.com/ca-bundle.crt;
        resolver 8.8.8.8 8.8.4.4 valid=300s;
        resolver_timeout 5s;
        
        # Security Headers
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
        
        # Your website configuration
        root /var/www/yourdomain.com/html;
        index index.html index.htm;
        
        location / {
            try_files $uri $uri/ =404;
        }
    }

    Installing Wildcard SSL on Nginx

    Wildcard certificates secure your main domain and all subdomains (*.yourdomain.com).

    Wildcard Certificate Configuration

    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        
        # Wildcard covers all subdomains
        server_name yourdomain.com *.yourdomain.com;
        
        ssl_certificate /etc/nginx/ssl/yourdomain.com/wildcard-fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/yourdomain.com/wildcard.key;
        
        # ... rest of SSL configuration
    }

    Multiple Subdomains with Single Certificate

    Configure different roots for different subdomains:

    # Main domain
    server {
        listen 443 ssl http2;
        server_name yourdomain.com www.yourdomain.com;
        ssl_certificate /etc/nginx/ssl/wildcard-fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/wildcard.key;
        root /var/www/yourdomain.com;
    }
    
    # Blog subdomain
    server {
        listen 443 ssl http2;
        server_name blog.yourdomain.com;
        ssl_certificate /etc/nginx/ssl/wildcard-fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/wildcard.key;
        root /var/www/blog.yourdomain.com;
    }
    
    # API subdomain
    server {
        listen 443 ssl http2;
        server_name api.yourdomain.com;
        ssl_certificate /etc/nginx/ssl/wildcard-fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/wildcard.key;
        root /var/www/api.yourdomain.com;
    }

    Learn more about Wildcard SSL Certificates and their benefits.


    Nginx as Reverse Proxy with SSL

    Configure Nginx as an SSL-terminating reverse proxy for backend applications.

    Basic Reverse Proxy Configuration

    server {
        listen 443 ssl http2;
        server_name yourdomain.com;
        
        ssl_certificate /etc/nginx/ssl/yourdomain.com/fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/yourdomain.com/private.key;
        
        # SSL settings...
        
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            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 $scheme;
            proxy_cache_bypass $http_upgrade;
        }
    }

    SSL Termination for Multiple Backend Services

    upstream backend_app {
        server 127.0.0.1:3000;
        server 127.0.0.1:3001;
    }
    
    server {
        listen 443 ssl http2;
        server_name yourdomain.com;
        
        ssl_certificate /etc/nginx/ssl/fullchain.crt;
        ssl_certificate_key /etc/nginx/ssl/private.key;
        
        location / {
            proxy_pass http://backend_app;
            # proxy headers...
        }
    }

    Let's Encrypt vs Purchased SSL for Nginx

    | Feature | Let's Encrypt (Certbot) | Purchased SSL |

    |---------|------------------------|---------------|

    | Cost | Free | Starting at $2.99/year |

    | Validity | 90 days | 1-2 years |

    | Renewal | Automatic (cron job) | Manual or reminder-based |

    | Validation Types | DV only | DV, OV, EV available |

    | Warranty | None | Up to $1.75M |

    | Wildcard | Requires DNS validation | Easy ordering |

    | Support | Community forums | Professional support |

    | Trust Level | Standard | Higher with OV/EV |

    Installing Certbot for Let's Encrypt

    # Ubuntu/Debian
    sudo apt update
    sudo apt install certbot python3-certbot-nginx
    
    # CentOS/RHEL
    sudo yum install certbot python3-certbot-nginx
    
    # Obtain certificate
    sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
    
    # Test auto-renewal
    sudo certbot renew --dry-run

    When to choose purchased SSL:

    • Need OV or EV validation for business trust
    • Require warranty protection
    • Want longer validity periods
    • Need professional technical support
    • Corporate compliance requirements

    Browse our SSL Certificate options for competitive pricing.


    Troubleshooting Common Nginx SSL Errors

    Error: "ssl_certificate" directive is duplicate

    Cause: Multiple ssl_certificate directives in the same server block.

    Solution: Remove duplicate directives, keep only one certificate path.

    Error: "cannot load certificate"

    Cause: Certificate file path incorrect or file permissions wrong.

    Solution:

    # Check file exists
    ls -la /etc/nginx/ssl/yourdomain.com/
    
    # Check permissions
    sudo chmod 644 /etc/nginx/ssl/yourdomain.com/*.crt
    sudo chmod 600 /etc/nginx/ssl/yourdomain.com/*.key

    Error: "PEM_read_bio" or key mismatch

    Cause: Private key doesn't match the certificate.

    Solution: Verify key-certificate match using our Key Matcher Tool:

    # Compare modulus values
    openssl x509 -noout -modulus -in yourdomain.crt | openssl md5
    openssl rsa -noout -modulus -in yourdomain.key | openssl md5
    # Both should output the same hash

    Error: "certificate chain incomplete"

    Cause: Intermediate certificates not included in the certificate file.

    Solution:

    # Recreate the certificate chain
    cat yourdomain.crt intermediate.crt root.crt > fullchain.crt

    Use our SSL Checker to verify the complete chain.

    Error: "nginx: [emerg] bind() to 0.0.0.0:443 failed"

    Cause: Port 443 already in use or permissions issue.

    Solution:

    # Check what's using port 443
    sudo netstat -tlnp | grep 443
    # or
    sudo ss -tlnp | grep 443
    
    # Stop conflicting service or change Nginx config

    SSL Handshake Failed

    Cause: Protocol or cipher mismatch, firewall blocking.

    Solution:

    # Test SSL connection
    openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
    
    # Check firewall
    sudo ufw status
    sudo ufw allow 443/tcp

    Certificate Not Trusted in Browser

    Cause: Missing intermediate certificates.

    Solution:

    1. Download intermediate certificates from your CA
    2. Append them to your certificate file
    3. Reload Nginx: sudo nginx -s reload

    Mixed Content Warnings

    Cause: Page loads HTTP resources over HTTPS.

    Solution:

    • Update all resource URLs to use HTTPS or protocol-relative URLs
    • Use Content-Security-Policy header to upgrade insecure requests:
    add_header Content-Security-Policy "upgrade-insecure-requests" always;

    SSL Certificate Renewal on Nginx

    Manual Renewal Process

    1. Generate new CSR (or reuse existing if key is unchanged)
    2. Order renewal certificate from CA
    3. Download new certificate files
    4. Replace old certificate files:
    sudo cp new-certificate.crt /etc/nginx/ssl/yourdomain.com/fullchain.crt
    1. Test and reload Nginx:
    sudo nginx -t && sudo nginx -s reload

    Set Up Expiry Reminders

    Don't let certificates expire unexpectedly! Use our free SSL Expiry Reminder service to receive email notifications before your certificate expires.


    Best Practices for Nginx SSL

    1. Use TLS 1.2 and 1.3 only - Disable older, insecure protocols
    2. Enable HTTP/2 - Improved performance over HTTPS
    3. Implement HSTS - Force HTTPS for returning visitors
    4. Enable OCSP Stapling - Faster certificate validation
    5. Use strong ciphers - Follow Mozilla's recommendations
    6. Monitor certificate expiry - Set up SSL reminders
    7. Regular security audits - Test with SSL Checker
    8. Keep Nginx updated - Security patches and new features
    9. Backup certificates - Store copies securely offsite
    10. Document configurations - Maintain clear documentation

    For more security concepts, read about Public Key Infrastructure (PKI).


    Frequently Asked Questions

    Recommended

    Secure Your Nginx Server Today

    Get a trusted SSL certificate for your Nginx web server with fast issuance and expert support.

    DV SSL Certificate

    Starting at $2.99/year

    • Domain Validation
    • 5-Min Issuance
    • Unlimited Server Licenses
    • 99.9% Browser Trust
    Get SSL Certificate

    Let's Encrypt vs Purchased SSL Comparison

    FeatureLet's EncryptPurchased SSL
    CostFreeFrom $2.99/year
    Validity Period90 days1-2 years
    RenewalAutomatic (Certbot)Manual / Reminder-based
    Validation TypesDV onlyDV, OV, EV
    WarrantyNoneUp to $1.75M
    SupportCommunity forumsProfessional support
    Best ForPersonal sites, testingBusiness, e-commerce

    Frequently Asked Questions

    Recommended

    Need a Wildcard SSL for Multiple Subdomains?

    Secure unlimited subdomains with a single Wildcard SSL certificate. Perfect for complex Nginx configurations.

    Wildcard DV SSL

    Starting at $29.99/year

    • Unlimited Subdomains
    • Domain Validation
    • Quick Issuance
    • $10,000 Warranty
    Get Wildcard SSL

    Never Forget Certificate Renewals

    Set up free email reminders before your SSL certificate expires. Get notified 30, 14, 7, and 1 day before expiration.

    Set Up Free Reminders