OpenVPN på GCE: lägg till en alias-IP innan du pushar rutter
En pushad rutt gör inte VM:en till next hop. Lägg till alias-IP-intervallet, matcha det mot serverpoolen och skapa VPC-returrutten innan du testar klienter.
En klient ringer upp OpenVPN-servern på en Compute Engine-VM, statusfönstret säger ansluten, och en ping till en värd i VPC:n kommer fortfarande ingenstans. Instinkten är att lägga till ännu en push-rad, och det löser det aldrig. Compute Engine avgör vart paket tar vägen utifrån sin egen rutttabell och utifrån de adresser som ett VM-gränssnitt faktiskt har, så en tunnelpool som VM:en inte äger är en pool som ingen levererar till.
Följ det misslyckade paketet i stället för konfigurationsfilen, så dyker de saknade delarna upp i ordning.
Börja vid paketet som dör
SYN-paketet lämnar klienten, landar i tunneln och når VM:en som ett inkapslat paket för en destination i VPC:n. OpenVPN avkapslar det och försöker vidarebefordra det ut genom eth0, där fabricen ställer en fråga före allt annat: äger den här instansen destinationsadressen. En tunnelpool som skurits ut ur någon annans subnet faller på den frågan, och paketet kastas innan någon rutt eller brandväggsregel konsulteras.
Riktningen från klient till VPC har alltså två separata krav, och inget av dem är ett push-direktiv. VM:en behöver ett aliasintervall som täcker tunnelpoolen, och det är just det som gör den till legitim ägare av de adresserna. VPC:n behöver en rutt som pekar ut VM:en som next hop för varje skyddat prefix. Saknas något av dem dör paketet på en annan plats, medan klienten ser samma tystnad.
Läs felet i den ordningen, för från klientsidan ser de två villkoren identiska ut. En tunnel som rapporterar ansluten medan inget svarar är signaturen för ett topologiproblem och inte för en dålig cipher.
Äger instansen tunnelpoolen
Ge VM:en ett sekundärt intervall inuti dess eget subnet och låt sedan OpenVPN dela ut adresser från exakt det intervallet. På en instans vars primära adress är 10.156.0.10/20 håller ett /28-alias poolen åtskild från de adresser som andra instanser redan har:
gcloud compute instances network-interfaces update openvpn-vm \
--zone=europe-west1-b \
--aliases=eth0:10.156.1.0/28Serverdirektivet måste då beskriva samma block. Dess första adress blir tunnelns gateway, och de återstående adresserna delas ut till klienter. Två tal beskriver ett block här, ett nätverk och en nätmask, och det är den pool-syntax som OpenVPN fortfarande förväntar sig.
server 10.156.1.0 255.255.255.240Bekräfta att adressen verkligen landade på gränssnittet och inte bara inne i OpenVPN-konfigurationen. Fabricen vidarebefordrar det NIC:en rapporterar, inte det daemonen tror. Ett kommando avgör saken:
ip -4 addr show dev eth0En sekundär adress som aldrig når eth0, eller en pool som överlappar ett annat subnet, visar sig senare som sporadiska tapp i stället för som ett startfel. Daemonen startar, klienter ansluter, och bara vissa destinationer beter sig fel. Håll aliasintervallet litet så att poolen är lätt att känna igen i en rutttabell. Skär aldrig ut det ur ett subnet som en annan instans redan använder.
Ge returtrafiken en next hop
Ett svar från en värd i VPC:n är adresserat till en klientadress i tunnelpoolen, som inte tillhör något subnet som VPC:n känner till. Utan en rutt för den poolen stannar svaret vid det första hoppet utan matchning, och begäran kan mycket väl ha lyckats i andra änden.
gcloud compute routes create openvpn-return \
--network=prod-vpc \
--destination-range=192.168.127.0/24 \
--next-hop-instance=openvpn-vm \
--next-hop-instance-zone=europe-west1-b \
--priority=800Samma rutt behövs för varje prefix som ligger bakom en klient i stället för inne i VPC:n. De prefixen behöver också en iroute-post i den klientens ccd-fil. Den posten är bokföring på serversidan: den talar om för servern vilken klient som äger prefixet, och den installerar ingenting på klienten själv.
Behåll push-listan för klientsidan av samtalet, eftersom den bara lägger till rutter på maskinen som ansluter. En push-rad för ett VPC-subnet och en VPC-rutt tillbaka till poolen är två halvor av samma väg, och varje halva för sig ger en tunnel som bär begäranden men inga svar.
Brandväggar, vidarebefordran och hoppen däremellan
VPC-brandväggen utvärderar det avkapslade paketet, så en ingress-regel måste tillåta tunnelpoolen och varje site-prefix som når VM:en den vägen. En default-deny-hållning misslyckas tyst här: paketet kastas efter avkapslingen, och OpenVPN-loggen visar en frisk session.
Kontrollera på varje Linux-värd som vidarebefordrar i stället för att terminera att net.ipv4.ip_forward är aktiverat. Ägarregeln gäller där också: en maskin som vidarebefordrar för ett subnet den inte har kastar paketet precis som VM:en skulle göra. Läs värdet innan du skyller på tunneln.
När exakt ett prefix misslyckas
Partiellt fel är det lättaste fallet att läsa, eftersom allt annat i vägen redan är bevisat. Börja med ruttlistan och läs destinationsintervallet och next hop för posten som borde täcka prefixet, läs sedan instansbeskrivningen och jämför dess aliasintervall med poolen som servern delar ut.
gcloud compute routes list --filter=destination-range~10.164.0.0
gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)En saknad rutt visar sig som ingen next hop för prefixet, medan ett saknat alias visar sig som ett paket som kastas vid gränssnittet; från klienten ser de två likadana ut och i de två utskrifterna är de helt olika. Om båda finns är den återstående misstänkta ccd-irouten för den klient som gör anspråk på prefixet.
Skriv ner de fyra värdena bredvid tunneln: aliasintervall, serverpool, pushade prefix, VPC-rutter. Ett inaktuellt alias bryter varje pooladress, en inaktuell rutt bryter en riktning, en saknad push döljer prefixet för klienten, och en felaktig iroute skickar prefixet till fel peer. Nästa person som lägger till ett subnet behöver alla fyra på ett ställe, och anteckningen är billigare än kvällen.