OpenVPN på GCE: tilføj en alias-IP, før du pusher ruter
En pushet rute gør ikke VM'en til next hop. Tilføj alias-IP-intervallet, få det til at matche serverpoolen, og opret VPC-returruten, før du tester klienter.
En klient ringer op til OpenVPN-serveren på en Compute Engine-VM, statusvinduet siger forbundet, og en ping til en vært i VPC'en ender stadig ingen steder. Instinktet er at tilføje endnu en push-linje, og det løser det aldrig. Compute Engine beslutter, hvor pakker skal hen, ud fra sin egen rutetabel og ud fra de adresser, som en VM-netværksgrænseflade faktisk har, så en tunnelpool, som VM'en ikke ejer, er en pool, som ingen leverer til.
Følg den fejlende pakke i stedet for konfigurationsfilen, så dukker de manglende dele op i rækkefølge.
Start ved pakken, der dør
SYN'et forlader klienten, lander i tunnelen og når VM'en som en indkapslet pakke til en destination i VPC'en. OpenVPN afkapsler den og forsøger at videresende den ud af eth0, hvor fabric'en stiller ét spørgsmål før alt andet: ejer denne instans destinationsadressen. En tunnelpool, der er skåret ud af en andens subnet, fejler det spørgsmål, og pakken kasseres, før nogen rute eller firewallregel bliver konsulteret.
Retningen fra klient til VPC har altså to adskilte krav, og ingen af dem er en push-direktiv. VM'en har brug for et aliasinterval, der dækker tunnelpoolen, og det er netop det, der gør den til retmæssig ejer af de adresser. VPC'en har brug for en rute, der udpeger VM'en som next hop for hvert beskyttet præfiks. Mangler ét af dem, dør pakken et andet sted, mens klienten ser den samme tavshed.
Læs fejlen i den rækkefølge, for fra klientsiden ser de to betingelser identiske ud. En tunnel, der rapporterer forbundet, mens intet svarer, er signaturen på et topologiproblem og ikke på en dårlig cipher.
Ejer instansen tunnelpoolen
Giv VM'en et sekundært interval inde i dens eget subnet, og lad derefter OpenVPN uddele adresser fra præcis det interval. På en instans, hvis primære adresse er 10.156.0.10/20, holder et /28-alias poolen adskilt fra de adresser, som andre instanser allerede har:
gcloud compute instances network-interfaces update openvpn-vm \
--zone=europe-west1-b \
--aliases=eth0:10.156.1.0/28Serverdirektivet skal så beskrive den samme blok. Dens første adresse bliver tunnelgatewayen, og de resterende adresser uddeles til klienter. To tal beskriver én blok her, et netværk og en netmaske, og det er den pool-syntaks, som OpenVPN stadig forventer.
server 10.156.1.0 255.255.255.240Bekræft, at adressen virkelig landede på grænsefladen og ikke kun inde i OpenVPN-konfigurationen. Fabric'en videresender efter det, NIC'en rapporterer, ikke efter det, daemonen tror. Én kommando afgør det:
ip -4 addr show dev eth0En sekundær adresse, der aldrig når eth0, eller en pool, der overlapper et andet subnet, viser sig senere som periodisk tab i stedet for som en opstartsfejl. Daemonen starter, klienter forbinder, og kun nogle destinationer opfører sig forkert. Hold aliasintervallet lille, så poolen let kan genkendes i en rutetabel. Skær det aldrig ud af et subnet, som en anden instans allerede bruger.
Giv returtrafikken en next hop
Et svar fra en vært i VPC'en er adresseret til en klientadresse i tunnelpoolen, som ikke hører til noget subnet, VPC'en kender. Uden en rute til den pool stopper svaret ved det første hop uden match, og anmodningen kan sagtens være lykkedes i den anden ende.
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=800Den samme rute er nødvendig for ethvert præfiks, der ligger bag en klient i stedet for inde i VPC'en. De præfikser har også brug for en iroute-post i den pågældende klients ccd-fil. Den post er bogholderi på serversiden: den fortæller serveren, hvilken klient der ejer præfikset, og den installerer intet på klienten selv.
Behold push-listen til klientsiden af samtalen, for den tilføjer kun ruter på den maskine, der forbinder. En push-linje til et VPC-subnet og en VPC-rute tilbage til poolen er to halvdele af samme vej, og hver halvdel alene giver en tunnel, der bærer anmodninger men ingen svar.
Firewalls, videresendelse og hopene imellem
VPC-firewallen vurderer den afkapslede pakke, så en ingress-regel skal tillade tunnelpoolen og ethvert site-præfiks, der når VM'en den vej. En default-deny-holdning fejler lydløst her: pakken kasseres efter afkapslingen, og OpenVPN-loggen viser en sund session.
Kontroller på enhver Linux-vært, der videresender i stedet for at terminere, at net.ipv4.ip_forward er aktiveret. Ejerreglen gælder også der: en boks, der videresender for et subnet, den ikke har, kasserer pakken ligesom VM'en ville. Læs værdien, før du giver tunnelen skylden.
Når præcis ét præfiks fejler
Delvis fejl er det nemmeste tilfælde at læse, fordi alt andet i vejen allerede er bevist. Start med rutelisten, og læs destinationsinterval og next hop på den post, der burde dække præfikset, og læs derefter instansbeskrivelsen og sammenlign dens aliasinterval med den pool, serveren uddeler.
gcloud compute routes list --filter=destination-range~10.164.0.0
gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)En manglende rute viser sig som ingen next hop for præfikset, mens et manglende alias viser sig som en pakke, der kasseres ved grænsefladen; fra klienten ligner de to hinanden og i de to output er de helt forskellige. Hvis begge er til stede, er den resterende mistænkte ccd-irouten for den klient, der gør krav på præfikset.
Skriv de fire værdier ned ved siden af tunnelen: aliasinterval, serverpool, pushede præfikser, VPC-ruter. Et forældet alias ødelægger hver pooladresse, en forældet rute ødelægger én retning, en manglende push skjuler præfikset for klienten, og en forkert iroute sender præfikset til den forkerte peer. Den næste, der tilføjer et subnet, har brug for alle fire på ét sted, og noten er billigere end aftenen.