SSL Setup in Nginx and a 301 Redirect from HTTP to HTTPS
Nginx is one of the most widely preferred web servers in the world thanks to its performance and low memory usage. In this guide, we'll show you how to configure a free SSL certificate in Nginx and how to redirect all HTTP traffic to secure HTTPS, complete with a full server block example.
Required files
Nginx expects the certificate and the intermediate chain in a single combined file. The fullchain.pem is ideal for this; it holds your certificate and the CA chain together. You also need private.key as the private key.
fullchain.pem→ certificate + intermediate chain (ssl_certificate)private.key→ private key (ssl_certificate_key)
If you don't have these two files, verify your domain with our free SSL wizard and take the fullchain.pem and private.key files from the ZIP package you download.
Step 1 — Upload the files to the server
Copy the files to a secure directory and tighten the permissions. It is critical that the private key is readable only by root:
sudo mkdir -p /etc/nginx/ssl/yourdomain.com
sudo cp fullchain.pem /etc/nginx/ssl/yourdomain.com/
sudo cp private.key /etc/nginx/ssl/yourdomain.com/
sudo chmod 600 /etc/nginx/ssl/yourdomain.com/private.key
Step 2 — Configure the server block
Open your site's configuration file (e.g., /etc/nginx/sites-available/yourdomain.com). The example below contains two server blocks: one that redirects HTTP to HTTPS and one that serves TLS with secure settings:
# 1) Permanently move all HTTP requests to HTTPS
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}
# 2) HTTPS server
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/nginx/ssl/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/yourdomain.com/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
root /var/www/yourdomain.com;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
Step 3 — Test the configuration and reload
To catch syntax errors, always test before restarting Nginx:
sudo nginx -t
If the output says syntax is ok and test is successful, reload the service gracefully (without downtime):
sudo systemctl reload nginx
Step 4 — Verification
You can check from the command line that the redirect and the certificate are working:
# To see the 301 redirect header
curl -I http://yourdomain.com
# To verify that the certificate chain is fully served
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
In the first command, you should see HTTP/1.1 301 Moved Permanently and Location: https://.... In the second command, make sure the chain is listed completely, from the certificate down to the intermediate chain.
Common errors
- SSL_ERROR_BAD_CERT_DOMAIN: The
server_namedoesn't match the domain in the certificate. Ifwwwis included, write both names. - Missing intermediate chain: Don't use only
certificate.crtforssl_certificate; usefullchain.pem. - Permission error: If Nginx can't read the private key, check the
chmod 600and ownership settings.
Summary
SSL in Nginx comes down to defining ssl_certificate and ssl_certificate_key and having a separate block redirect all HTTP traffic to HTTPS with a 301. If you don't have a certificate, get your 90-day certificate with our free SSL wizard, extract the fullchain.pem and private.key files from the ZIP, and adapt the block above.