Van plat netwerk naar vertrouwenszones
Mijn thuisnetwerk is ooit heel gewoon begonnen: één netwerk, alles erop. De NAS, mijn laptop, de telefoon, wat slimme apparaten, en later de Proxmox-server waarop ik ben gaan virtualiseren. Dat werkte uitstekend — tot het niet meer werkte. Niet omdat er iets kapot ging, maar omdat het netwerk op een gegeven moment niet meer aanvoelde als “mijn netwerk thuis”, maar als een kleine IT-omgeving die ik toevallig ook nog ergens anders voor gebruikte.
Dat moment kwam niet in één klap. Het kwam geleidelijk, naarmate er steeds meer op die ene Proxmox-server bijkwam: een reverse proxy om meerdere diensten publiek te ontsluiten, een fotobibliotheek (Immich), een paar van mijn eigen webapps, een Git-server, monitoring, en een wifi-omgeving met een eigen controller. Op een plat netwerk betekent dat: alles kan in principe met alles praten. Een kapotte of gecompromitteerde telefoon zit dan letterlijk op hetzelfde segment als de server die mijn foto’s, mijn code en de sites host. Dat voelde niet meer correct.
De vraag die alles veranderde
De eerste reflex is om te denken in VLAN’s: “ik maak een VLAN per apparaattype en ben klaar.” Dat bleek de verkeerde ingang. De vraag die uiteindelijk alles stuurde, was niet hoe ik VLAN’s zou inrichten, maar:
Welke systemen moeten elkaar daadwerkelijk kunnen bereiken — en waarom?
Dat is een andere vraag dan “welke apparaten horen bij elkaar”. Een server is niet automatisch te vertrouwen omdat het een server is, en een IoT-apparaat is niet automatisch onbetrouwbaar omdat het een IoT-apparaat is. Wat telt, is de functie die iets vervult, welke gegevens erdoorheen gaan, en welke andere systemen het moet kunnen bereiken om zijn werk te doen. Die verschuiving — van denken in apparaten naar denken in vertrouwenszones — is achteraf de belangrijkste stap in het hele traject geweest.
Het VLAN-model dat daaruit volgde
De vertrouwenszones kregen uiteindelijk een technische vorm in zes VLAN’s:
- Management — het hoogste vertrouwensniveau, en bewust het kleinste publiek: OPNsense zelf, Proxmox-beheer, de UniFi-controller, switchbeheer, monitoring. Niets hiervan is bereikbaar vanaf gewoon gebruikersverkeer.
- Servers — de containers en VM’s die daadwerkelijk diensten leveren: Immich, mijn WordPress-sites, Gitea, en de rest van mijn eigen applicaties.
- Clients — laptops, telefoons, tablets: alles wat diensten gebruikt in plaats van levert.
- IoT — slimme apparaten, camera’s, printers: laag vertrouwen, zo veel mogelijk geïsoleerd, want dit is precies de categorie apparaten met de minste beveiliging en de minste kans dat ik er zelf nog iets aan ga patchen.
- Guest — uitsluitend internettoegang, geen enkele route naar binnen.
- DMZ — het publicatiepunt richting internet met de reverse proxy. om de toegang tot de servers te beheren en sturen.
Belangrijk is niet de lijst zelf, maar het inzicht erachter: niet elk apparaat verdient een eigen VLAN, maar elke vertrouwenszone wel.
OPNsense als enige weg naar binnen
De grootste architectuurbeslissing was dat verkeer nooit rechtstreeks van het ene VLAN naar het andere mag — alles loopt via OPNsense, en de uitgangspositie is default deny: alles is verboden, tenzij er een concrete, aanwijsbare reden is om het toe te staan.
Dat klinkt streng, en dat is het ook bedoeld. Het dwingt je om voor elke regel die je toevoegt drie dingen te kunnen beantwoorden: wie initieert de verbinding, waarom is die nodig, en welke poorten zijn daar daadwerkelijk voor vereist. Kun je die drie vragen niet beantwoorden, dan hoort de regel er niet te zijn. In de praktijk voelde dit in het begin als extra gedoe — elke nieuwe dienst die ik draaide, moest ik eerst expliciet een pad naar binnen geven in plaats van dat het “gewoon werkte”. Maar het effect was meteen zichtbaar: verkeersstromen die voorheen onzichtbaar waren, werden gedwongen expliciet en dus controleerbaar.
De DMZ die ik eerst verkeerd had
Mijn eerste instinct bij “een website publiek maken” was: zet die server in de DMZ. Logisch genoeg — DMZ is toch de plek voor publieke dingen? Bij nader inzien is dat precies de fout die je niet wilt maken: dan staat de applicatie zelf, met zijn database en zijn bestanden, in de zone die het dichtst bij internet ligt.
De uiteindelijke opzet draait het om: niet de applicatie staat in de DMZ, alleen de toegang ertoe. Traefik — mijn reverse proxy — is het enige dat in de DMZ staat en publiek bereikbaar is; die stuurt verkeer na een firewallregel door naar de eigenlijke applicatie, die veilig in de Server-zone blijft staan. Internet raakt dus nooit de applicatie zelf aan, alleen de voordeur. Dat verkleint het aanvalsoppervlak flink, en het geeft me één centrale plek voor TLS en voor publicatiebeleid, in plaats van dat elke applicatie dat zelf moet regelen.
Opslag is geen onderdeel van de applicatie
Een vergelijkbare denkfout zat in hoe ik opslag behandelde. In het begin hoorde data gewoon bij de applicatie die ermee werkte. Bij Immich — mijn zelfgehoste fotobibliotheek — werd duidelijk waarom dat niet houdbaar is: applicatie, database en de daadwerkelijke bestanden zijn drie verschillende dingen met drie verschillende levenscycli. Applicaties en opslag logisch scheiden maakt backups eenvoudiger, migraties eenvoudiger, en voorkomt dat het verwijderen of herbouwen van een applicatie-container ooit per ongeluk ook je data raakt.
Beheer is geen “nog een server”
Toen ik de UniFi-controller moest plaatsen, kwam een vraag op die ik niet had voorzien: hoort die bij de servers, of bij IoT, of is het eigenlijk een soort firewall? Geen van de drie, bleek het antwoord. Beheer is zijn eigen categorie: OPNsense, Proxmox-beheer, switchbeheer, de UniFi-controller en monitoring horen allemaal bij elkaar, juist omdat ze stuk voor stuk de sleutels tot de rest van het netwerk in handen hebben. Die zone krijgt daardoor het strengste regime van allemaal, en wordt nooit vanuit gewoon gebruikersverkeer benaderd.
Waar dit zich echt bewees: troubleshooting
Het ontwerp zelf voelt in de eerste plaats als meer werk. Waar het zich daadwerkelijk terugbetaalde, was bij het oplossen van problemen. Bij DNS-issues, bij een reverse proxy die een backend niet kon bereiken, of bij Immich dat zich anders gedroeg dan verwacht, kon ik telkens dezelfde vragen stellen: uit welk VLAN komt dit verkeer, naar welk VLAN moet het, en welke regel staat dat wel of niet toe? In een plat netwerk is het antwoord op die vragen altijd “overal en nergens” — hier kon ik het stap voor stap aanwijzen. Dat kost in het begin iets meer denkwerk dan “gewoon even restarten”, maar het netwerk werd er wel voorspelbaarder van, en storingen werden sneller te herleiden tot een oorzaak in plaats van tot een gok.
Het inzicht dat eruit rolde
Ik ben hier nooit aan begonnen met het doel “zero trust implementeren” — die term kwam pas achteraf. Maar elke beslissing afzonderlijk (geen impliciet vertrouwen, verkeer altijd expliciet toestaan, beheer apart, applicatie en opslag gescheiden, publieke toegang gescheiden van de applicatie zelf) bleek achteraf precies in die richting te wijzen. Dat is denk ik ook de eigenlijke les: het was geen VLAN-project met een eindpunt, maar een manier van denken die zich vanzelf doorzette zodra je ‘m één keer goed had toegepast.
De kortste samenvatting van waar ik nu sta: bouw het netwerk rondom vertrouwen, niet rondom apparaten. Elke keer dat ik een nieuwe dienst toevoeg, is de eerste vraag niet meer “op welke server zet ik dit”, maar “tot welke vertrouwenszone behoort dit, en wat moet het daadwerkelijk kunnen bereiken”. Dat is een trager startpunt dan vroeger — en precies daardoor een netwerk waarvan ik kan uitleggen waarom het werkt, in plaats van alleen dat het werkt.
