Batch 5: Protocols & Security Networking Apache & NGINX Docker ← Full TOC

← Protocols Index

🔐 SSL & TLS / OpenSSL — TLS handshake, certificates, OpenSSL commands, Let's Encrypt

TLS (Transport Layer Security) encrypts data in transit. Every HTTPS connection uses TLS. OpenSSL is the universal toolkit for generating keys, certificates, and testing TLS. Let's Encrypt provides free, auto-renewing certificates.

📋 Reference

ItemSyntax / ValueDescription
TLS handshakeClientHello, ServerHello, Certificate, FinishedNegotiate cipher, exchange keys, verify certificate
TLS 1.2Requires 2 round trips to establishStill widely supported — uses RSA or ECDHE key exchange
TLS 1.31 round trip (0-RTT resumption)Faster and more secure — removes weak cipher suites
CertificateX.509 certificate — public key + identity + signatureIssued by CA, proves server identity
CACertificate Authority — signs certificatesDigiCert, Comodo, Let's Encrypt, self-signed
Self-signed certopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodesFor dev/testing only — browsers don't trust it
CSRCertificate Signing RequestSend to CA to get certificate signed
PEM format.pem — Base64-encoded certificate or keyMost common format — header: -----BEGIN CERTIFICATE-----
DER format.der — Binary encoded certificateUsed in Java keystores, Windows
PKCS#12.p12 / .pfx — Certificate + key in one fileUsed in Windows, Java — password-protected
openssl genrsaopenssl genrsa -out key.pem 4096Generate RSA private key
openssl genpkeyopenssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out key.pemGenerate EC key (faster than RSA)
openssl reqopenssl req -new -key key.pem -out csr.pemGenerate Certificate Signing Request
openssl x509openssl x509 -in cert.pem -text -nooutDisplay certificate details
openssl verifyopenssl verify -CAfile ca.pem cert.pemVerify certificate against CA
openssl s_clientopenssl s_client -connect example.com:443Test TLS connection — debug certificates
openssl pkcs12openssl pkcs12 -export -in cert.pem -inkey key.pem -out bundle.p12Create PKCS#12 bundle
Let's EncryptFree, automated, open CA — 90-day certs, auto-renewcertbot --apache or --nginx
certbotcertbot certonly --webroot -w /var/www/html -d example.comObtain Let's Encrypt certificate
certbot renewcertbot renew --quietRenew expiring certificates
HSTSStrict-Transport-Security: max-age=31536000; includeSubDomainsForce HTTPS for 1 year
Certificate pinningPin expected certificate fingerprint in clientPrevents MITM even with rogue CA — hard to update
SNIServer Name Indication — TLS extensionMultiple certs on one IP — client sends hostname in hello
OCSP staplingSSLUseStapling on (Apache)Server provides cert validity proof — faster than OCSP lookup
Perfect Forward SecrecyECDHE key exchange — session keys not derived from private keyCompromise of private key doesn't expose past sessions

💡 Example

# OpenSSL — Essential Commands

# ── Generate keys and certificates ───────────────────────────
# RSA private key (4096-bit)
openssl genrsa -out server.key 4096

# EC private key (256-bit — faster, equally secure)
openssl ecparam -name prime256v1 -genkey -noout -out server.key

# Self-signed certificate (dev/testing)
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt \
  -days 365 -nodes \
  -subj "/C=US/ST=CA/L=SanFrancisco/O=MyWebUniversity/CN=localhost"

# Self-signed with SAN (Subject Alternative Names) — required by modern browsers
cat > san.cnf << 'EOF'
[req]
distinguished_name = req_distinguished_name
x509_extensions    = v3_req
prompt = no
[req_distinguished_name]
CN = mywebuniversity.com
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = mywebuniversity.com
DNS.2 = www.mywebuniversity.com
DNS.3 = localhost
IP.1  = 127.0.0.1
EOF
openssl req -x509 -newkey rsa:4096 -keyout server.key -out server.crt \
  -days 365 -nodes -config san.cnf

# Generate CSR (to send to a real CA)
openssl req -new -key server.key -out server.csr \
  -subj "/C=US/O=MyWebUniversity/CN=www.mywebuniversity.com"

# ── Inspect certificates ──────────────────────────────────────
openssl x509 -in server.crt -text -noout          # full details
openssl x509 -in server.crt -dates -noout         # expiry dates
openssl x509 -in server.crt -subject -noout       # subject
openssl x509 -in server.crt -fingerprint -noout   # SHA1 fingerprint
openssl x509 -in server.crt -fingerprint -sha256 -noout  # SHA256

# Check certificate matches private key
openssl x509 -noout -modulus -in server.crt | md5sum
openssl rsa  -noout -modulus -in server.key | md5sum
# Must match!

# ── Test TLS connections ──────────────────────────────────────
# Basic TLS test
openssl s_client -connect www.mywebuniversity.com:443

# Show full certificate chain
openssl s_client -connect www.mywebuniversity.com:443 -showcerts

# Check TLS version and ciphers
openssl s_client -connect www.mywebuniversity.com:443 -tls1_3
openssl ciphers -v | grep ECDHE | head -10

# Test specific TLS version
openssl s_client -connect example.com:443 -no_tls1 -no_tls1_1  # force TLS 1.2+

# ── Let's Encrypt ─────────────────────────────────────────────
sudo apt install certbot python3-certbot-apache python3-certbot-nginx

# Apache
sudo certbot --apache -d mywebuniversity.com -d www.mywebuniversity.com

# NGINX
sudo certbot --nginx -d mywebuniversity.com -d www.mywebuniversity.com

# Standalone (no web server running)
sudo certbot certonly --standalone -d mywebuniversity.com

# Check certificate expiry
sudo certbot certificates
openssl x509 -in /etc/letsencrypt/live/mywebuniversity.com/cert.pem -noout -dates

# Auto-renewal cron (certbot usually adds this automatically)
echo "0 3 * * * certbot renew --quiet" | sudo crontab -

# ── Python: verify TLS ────────────────────────────────────────
import ssl, socket
def check_cert(hostname, port=443):
    ctx = ssl.create_default_context()
    with socket.create_connection((hostname, port), timeout=5) as sock:
        with ctx.wrap_socket(sock, server_hostname=hostname) as ssock:
            cert = ssock.getpeercert()
            print(f"Subject:  {dict(x[0] for x in cert['subject'])}")
            print(f"Issuer:   {dict(x[0] for x in cert['issuer'])}")
            print(f"Expires:  {cert['notAfter']}")
            print(f"SANs:     {[v for t,v in cert.get('subjectAltName',[])]}")
            return cert

check_cert("www.mywebuniversity.com")
# python3 check_cert.py

← HTTP & HTTPS  |  🏠 Index  |  SSH & SCP & SFTP →