In this tutorial, we'll learn how to install and configure Nginx with SSL on a KVM VPS. Secure it with Let’s Encrypt SSL certificates, and optimize some of the basic settings. This tutorial performed on Ubuntu 24.04 server.
Prerequisites
- A Ubuntu 24.04 installed dedicated server or KVM VPS.
- A root user or normal user with administrative privileges.
- A domain name point A record to server's IP
1. Preparation
Server Updates: It is a best practice to update your VPS packages before installing new software:
sudo apt update && sudo apt upgrade -y
2. Installing Nginx
Most Linux distributions provide Nginx in their official package repositories. On Ubuntu/Debian:
sudo apt install nginx -y
2.1 Verifying Nginx Status
After the installation completes, check whether Nginx is running and enabled:
sudo systemctl status nginx
You should see an output indicating that nginx is “active (running).” If it is inactive, start and enable Nginx with:
sudo systemctl start nginx
sudo systemctl enable nginx
2.2 Firewall Configuration
If you are using UFW on Ubuntu/Debian, allow HTTP and HTTPS traffic:
sudo ufw allow 'Nginx HTTP'
sudo ufw allow 'Nginx HTTPS'
Confirm that the rules are applied:
sudo ufw status
You should see rules for 80/tcp
and 443/tcp
.
3. Obtaining and Installing Let’s Encrypt SSL Certificates
Let’s Encrypt provides free SSL/TLS certificates. To manage the certificate issuance and renewal, you will use Certbot.
3.1 Install Certbot
sudo apt install certbot python3-certbot-nginx -y
If you are on a different distribution, Certbot might be packaged differently, or you might have to download it from the snap package or EPEL repository (for CentOS-based systems). But in most Ubuntu/Debian systems, certbot and python3-certbot-nginx are sufficient.
3.2 Configure a Server Block (Optional but Recommended)
Before you request a certificate, it is best practice to set up an Nginx server block (virtual host configuration) for your domain. Let’s say your domain is example.com
; create a configuration file in /etc/nginx/sites-available/
:
sudo nano /etc/nginx/sites-available/example.com
Insert something like this basic configuration:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com; # Path to your web root folder
index index.html index.htm; # Or index.php if you use PHP
location / {
try_files $uri $uri/ =404;
}
}
Then enable this configuration by creating a symbolic link to /etc/nginx/sites-enabled/
:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Make sure that /var/www/example.com/
exists:
sudo mkdir -p /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
Finally, test Nginx configuration syntax and reload:
sudo nginx -t
sudo systemctl reload nginx
3.3 Obtain Let’s Encrypt SSL Certificate
Now that your domain is served on HTTP port 80, Certbot can verify ownership of the domain. Issue the certificate by running:
sudo certbot --nginx -d example.com -d www.example.com
Certbot will:
- Ask for an email address (for expiry notices).
- Ask whether you agree to the terms of service.
When finished, you can verify by visiting https://example.com
in your browser. You should see a valid SSL padlock in the URL bar.
3.4 Automatic Certificate Renewal
Let’s Encrypt certificates are valid for 90 days. The package certbot should install a systemd timer or a cron job by default that automates renewal. Confirm your renewal timer:
systemctl list-timers | grep certbot
or
sudo certbot renew --dry-run
The --dry-run
test verifies that everything is properly configured. If successful, you do not need to do anything else for renewal.
4. Basic Nginx SSL Configuration and Security Best Practices
Now that you have a valid SSL certificate, you should refine your Nginx configurations to increase security and performance.
4.1 Enforce Strong TLS Protocols
By default, Nginx supports multiple TLS versions. Modern best practice is to enable TLS 1.2 and TLS 1.3 only, disabling older protocols (TLS 1.0, 1.1). Inside your server block that handles SSL (/etc/nginx/sites-available/example.com
or in a broader /etc/nginx/nginx.conf
SSL configuration segment), adjust the SSL directives:
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
You can fetch updated ciphers from the Mozilla SSL Configuration Generator.
4.2 HTTP Strict Transport Security (HSTS)
HSTS forces clients to use HTTPS for a specified period. This can prevent certain man-in-the-middle attacks. Add it to your server block:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Note: Once you enable HSTS with a high max-age, browsers will remember it. If you later decide to revert to HTTP or change domains/subdomains, be aware that HSTS remains cached.
4.3 OCSP Stapling
To speed up certificate verification, enable OCSP Stapling. You need the fullchain and trusted CA certificate from Let’s Encrypt:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s; # Example resolvers
resolver_timeout 5s;
4.4 Enable HTTP/2
For better performance over SSL, enable HTTP/2:
listen 443 ssl http2;
Then reload Nginx:
sudo systemctl reload nginx
5. Basic Nginx Performance Tuning
5.1 Adjust Worker Processes
Edit the main configuration file /etc/nginx/nginx.conf
to set worker processes and connections. By default, Nginx sets them automatically. A common baseline is:
worker_processes auto;
events {
worker_connections 1024;
}
- worker_processes auto;: Detects the number of CPU cores and assigns worker processes automatically.
- worker_connections 1024;: The number of connections each worker can handle.
5.2 Gzip Compression
You can enable Gzip compression to reduce bandwidth usage:
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;
gzip_vary on;
Place these directives in the http block of /etc/nginx/nginx.conf
or in a separate file included by the http block.
5.3 Caching Static Files
If you serve static assets (images, CSS, JS), you can set caching headers:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
Place this inside your server block for optimal performance with static files.
6. Testing Your Configuration
Nginx Syntax: Before you reload or restart Nginx, always test the configuration:
sudo nginx -t
Fix any syntax errors or typos reported.
Service Reload: After updates:
sudo systemctl reload nginx
or
sudo systemctl restart nginx
Browser Test: Visit https://example.com
and confirm that the padlock icon is present, and that you’re being redirected from HTTP to HTTPS if you attempt to connect over http://example.com
.
SSL Labs Test: (Optional) If internet access was available, you could test your site using SSL Labs’ SSL Server Test. Aim for an A rating or higher. Since direct external web access isn’t possible here, keep this as a general best practice recommendation.
7. Maintenance and Updates
Nginx Updates: Keep your system and Nginx updated:
sudo apt update && sudo apt upgrade -y
Certificate Renewal: Check periodically that Certbot’s renewal is successful. If you receive emails about upcoming certificate expiration, try sudo certbot renew manually to see if it works, or troubleshoot any issues.
Log Rotation: Nginx logs typically rotate automatically via /etc/logrotate.d/nginx
. Confirm that logs are rotating properly to avoid large log files.
Monitor Performance: Tools like htop, top, or netstat can help monitor usage. If your site receives high traffic, you may need to tune worker connections, caching, or spin up more CPU cores and memory on your VPS.
8. Summary
- Install Nginx from your distribution’s repository and enable it.
- Open Firewall Ports to allow web traffic on ports 80 and 443.
- Install Certbot and use it to obtain a Let’s Encrypt certificate, configuring Nginx automatically.
- Optimize SSL to use modern protocols like TLS 1.2 and 1.3, enable OCSP Stapling, and consider HTTP/2.
- Enhance Security with HSTS and carefully select SSL ciphers for a strong security posture.
- Optimize Nginx with the right number of worker processes, gzip compression, and caching for static files.
- Keep Everything Updated: Nginx, Certbot, and your system for security patches, performance improvements, and reliability.
Following these steps will result in a secure, performant, and well-maintained Nginx server. This forms a solid foundation for hosting web applications or static websites with HTTPS enabled by default, which is the modern standard for web security.
Additional Tips
Backup Configuration: Always keep a backup of your main config files (in /etc/nginx/ and /etc/letsencrypt/) in case you need to revert.
Least Privilege Principle: Use a non-root user for routine operations and limit service permissions as much as possible.
Monitoring: Setting up server monitoring (using tools like Prometheus, Grafana, or Nagios) helps you catch potential issues early (high CPU, memory usage, etc.).
Auto Renewal Checking: You can set up an email alert (or any other alerting mechanism) if for some reason renewal fails.
With these best practices and configurations, your KVM VPS should deliver content securely and efficiently. If you need advanced configuration (like load balancing, reverse proxy, or advanced caching strategies), Nginx offers a wide array of features you can explore in the official documentation.
Check out robust data center services in New Zealand