This guide covers certificate installation, HTTPS redirects, and TLS configuration for NGINX so you can deploy HTTPS reliably.
1. Preparation
1. Obtain an SSL/TLS certificate
Before configuring NGINX, prepare:
- A certificate issued through CertOne, Let's Encrypt, or another provider
- A certificate file (.crt or .pem)
- A private key file (.key)
- The intermediate chain file (chain.crt), if required
2. Upload certificate files
Upload the files to your server:
# Create the certificate directory.
sudo mkdir -p /etc/nginx/ssl
# Upload the certificate files.
sudo cp certificate.crt /etc/nginx/ssl/
sudo cp private.key /etc/nginx/ssl/
sudo cp chain.crt /etc/nginx/ssl/
# Set file permissions.
sudo chmod 600 /etc/nginx/ssl/private.key
sudo chmod 644 /etc/nginx/ssl/certificate.crt
sudo chmod 644 /etc/nginx/ssl/chain.crt
2. Basic TLS configuration
1. Edit the site configuration
Edit the site file, usually under /etc/nginx/sites-available/:
sudo nano /etc/nginx/sites-available/example.com
2. Add TLS settings
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# Certificate settings
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
# Trusted chain for verification where needed
ssl_trusted_certificate /etc/nginx/ssl/chain.crt;
# TLS protocol configuration
ssl_protocols TLSv1.2 TLSv1.3;
# TLS cipher suites
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
# Add the remaining site configuration here.
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
3. Test the configuration
# Test NGINX configuration.
sudo nginx -t
# Reload NGINX if the test passes.
sudo systemctl reload nginx
Redirect HTTP requests to HTTPS
1. Redirect HTTP
# HTTP server block: redirect to HTTPS.
server {
listen 80;
server_name example.com www.example.com;
# Redirect all HTTP requests to HTTPS.
return 301 https://$server_name$request_uri;
}
# HTTPS server block
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# Add the remaining TLS settings here.
}
2. Enable HSTS
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# Add the remaining TLS settings here.
# HSTS(HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Add the remaining site configuration here.
}
4. TLS optimization
1. Complete security configuration
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# TLS certificate
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
ssl_trusted_certificate /etc/nginx/ssl/chain.crt;
# TLS protocols
ssl_protocols TLSv1.2 TLSv1.3;
# TLS 1.2 cipher suites; TLS 1.3 uses separate configuration.
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';
ssl_prefer_server_ciphers off;
# TLS session cache
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_stapling_file /etc/nginx/ssl/chain.crt;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" 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;
# Add the remaining site configuration here.
}
2. Performance settings
# Add to the http block to apply across server blocks.
http {
# TLS optimization
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# Add the remaining site configuration here.
}
5. Multiple domains
1. One certificate for multiple domains
server {
listen 443 ssl http2;
server_name example.com www.example.com api.example.com;
# Add the remaining TLS settings here.
}
2. Multiple certificates
# First domain
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# Add the remaining site configuration here.
}
# Second domain
server {
listen 443 ssl http2;
server_name another.com;
ssl_certificate /etc/nginx/ssl/another.com.crt;
ssl_certificate_key /etc/nginx/ssl/another.com.key;
# Add the remaining site configuration here.
}
6. Wildcard configuration
1. Wildcard subdomains
server {
listen 443 ssl http2;
server_name *.example.com;
# Add the remaining TLS settings here.
ssl_certificate /etc/nginx/ssl/wildcard.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.example.com.key;
# Add the remaining site configuration here.
}
2. Wildcard and apex domain
# Primary domain
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# Add the remaining site configuration here.
}
# Wildcard subdomains
server {
listen 443 ssl http2;
server_name *.example.com;
ssl_certificate /etc/nginx/ssl/wildcard.example.com.crt;
ssl_certificate_key /etc/nginx/ssl/wildcard.example.com.key;
# Add the remaining site configuration here.
}
7. Troubleshooting
1. Incomplete certificate chain
Problem: the browser reports an untrusted certificate.
Resolution:
# Use the full-chain file.
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_trusted_certificate /etc/nginx/ssl/chain.crt;
2. Mixed-content warnings
Problem: an HTTPS page loads HTTP resources.
Resolution:
# Enable a Content Security Policy.
add_header Content-Security-Policy "upgrade-insecure-requests" always;
3. TLS handshake failures
Problem: the client cannot establish a TLS connection.
Resolution:
- Check configured TLS versions
- Check cipher suites
- Check firewall settings
- Review the NGINX error log
8. Test TLS configuration
1. Test with SSL Labs
Visit https://www.ssllabs.com/ssltest/, enter your domain, and review the TLS configuration grade.
2. Command-line testing
# Test the TLS connection.
openssl s_client -connect example.com:443 -servername example.com
# Inspect certificate details.
openssl x509 -in /etc/nginx/ssl/certificate.crt -text -noout
3. Check HTTP/2
# Check HTTP/2 support.
curl -I --http2 https://example.com
9. Automatic renewal
1. Renew automatically with CertOne
For certificates issued through CertOne:
- Enable automatic renewal in CertOne
- Configure automatic deployment to the server
- Renewed certificates will be deployed automatically
2. Renew with acme.sh
# acme.sh installs a renewal cron job.
# Reload NGINX after renewal.
~/.acme.sh/acme.sh --install-cert -d example.com \
--reloadcmd "systemctl reload nginx"
3. Renew with Certbot
# Test automatic renewal.
sudo certbot renew --dry-run
# Certbot packages may install a systemd renewal timer.
Best practices
1. Security configuration
- ✅ Use TLS 1.2 or later
- ✅ Disable insecure cipher suites
- ✅ Enable HSTS
- ✅ Enable OCSP stapling when supported by the certificate's CA
- ✅ Configure security response headers
2. Performance optimization
- ✅ Enable HTTP/2
- ✅ Configure TLS session caching
- ✅ Use strong encryption with appropriate resource requirements
- ✅ Use OCSP stapling where supported to reduce latency
3. Certificate management
- ✅ Renew certificates regularly
- ✅ Monitor certificate expiration
- ✅ Back up certificates and private keys
- ✅ Use automated certificate management tools
Conclusion
Correct NGINX TLS configuration protects website traffic. This guide covers how to:
- ✅ Install and configure certificates
- ✅ Optimize TLS security settings
- ✅ Configure HTTP-to-HTTPS redirects
- ✅ Enable HSTS and supported OCSP stapling
- ✅ Automate certificate renewal
Renew certificates regularly and monitor your TLS settings. CertOne offers free certificate issuance, certificate management, and automatic deployment.