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

🔒 Chapter 42 — Protocols, APIs & Security

Complete reference for HTTP/S, TLS/SSL, SSH, REST APIs, curl, OAuth2, JWT, SAML, MFA, RBAC, Kerberos, FreeIPA, and cybersecurity fundamentals.
Part of The Direct Path to Linux Ubuntu — free for all.

6Topics
169+Concepts
5Examples
curl / sshTools
TLS 1.3Standard
FreeNo login
🌐 HTTP & HTTPS 🔐 SSL & TLS 🔑 SSH & SCP & SFTP 🔗 REST APIs & curl 🛡️ IAM & Identity 🔒 Cybersecurity ⚡ Examples

🌐 HTTP & HTTPS

🌐 HTTP & HTTPSHTTP methods, status codes, headers, HTTPS, TLS handshake

🔐 SSL & TLS

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

🔑 SSH & SCP & SFTP

🔑 SSH & SCP & SFTPSSH keys, config, tunnels, SCP file transfer, SFTP

🔗 REST APIs & curl

🔗 REST APIs & curlREST principles, curl, wget, API authentication patterns

🛡️ IAM & Identity

🛡️ Identity & Access ManagementOAuth2, JWT, SAML, SSO, Kerberos, MFA, RBAC, IPA

🔒 Cybersecurity

🔒 Cybersecurity FundamentalsOWASP Top 10, hardening, pen testing tools, secure coding

⚡ Quick Examples

Install: sudo apt install curl openssh-client openssl fail2ban ufw. Python: pip install requests pyjwt bcrypt paramiko.

curl API Quick Reference

Most-used curl commands for API testing and scripting.

# ── GET requests ──────────────────────────────────────────────
curl https://api.example.com/users
curl -s https://api.example.com/users | python3 -m json.tool
curl -s -o /dev/null -w "%{http_code}" https://example.com/health

# ── POST / PUT / PATCH / DELETE ───────────────────────────────
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"Alice","email":"alice@example.com"}'

curl -X PATCH https://api.example.com/users/42 \
  -H "Content-Type: application/json" \
  -d '{"email":"newemail@example.com"}'

curl -X DELETE https://api.example.com/users/42 \
  -H "Authorization: Bearer $TOKEN" \
  -w "Status: %{http_code}\n"

# ── Authentication ────────────────────────────────────────────
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." https://api.example.com/me
curl -H "X-API-Key: mykey123" https://api.example.com/data
curl -u alice:password https://api.example.com/admin/

# Login and get token
TOKEN=$(curl -s -X POST https://api.example.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"alice","password":"secret"}' \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')
echo "Token: ${TOKEN:0:30}..."

# ── Useful flags ──────────────────────────────────────────────
curl -v url                        # verbose — show all headers
curl -I url                        # HEAD — headers only
curl -L url                        # follow redirects
curl -s url                        # silent — no progress
curl -k url                        # skip TLS verification (dev only)
curl -o file.html url              # save to file
curl -O url/file.tar.gz            # save with remote name
curl --retry 3 --retry-delay 2 url # retry on failure
curl --compressed url              # request gzip
curl --limit-rate 1m url           # limit download speed
curl --resolve example.com:443:1.2.3.4 https://example.com/  # override DNS

# ── Timing ────────────────────────────────────────────────────
curl -s -o /dev/null -w "DNS:%{time_namelookup}s Connect:%{time_connect}s TLS:%{time_appconnect}s Total:%{time_total}s\n" https://www.mywebuniversity.com/

SSH Key Setup & Config

Generate SSH keys, configure ~/.ssh/config, tunnels.

# ── Generate SSH keys ─────────────────────────────────────────
# ED25519 (preferred — modern, fast, secure)
ssh-keygen -t ed25519 -C "alice@mywebuniversity.com"
# Saves: ~/.ssh/id_ed25519 (private) + ~/.ssh/id_ed25519.pub (public)

# RSA (for compatibility with older systems)
ssh-keygen -t rsa -b 4096 -C "alice@mywebuniversity.com"

# Copy public key to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub ubuntu@mywebuniversity.com
# Or manually:
cat ~/.ssh/id_ed25519.pub | ssh ubuntu@host "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

# ── ~/.ssh/config ─────────────────────────────────────────────
cat ~/.ssh/config
# Host mwu
#     HostName      mywebuniversity.com
#     User          ubuntu
#     IdentityFile  ~/.ssh/id_ed25519
#     Port          22
#     ServerAliveInterval 60

# Connect via alias
ssh mwu                     # instead of: ssh -i ~/.ssh/id_ed25519 ubuntu@mywebuniversity.com

# ── File transfer ─────────────────────────────────────────────
scp local.txt mwu:/var/www/React/prod/         # upload file
scp -r ./html/ mwu:/var/www/React/prod/        # upload folder
scp mwu:/var/log/apache2/error.log ./          # download file
rsync -avz --progress ./html/ mwu:/var/www/React/prod/   # smart sync
rsync -avz --delete ./html/ mwu:/var/www/React/prod/     # mirror

# ── SSH tunnels ───────────────────────────────────────────────
ssh -L 5432:localhost:5432 mwu -N &    # access remote PostgreSQL locally
ssh -L 6379:localhost:6379 mwu -N &    # access remote Redis locally
ssh -L 8080:localhost:80  mwu -N &    # access remote web server
ssh -D 1080 mwu -N &                   # SOCKS proxy through server

# ── SSH hardening ─────────────────────────────────────────────
sudo nano /etc/ssh/sshd_config
# PermitRootLogin          no
# PasswordAuthentication   no
# MaxAuthTries             3
# AllowUsers               ubuntu deploy
sudo sshd -t && sudo systemctl reload sshd

TLS Certificate Management

OpenSSL, Let's Encrypt, and certificate workflows.

# ── Let's Encrypt (production) ───────────────────────────────
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)
sudo certbot certonly --standalone -d mywebuniversity.com

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

