Alles werkt tot de buildrunner dezelfde hostsocket nodig heeft als de VPN-gast gebruikt, en dan kan niemand uitleggen waarom een taak de sleutels van de gateway kan lezen. Alles is op één machine geïnstalleerd omdat het paste, en elke gast kreeg brede toegang omdat dat de snelste manier was om het aan de praat te krijgen. Het resultaat is een host waarvan de vertrouwensgrens de voedingskabel is. De rollen splitsen kost minder werk dan het klinkt, en het begint met ze een naam te geven.

Drie rollen die nu alles delen

Een VPN-ingang, een set private diensten en een buildrunner willen verschillende dingen. De eerste heeft een openbare poort en een smal netwerk aan de private kant nodig. De tweede heeft permanente opslag en applicatiegeheimen nodig. De derde voert code uit die iemand anders heeft geschreven.

Juist het geven van dezelfde toegang aan alle drie maakt het symptoom verwarrend, omdat daarna elk van hen de anderen kan beïnvloeden. Een buildtaak die de socket van de hypervisor bereikt, is een taak die de VPN kan stoppen. Een dienstengast met een route naar het beheernetwerk kan de configuratie van de switch wijzigen. De rechten zijn het probleem, en de proceslijst is alleen de plek waar het zichtbaar wordt. De rollen eerst benoemen geeft elk recht een plek om te leven.

De schets hieronder is een vertrekpunt voor die splitsing, geen belofte van hoge beschikbaarheid. Behandel hem als een hypothese om te verifiëren, niet als het voltooide ontwerp.

Splits drie rollen, niet drie processen

Drie gasten op één host geven drie rechtensets en drie netwerkposities. Ze geven geen drie storingsdomeinen, en het ontwerp zou dat hardop moeten zeggen.

De scheiding helpt alleen als een compromis in één gast de andere niet automatisch rechten geeft, en dat is een hypervisorinstelling, geen naamconventie. Een VM gateway noemen weerhoudt een andere gast er niet van de host te bereiken. Lees de configuratie van de virtuele switch in plaats van de hostnaam, en bevestig dan dat elke gast zit waar je denkt.

host
├─ vpn-gw      10.60.10.2/24   public 51820/udp only
├─ services    10.60.0.10/24   no route to the management network
└─ ci-runner   10.60.20.2/24   outbound only, no host socket

Schrijf de topologie op en verifieer die vervolgens met het gereedschap dat hem bezit. Een gast die op de verkeerde bridge verschijnt is een bevinding, geen detail. Corrigeer het netwerk voordat je enige dienstconfiguratie wijzigt.

Laat de VPN-gast alleen de deuren openen die hij bezit

Publiceer de tunnelpoort op de router en niets anders. Beheerpoorten van gasten horen op een beheerpad, niet op internet, en de eigen interface van de hypervisor hoort daar ook.

Het netwerk aan de private kant zou de diensten moeten bereiken die externe gebruikers nodig hebben en daar stoppen. Applicatieauthenticatie blijft aan, want een tunnel is transport en geen login. Houd de routetabel van de VPN-gast klein genoeg om in één zin te beschrijven. Als je hem niet zo eenvoudig kunt beschrijven, is de grens al vervaagd.

virsh net-list --all
virsh net-dumpxml lab-private
sudo nft list ruleset | grep -n -E '51820|10.60'

Alles wat op de host luistert en niet voor beheer nodig is, zou helemaal niet moeten luisteren. Dat omvat de API van de hypervisor, die je gemakkelijk op een openbare interface open laat staan.

Buildtaken hebben een ander soort grens nodig

Een CI-taak voert opdrachten uit die door de repository worden beheerst, dus het vertrouwen hangt af van wie code kan pushen. Een shell-uitvoerder draait die opdrachten als de gebruiker van de runner op de host, en dat is de breedste grens die beschikbaar is.

Containeruitvoerders zijn smaller, en een geprivilegieerde container is niet een van de smalle. Houd de runner in zijn eigen gast met zijn eigen netwerkbereik, en geef hem alleen de artefact- en implementatietoegang die de taken nodig hebben. Wegwerparbeiders verminderen de bewaarde staat; ze verminderen de bereikbaarheid of blootstelling van geheimen niet. Beide hebben nog steeds expliciete grenzen nodig.

De dienstengast bezit de gegevens, dus het back-upplan daarvan is het plan dat moet werken. Houd repositories, uploads en de database in hetzelfde schema. Test een herstel in plaats van de taakstatus te lezen.

Plan voor de storing die alle drie delen

Eén host is één storingsdomein. Een herstart verwijdert de tunnel en elke private dienst op hetzelfde moment, en juist dan telt een weg naar binnen het meest.

Houd consoletoegang die niet van de VPN-gast afhangt, of dat nu een fysieke console, een out-of-band-beheerinterface of een providerconsole is. Een snapshot op dezelfde schijf is geen onafhankelijke kopie, en een back-up die in de gast draait die hij beschermt ook niet. Test daarna de koude start als een reeks en niet als een checklist: host, virtuele netwerken, tunnelpad en één genoemde applicatie onder een gewoon account.

virsh list --all
systemctl is-active libvirtd
curl -sS -m 5 -o /dev/null -w '%{http_code}\n' https://10.60.0.10/
ss -ltnp | grep -E ':51820|:443'

De volgorde van processtarts bewijst niets over routes en DNS, dus test het pad in plaats van de eenheidsstatussen. Het pad is wat een externe gebruiker werkelijk nodig heeft.

Gerelateerde artikelen