# ============================================================ # Nova Shield — Caddy Zero Trust Gateway (DRAF) # Versi: 0.1 (2026-08-15) · REDTEAM / NOVA # # NOTA: Draf — SAH KAN sebelum deploy: # caddy validate --config /etc/caddy/Caddyfile # systemctl reload caddy # # Keperluan: Caddy >= 2.8 (untuk X25519MLKEM768 default PQC) # Gantikan [PLACEHOLDER] ikut persekitaran. # ============================================================ { # Matikan admin API (kurangkan surface) admin off # Lokasi data/pelbagai instance — elak konflik # data_dir /var/lib/caddy } # ------------------------------------------------------------ # SITE: shield.alesanova.my # ------------------------------------------------------------ shield.alesanova.my { # ========================================================== # 1) TLS — Post-Quantum hybrid key exchange # ========================================================== # X25519MLKEM768 (NIST hybrid) — DEFAULT dalam Caddy 2.8+. # Dinyatakan eksplisit untuk kejelasan + lock-down. tls { curves X25519MLKEM768 X25519 # TLS 1.3 SAHAJA = semua koneksi guna KEX PQC-capable. # Komen baris ini jika ada client legacy yang perlukan 1.2. protocols tls1.3 } # ========================================================== # 2) Security Headers (fix audit A5) # ========================================================== header { Strict-Transport-Security "max-age=31536000; includeSubDomains" Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "no-referrer" Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" # Buang header fingerprint (fix audit A6) -Server -Via -X-Powered-By } # ========================================================== # 3) Had body + masa (hardening asas) # ========================================================== request_body { max_size 10MB } # ========================================================== # 4) Reverse proxy ke origin (LiteSpeed) # ========================================================== # Gantikan 127.0.0.1:8080 dengan alamat/port origin sebenar. # PRINSIP ZT: origin HANYA terima trafik dari shield (lihat nota di bawah). reverse_proxy 127.0.0.1:8080 { header_up X-Forwarded-Proto {scheme} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} } # ========================================================== # 5) Logging (untuk continuous verification — audit F1) # ========================================================== log { output file /var/log/caddy/shield-access.log { roll_size 100MiB roll_keep 10 } format json } # ========================================================== # 6) OPSYEN — aktifkan bila perlu (sila buang #) # ========================================================== # --- Rate limiting per-IP (perlukan plugin caddy-rate-limit) --- # rate_limit / 10r/s # --- mTLS untuk console (akses dalaman sahaja, ZT C2) --- # handle_path /console/* { # tls { # client_auth { # mode require_and_verify # trusted_ca_certs /etc/caddy/ca-internal.pem # } # } # reverse_proxy 127.0.0.1:8080 # } # --- Redirect admin path lama ke console (elak asimetri 301/302) --- # redir /admin* /console/ } # ============================================================ # NOTA OPERASI (di luar Caddyfile): # # 1. ORIGIN ISOLATION (audit D1) — di host origin (LiteSpeed): # iptables -A INPUT -p tcp --dport 80 -s -j ACCEPT # iptables -A INPUT -p tcp --dport 80 -j DROP # (ulang untuk port 443 jika origin ada TLS sendiri — elak direct reach) # # 2. PATH SENSITIF → 404 (audit A10): # handle /.git/* { respond 404 } # handle /.env { respond 404 } # # 3. VERIFY selepas reload: # curl -sI https://shield.alesanova.my/ | grep -iE "strict|content-security|x-frame|server|via" # echo | openssl s_client -connect shield.alesanova.my:443 -servername shield.alesanova.my -tls1_3 2>/dev/null | grep "group" # # Harap nampak: X25519MLKEM768 + headers lengkap + TIADA "via: Caddy" # ============================================================