# Test auto-renewal
sudo certbot renew --dry-run

# ── Self-signed (development) ─────────────────────────────────
openssl req -x509 -newkey rsa:4096 -nodes \
  -keyout server.key -out server.crt \
  -days 365 \
  -subj "/C=US/O=MyWebUniversity/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

# ── Inspect certificates ──────────────────────────────────────
openssl x509 -in cert.pem -text -noout     # full details
openssl x509 -in cert.pem -dates -noout    # expiry only
openssl s_client -connect example.com:443  # test live TLS
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

# Check if cert matches key
openssl x509 -noout -modulus -in cert.pem | md5sum
openssl rsa  -noout -modulus -in key.pem  | md5sum
# Must match!

# ── PKCS#12 bundle (for Java/Windows) ─────────────────────────
openssl pkcs12 -export \
  -in cert.pem -inkey key.pem -name "mywebuniversity" \
  -out bundle.p12
# Import into Java keystore:
keytool -importkeystore -srckeystore bundle.p12 -srcstoretype PKCS12 \
  -destkeystore keystore.jks -deststoretype JKS

JWT Authentication (Python)

Create, sign, and verify JSON Web Tokens.

# pip install pyjwt cryptography bcrypt
import jwt, bcrypt, secrets, datetime

# ── Configuration ────────────────────────────────────────────
SECRET = secrets.token_hex(32)   # Load from environment in production!
ALGORITHM   = 'HS256'
ACCESS_EXP  = 15    # minutes
REFRESH_EXP = 7     # days

# ── Token creation ────────────────────────────────────────────
def create_access_token(user_id: str, email: str, roles: list) -> str:
    now = datetime.datetime.utcnow()
    return jwt.encode({
        'sub':   user_id,
        'email': email,
        'roles': roles,
        'type':  'access',
        'iss':   'mywebuniversity.com',
        'aud':   'api.mywebuniversity.com',
        'iat':   now,
        'exp':   now + datetime.timedelta(minutes=ACCESS_EXP),
        'jti':   secrets.token_hex(8),
    }, SECRET, algorithm=ALGORITHM)

def create_refresh_token(user_id: str) -> str:
    now = datetime.datetime.utcnow()
    return jwt.encode({
        'sub':  user_id,
        'type': 'refresh',
        'iat':  now,
        'exp':  now + datetime.timedelta(days=REFRESH_EXP),
        'jti':  secrets.token_hex(8),
    }, SECRET, algorithm=ALGORITHM)

# ── Token verification ────────────────────────────────────────
def verify_token(token: str, token_type: str = 'access') -> dict:
    try:
        payload = jwt.decode(token, SECRET, algorithms=[ALGORITHM],
                             audience='api.mywebuniversity.com')
        if payload.get('type') != token_type:
            raise jwt.InvalidTokenError(f"Expected {token_type} token")
        return payload
    except jwt.ExpiredSignatureError:
        raise ValueError("Token expired")
    except jwt.InvalidTokenError as e:
        raise ValueError(f"Invalid token: {e}")

