Day 15: Deploying Nginx with SSL β Preparing App Server 3 for Secure Application Hosting πβ‘

Welcome back! π Day 15 of the 100 Days Cloud DevOps Challenge β today weβre shifting gears from Apache troubleshooting to setting up Nginx with HTTPS for a new application deployment on App Server 3 (stapp03).
This wasnβt just βinstall Nginx and drop a fileβ β the challenge required understanding SSL, Nginx server blocks, security practices, and connectivity validation from the jump host.
Letβs walk through the entire process in typical DevOps detective fashion. π΅οΈββοΈ
π₯ The Situation: New Application, New Requirements
The system admins at xFusionCorp Industries are preparing stapp03 for a new application launch.
Pre-requisites:
1οΈβ£ Install and configure Nginx
2οΈβ£ Move existing self-signed SSL cert + key
3οΈβ£ Configure HTTPS on port 443
4οΈβ£ Create a Welcome! landing page
5οΈβ£ Validate using:
curl -Ik https://stapp03/
Seems simpleβ¦ until you realize youβre working in a secure enterprise environment with strict expectations. So everything must be done cleanly, securely, and correctly.
π§ Why SSL Matters (And Why Nginx Is Ideal)
Modern applications must enforce:
π Encryption
π Data integrity
βοΈ Identity assurance
π Browser compatibility
Even if itβs a self-signed certificate, enabling HTTPS early ensures:
No insecure redirects
No plaintext credentials
No MITM risk
Proper production readiness
Nginx is preferred here because:
Event-driven model β faster concurrency
Lightweight footprint β ideal for app servers
First-class SSL/TLS support
Easy to manage server blocks
Designed for reverse proxy and modern workloads
πΊοΈ Nautilus Infrastructure Map
ββββββββββββββββββββββββββββ
β Jump Host β
β (thor@jumphost) β
βββββββββββββββ¬βββββββββββββ
|
| SSH / curl -Ik
|
βββββββββββββββΌββββββββββββββ
β App Server 3 β
β stapp03 β
β IP: 172.16.238.12 β
βββββββββββββββββββββββββββββ€
β Nginx (port 80, HTTPS 443)β
β SSL: nautilus.crt/key β
β Document Root: /usr/share β
βββββββββββββββββββββββββββββ
π§© Step 1: SSH into App Server 3
ssh banner@stapp03
sudo su -
Credentials work, weβre in.
π§© Step 2: Install Nginx
yum install -y nginx
systemctl enable nginx
systemctl start nginx
systemctl status nginx
Nginx starts successfully and begins listening on:
port 80
port 443 (after SSL block is added)
Verify:
ss -tulpn | grep nginx
π§© Step 3: Move SSL Certificate to a Secure Location
Given files:
/tmp/nautilus.crt/tmp/nautilus.key
Industry best practice β store under:
/etc/nginx/ssl/
So:
mkdir -p /etc/nginx/ssl
mv /tmp/nautilus.crt /etc/nginx/ssl/
mv /tmp/nautilus.key /etc/nginx/ssl/
chmod 600 /etc/nginx/ssl/nautilus.key
Why chmod 600?
Private keys must not be world-readable β Nginx will refuse insecure key permissions.
𧬠Step 4: Create SSL Server Block (HTTPS)
We do NOT modify nginx.conf.
Instead, we create a clean server block:
/etc/nginx/conf.d/ssl.conf
server {
listen 443 ssl;
server_name stapp03;
ssl_certificate /etc/nginx/ssl/nautilus.crt;
ssl_certificate_key /etc/nginx/ssl/nautilus.key;
root /usr/share/nginx/html;
index index.html;
}
Test configuration:
nginx -t
Reload:
systemctl restart nginx
π§© Step 5: Add Landing Page
echo "Welcome!" > /usr/share/nginx/html/index.html
cat /usr/share/nginx/html/index.html
π§ͺ Step 6: Test HTTPS Locally
curl -Ik https://localhost/
Expected output:
HTTP/1.1 200 OK
Server: nginx/1.20.1
Content-Type: text/html
Works perfectly.
π§ͺ Step 7: Test from Jump Host
curl -Ik https://stapp03/
If everything is correct, you will see:
HTTP/1.1 200 OK
And youβve met all requirements.
π How Nginx Handles SSL (Under the Hood)
Letβs peek inside Nginxβs TLS handshake flow:
Client (curl) β Nginx (port 443)
|
βββ ClientHello
|
βββ ServerHello + Certificate
|
βββ Key Exchange
|
βββ Session Established π
|
βββ HTTP Request (GET /)
Nginx performs:
Certificate verification
Cipher negotiation
Session creation
Content serving
All without loading the CPU heavily because its event loop is highly optimized.
π Troubleshooting: Common Issues & Fixes
β curl: (7) Failed to connect
Cause:
Nginx not listening on port 443
Config file not loaded
Cert/key path incorrect
Fix:
nginx -t
ss -tulpn | grep :443
journalctl -xe
β SSL key permission error
nginx: [emerg] cannot load certificate key ...
Fix:
chmod 600 /etc/nginx/ssl/nautilus.key
β Wrong server_name
If server_name mismatch, curl might return default Nginx block.
Fix:
server_name stapp03;
β Firewall blocking 443
On CentOS Stream 9, systems may use nftables instead of iptables.
Fix:
nft list ruleset
Usually firewall isnβt enabled in KodeKloud Lab.
π Security Best Practices (Production Standards)
Even though this lab uses a self-signed certificate, real-world deployments follow strict rules:
β Store certs & keys properly
/etc/nginx/ssl/
β File Permissions
Key β 600
Cert β 644
β Enable strong ciphers
(Recommended for real workloads)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
β Enable HSTS
Prevents downgrade attacks.
β Automate certificate renewal
Using Let's Encrypt + Certbot.
β Add monitoring
Track cert expiry via Prometheus alerts.
π Interview Questions to Master
Q1: Why use Nginx instead of Apache for SSL workloads?
Nginx has:
Event-driven architecture
Lower memory footprint
Faster SSL/TLS termination
Better concurrency
Q2: What is the purpose of ssl_certificate_key and why must it be restricted?
The key authenticates your server.
If leaked β attacker can impersonate your server.
Therefore must be readable only by root.
Q3: What is the difference between self-signed and CA-signed certificates?
| Self-Signed | CA-Signed |
| Created manually | Issued by trusted CA |
| Not trusted by browsers | Fully trusted |
| Used for labs | Used for production |
Q4: What happens internally when you run nginx -t?
Nginx does:
Configuration syntax validation
Certificate/key existence check
Port availability checks
Permission checks
Q5: Explain the entire HTTPS flow in 30 seconds.
Client sends hello β server responds with cert β key exchange β secure channel β encrypted HTTP traffic.
β Common Mistakes Engineers Make
Editing
/etc/nginx/nginx.confdirectlyWrong cert/key paths
Forgetting to set
server_nameMissing
indexfile causing 403 errorsNot testing config before restart
Restarting nginx instead of reload during heavy traffic
Incorrect permission on private keys
π― What We Achieved Today
Today we successfully:
β Installed and configured Nginx
β Moved SSL certificate + key securely
β Configured a proper HTTPS server block
β Added a landing page
β Validated HTTPS locally + from jump host
β Followed security best practices
β Learned how TLS + Nginx work internally
This wasnβt just a server setup task β
it was real-world DevOps:
Security + Web Hosting + Infrastructure + Troubleshooting.
β Final Thoughts
Day 15 complete! π
From firewall-hardening (Day 13), to Apache conflict resolution (Day 14), and now to Nginx SSL deployment β each day is sharpening your ability to secure, configure, and operate production-grade services.
Tomorrow, we take on the next challenge.
Letβs keep building, learning, and sharing! πͺπ
Day: 15 / 100
Challenge: KodeKloud Cloud DevOps
Date: November 20, 2025
Topic: Nginx with HTTPS β SSL Configuration & Secure Deployment




