Skip to main content

Command Palette

Search for a command to run...

Day 15: Deploying Nginx with SSL β€” Preparing App Server 3 for Secure Application Hosting πŸ”βš‘

Published
β€’6 min read
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-SignedCA-Signed
Created manuallyIssued by trusted CA
Not trusted by browsersFully trusted
Used for labsUsed 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.conf directly

  • Wrong cert/key paths

  • Forgetting to set server_name

  • Missing index file causing 403 errors

  • Not 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

More from this blog

πŸš€ DevOps Challenge- KodeKloud Solutions

73 posts