# ── Password hashing ──────────────────────────────────────────
def hash_pw(plain: str) -> str:
    return bcrypt.hashpw(plain.encode(), bcrypt.gensalt(12)).decode()

def verify_pw(plain: str, hashed: str) -> bool:
    return bcrypt.checkpw(plain.encode(), hashed.encode())

# ── Demo ──────────────────────────────────────────────────────
# Register
pw_hash = hash_pw("MySecurePass123!")
print(f"Stored hash: {pw_hash[:30]}...")

# Login
if verify_pw("MySecurePass123!", pw_hash):
    access  = create_access_token("u001", "alice@mwu.com", ["student"])
    refresh = create_refresh_token("u001")
    print(f"Access token:  {access[:40]}...")
    print(f"Refresh token: {refresh[:40]}...")

    # Use access token
    payload = verify_token(access)
    print(f"User:  {payload['email']}")
    print(f"Roles: {payload['roles']}")
    print(f"Expires: {datetime.datetime.fromtimestamp(payload['exp'])}")

# python3 jwt_demo.py

Linux Security Hardening

Firewall, fail2ban, SSH hardening, and audit tools.

#!/bin/bash
# Linux Server Hardening Script
# Run as root on fresh Ubuntu 22.04/24.04

set -euo pipefail

echo "=== 1. System Update ==="
apt update && apt upgrade -y
apt install -y unattended-upgrades apt-listchanges
dpkg-reconfigure -plow unattended-upgrades

echo "=== 2. SSH Hardening ==="
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
cat > /etc/ssh/sshd_config.d/99-hardening.conf << 'EOF'
PermitRootLogin          no
PasswordAuthentication   no
PubkeyAuthentication     yes
PermitEmptyPasswords     no
ChallengeResponseAuthentication no
X11Forwarding            no
AllowAgentForwarding     no
MaxAuthTries             3
MaxSessions              5
LoginGraceTime           30
ClientAliveInterval      300
ClientAliveCountMax      2
Protocol                 2
AllowUsers               ubuntu deploy admin
EOF
sshd -t && systemctl reload sshd && echo "SSH hardened"

echo "=== 3. Firewall (ufw) ==="
ufw --force reset
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp   comment 'SSH'
ufw allow 80/tcp   comment 'HTTP'
ufw allow 443/tcp  comment 'HTTPS'
ufw --force enable
ufw status verbose

echo "=== 4. Fail2ban ==="
apt install -y fail2ban
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime   = 1h
findtime  = 10m
maxretry  = 5
destemail = security@mywebuniversity.com

[sshd]
enabled  = true
port     = ssh
logpath  = %(sshd_log)s
maxretry = 3
bantime  = 24h

[apache-auth]
enabled  = true

[nginx-http-auth]
enabled  = true
EOF
systemctl enable fail2ban && systemctl restart fail2ban
echo "Fail2ban configured"

echo "=== 5. Kernel hardening (sysctl) ==="
cat > /etc/sysctl.d/99-security.conf << 'EOF'
# Network security
net.ipv4.conf.all.rp_filter         = 1
net.ipv4.conf.default.rp_filter     = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_redirects  = 0
net.ipv4.conf.all.send_redirects    = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.tcp_syncookies             = 1

# Memory protection
kernel.randomize_va_space           = 2
kernel.dmesg_restrict               = 1
kernel.kptr_restrict                = 2
fs.protected_hardlinks              = 1
fs.protected_symlinks               = 1
EOF
sysctl -p /etc/sysctl.d/99-security.conf

echo "=== 6. Install audit tools ==="
apt install -y auditd audispd-plugins lynis rkhunter
systemctl enable auditd && systemctl start auditd

# Audit important files
auditctl -w /etc/passwd      -p wa -k passwd_changes
auditctl -w /etc/shadow      -p wa -k shadow_changes
auditctl -w /etc/ssh/sshd_config -p wa -k sshd_changes
auditctl -w /var/www         -p wa -k web_changes

echo "=== 7. Run security audit ==="
lynis audit system --quick --quiet 2>/dev/null | tail -20

echo "=== Hardening complete! ==="
echo "Next: run 'sudo lynis audit system' for full report"
# chmod +x hardening.sh && sudo ./hardening.sh