Secure NGINX on Linux: A Clear, Step-by-Step SSL Configuration Guide
Lock down your Linux web server with confidence—this clear, step-by-step NGINX SSL configuration guide walks you through certificates, ciphers, and best practices so your site serves traffic over modern TLS. Perfect for webmasters, devs, and sysadmins who want practical commands, config snippets, and automation tips to keep HTTPS strong and hassle-free.
Introduction
Securing web traffic is a fundamental responsibility for any site owner, developer, or sysadmin. Transport Layer Security (TLS), commonly referred to as SSL, encrypts data in transit and authenticates your server to clients. NGINX is a widely used web server and reverse proxy on Linux, known for its performance and flexibility. This guide provides a clear, step-by-step approach to configuring robust TLS on NGINX running on a Linux VPS, with practical commands, configuration snippets, and operational best practices suited to webmasters, enterprise users, and developers.
How TLS Works with NGINX: Core Concepts
Before diving into configuration, it helps to understand the essentials:
- Certificates and Keys: A certificate (X.509) binds your domain to a public key; the private key stays on the server. Certificates are issued by Certificate Authorities (CAs) like Let’s Encrypt.
- TLS Handshake: Client and server negotiate protocol version, cipher suite, and exchange keys to establish an encrypted session. Modern TLS (1.2/1.3) offers forward secrecy and better performance.
- Chain of Trust: The server presents a certificate chain (leaf + intermediates). Clients validate the chain back to a trusted root.
- SNI (Server Name Indication): Allows serving multiple TLS-enabled domains from a single IP by including the requested hostname during handshake.
When to Use This Setup (Application Scenarios)
This guide fits multiple scenarios:
- Single-site or multi-site hosting on a VPS (including WordPress) where HTTPS is required.
- Reverse proxy setups where NGINX terminates TLS and forwards traffic to backend application servers.
- Production services requiring strong security (HSTS, OCSP stapling, modern ciphers) and automation for certificate issuance and renewal.
- Environments needing compliance or increased trust signals for users (e-commerce, SaaS, corporate portals).
Preparation: System and Package Installation
Commands below assume a Debian/Ubuntu or CentOS/RHEL family system. Adjust package manager commands accordingly.
1. Update system and install NGINX:
Debian/Ubuntu:
sudo apt update && sudo apt install -y nginx
CentOS/RHEL (using EPEL):
sudo yum install -y epel-release && sudo yum install -y nginx
2. Install Certbot (Let’s Encrypt client):
Debian/Ubuntu (recommended snap):
sudo snap install core && sudo snap refresh core
sudo snap install –classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
CentOS/RHEL:
sudo yum install -y certbot python3-certbot-nginx
3. Open ports on your firewall:
Allow HTTP (80) and HTTPS (443):
sudo ufw allow 80/tcp && sudo ufw allow 443/tcp
Step-By-Step TLS Configuration
1. Obtain a Certificate
For automatic NGINX integration:
sudo certbot –nginx -d example.com -d www.example.com
This instructs Certbot to obtain a certificate and modify your NGINX configuration to use it. For environments where you cannot expose port 80, use DNS validation (useful for wildcard certificates):
sudo certbot -d ‘*.example.com’ –manual –preferred-challenges dns certonly
2. Store and Protect Keys
Certificates and keys are typically stored in /etc/letsencrypt/live/example.com/. Ensure correct permissions:
sudo chmod 600 /etc/letsencrypt/live/example.com/privkey.pem
Do not copy private keys to insecure locations. If using automated backups, ensure the backup storage is encrypted.
3. NGINX Configuration: A Secure Example
Place this in your server block (e.g., /etc/nginx/sites-available/example.com):
<pre>
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Strong SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ‘ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:…’;
ssl_prefer_server_ciphers off; # TLS1.3 ignores ciphers
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# HSTS (enable only after verifying HTTPS works)
add_header Strict-Transport-Security “max-age=31536000; includeSubDomains; preload” always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
resolver_timeout 5s;
# Recommended Diffie-Hellman parameters (see next step)
ssl_dhparam /etc/ssl/certs/dhparam.pem;
root /var/www/example.com/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# redirect HTTP to HTTPS (see separate block)
}
</pre>
Replace the ssl_ciphers string with curated modern values (the example is abbreviated). Use cipher suites that provide forward secrecy and avoid RC4/3DES. For precise modern ciphers, refer to current Mozilla SSL Configuration Generator recommendations.
4. Generate a Strong DH Parameter File
Diffie-Hellman parameters improve security for ephemeral key exchanges. Generating 2048-bit takes time but is standard:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Alternatively, use a pre-generated safe file if generation time is a concern, but generating locally is preferable.
5. Redirect HTTP to HTTPS
Ensure plain HTTP redirects to HTTPS to avoid mixed content and insecure access:
<pre>
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
</pre>
6. Enable OCSP Stapling and Keep Certificates Fresh
OCSP stapling reduces certificate revocation check latency and improves privacy. NGINX needs the ssl_stapling directives shown earlier and a working resolver. Verify Apache or other processes do not interfere with UDP DNS resolution.
Let’s Encrypt certificates expire every 90 days—automate renewal and reloading NGINX:
Use a cron job or systemd timer (Certbot installs one by default). To test renewal:
sudo certbot renew –dry-run
If renewal requires reloading NGINX, Certbot will typically handle that. You can add a post-hook:
sudo certbot renew –deploy-hook “systemctl reload nginx”
Hardening and Additional Best Practices
- Disable TLS 1.0/1.1: Only enable TLS 1.2 and 1.3 for modern security and performance.
- Use HTTP/2: Enabled by using the http2 flag on the listen directive to improve multiplexing and latency.
- Enable Content Security Policy (CSP) and other headers: add headers like X-Content-Type-Options, X-Frame-Options, and Referrer-Policy where appropriate.
- Implement HSTS carefully: Start with a short max-age when first enabling, then increase once confident. Avoid preloading until you fully understand consequences.
- Use a Web Application Firewall (WAF): Consider ModSecurity with NGINX or upstream WAF services for additional filtering.
- Regularly test with SSL Labs: Use Qualys SSL Labs SSL Server Test to validate configuration and discover issues (protocols, chain problems, cipher weaknesses).
- Limit exposure of server info: set server_tokens off in nginx.conf and avoid revealing software versions.
- Protect private keys and backups: Store private keys on the server with tight permissions and ensure backups are encrypted.
- Consider client certificate authentication for internal services: Enable mutual TLS (mTLS) by configuring ssl_verify_client on appropriate locations.
Comparing Options: Managed vs Manual Certificates
Two main approaches exist for obtaining certificates:
- Managed CA (Let’s Encrypt via Certbot): Pros: free, automated renewal, widely supported. Cons: rate limits for high-volume issuance, limited lifetime (90 days) but automation mitigates this.
- Commercial CA (paid certificates or enterprise PKI): Pros: longer validity, organization validation (OV/EV) for stronger identity assertions, commercial support. Cons: cost, may require more manual lifecycle management unless using ACME-enabled services.
For most websites and small-to-medium businesses, Let’s Encrypt provides a very strong balance of security and automation. Enterprises requiring OV/EV certificates or special contractual assurances should evaluate paid CAs and certificate management platforms.
Practical Buying Advice for VPS and Hosting
Choosing the right VPS impacts performance and security operations. Look for:
- Up-to-date distributions and fast kernel/security patch cadence.
- Low network latency and reliable uplinks for TLS handshake performance.
- Ability to configure firewall rules, install certificates, and run background jobs (e.g., Certbot renewals).
- Good snapshot and backup options (ensure backups are encrypted).
- Responsive support with root-level access options, if needed for troubleshooting.
If you’re setting up TLS on a new VPS, consider providers that offer global POPs and predictable performance. For example, VPS.DO provides a range of hosting plans and USA-based VPS options suitable for running secure NGINX instances. Learn more: USA VPS at VPS.DO.
Summary
Configuring secure TLS on NGINX requires attention to certificate management, strong cipher and protocol selection, and operational practices like renewal automation and OCSP stapling. This guide covered practical steps: installing NGINX and Certbot, obtaining certificates, configuring a hardened NGINX server block, generating DH parameters, enforcing HTTP-to-HTTPS redirects, and ongoing maintenance. For most sites, Let’s Encrypt combined with automated renewal and a properly tuned NGINX configuration provides strong, modern security with minimal operational overhead.
Finally, consider your hosting environment carefully—select a VPS provider that supports timely software updates, adequate performance, and secure backup options to complement your NGINX TLS setup. If you need a hosting starting point, see the USA VPS plans at VPS.DO: https://vps.do/usa/.