project 02

Drippin' Pools by Gio

A real business's website, built end-to-end and hosted from my own homelab — then put through a full four-layer security audit.

Visit the live site

A friend's pool-cleaning business needed a real online presence, so I built one — not through a website builder, but the same way a small production app actually gets shipped: a Flask backend, a real reverse proxy, a real domain, and a server I run myself.

Stack

FrontendHTML5, CSS3, JavaScript
BackendPython, Flask
App serverGunicorn
Reverse proxyNginx
OSUbuntu Linux
DNS / edgeCloudflare (Tunnel — hides the origin IP entirely)
HostingSelf-hosted, DMZ VLAN of my homelab

Features

A contact form (name, phone, email, service requested, referral source, message) sends a formatted lead email straight to the business owner via Gmail SMTP, with clickable phone/email links for fast follow-up. A referral-tracking field (Person / Facebook / Yelp / Google / "Saw the Truck" / Other) helps the owner see which marketing channels actually bring customers in. The site is fully responsive, with a dedicated mobile hero image after the original one scaled incorrectly on smaller screens, and links out to the business's Facebook and Yelp pages.

Security — a four-layer audit

Real traffic means real attackers scanning it constantly. I worked through the whole stack layer by layer, like a home inspection — what's solid, what needs work, what could bite later.

Anti-spam hardening (later addition)

The honeypot alone stopped working once spam scripts started POSTing directly to the contact endpoint, skipping the rendered page — and the honeypot field — entirely. Three more layers went in on top:

CSRF protectionFlask-WTF issues a one-time token on page load; submissions without it are auto-rejected
Cloudflare TurnstileInvisible human-verification widget on the form itself
Pattern-based filterFlags submissions containing URLs in the message/name fields or known throwaway email patterns

Current security stack

CloudflareHides origin IP, bot blocking, DDoS protection
HTTPS / TLSAll traffic encrypted end-to-end, including SMTP to Gmail
Suricata IPSBlocks known-bad IPs before they reach the network
OPNsense DMZIsolates the server from the rest of the homelab
Pi-hole DNSLogs all outbound DNS, blocks known C2 domains
fail2banBans SSH brute-forcers after 3 attempts
SSH keys onlyNo password to brute-force
Credential managementSecrets kept in environment variables, never in source code; app-specific passwords instead of real account passwords
CSRF + Turnstile + honeypotThree layers of contact-form spam prevention
Rate limitingContact form limited per IP
Input sanitization / XSS preventionAll submitted input validated and stripped of HTML/JS server-side before use
// note This is a real client's business — the application code stays private, but the architecture and security work above are exactly what was done.

Related work

This site runs in the DMZ VLAN of my own homelab, isolated from everything else running there.