The big picture
Everything lives behind one firewall, on one private network. The only things exposed to the outside world are a couple of public IPs on the gateway; every VM sits on a private 10.100.100.0/24 network with no direct route in.
Internet
|
(public IP 203.0.113.10)
|
+--------------v---------------+
| pfSense gateway VM |
| NAT + HAProxy (TLS) |
+------+----------------+------+
| |
SSH (bastion only) HTTPS *.example.com
| | (TLS terminates here,
+--------v-------+ | forwards plain HTTP)
| Jump host | |
| 10.100.100.254 | |
+--------+-------+ |
| |
private network 10.100.100.0/24 (nothing internet-facing)
+-----------------------+--------------------------------------------+
| |
| Core services (.2-.6) Kubernetes platform (.7-.15) |
| - Git (Gitea) - control plane (master .7) |
| - Docs (BookStack) - workers .8 / .9 / .10 |
| - Monitoring (Grafana/Influx) - build runner .11 |
| - Logs (Loki) - NFS storage .12 |
| - Registry - databases .13 / .14 / .15 |
| - MetalLB pool .100-.110 |
+--------------------------------------------------------------------+
Read it top to bottom and it's three layers:
- The edge — pfSense does NAT (so private VMs can reach the internet) and runs HAProxy, which is the single HTTPS front door for every web service. TLS is terminated here with one wildcard certificate.
- The way in — humans don't SSH straight to internal boxes. They land on the jump host first. It's the only machine with both a public foot and an internal foot.
- The private network — two clusters of machines: the long-running "core" services, and the newer Kubernetes platform (which now includes three dedicated database VMs,
.13–.15).
Why one front door and one way in? It collapses the attack surface to two boxes you can actually reason about and harden. Every other VM can assume it's only ever talked to by something already inside the network.
Diagram

No comments to display
No comments to display