Externe gebruikers bereiken de tweede locatie niet via de VPN-hub
Transit via de hub vraagt drie opzoekingen: de clientroute, de uitgaande route van de hub en het retourpad aan de verre kant, plus één afgebakende doorstuurregel.
Een externe gebruiker verbindt met de hub, bereikt de fileserver op het eigen LAN van de hub, en alles ziet er gezond uit. Dan opent hij een share op 10.20.0.50 op het hoofdkantoor, die de hub via een aparte site-to-site-tunnel bereikt, en het loopt vast. Beide tunnels staan omhoog en beide tellers lopen op, dus geen enkele tunnel is stuk. De hub passeren zijn drie routeringsbeslissingen op drie apparaten, en een tunnel vervoert alleen de prefixes waarvoor hij is gebouwd. Dit is de volgorde die ik controleer, en het commando dat laat zien of elke stap klopt.
Transit vraagt drie opzoekingen, niet één tunnel
Elk apparaat doet zijn eigen longest-prefix-match en vergeet die. De laptop moet 10.20.0.50 de tunnel in sturen in plaats van naar zijn lokale router. De hub moet een pakket dat op de remote-access-interface aankwam doorgeven aan de site-to-site-interface. Het hoofdkantoor moet een antwoord voor het adres van de gebruiker terugsturen door de tunnel. Faalt één van de drie, dan ziet dat er in de browser hetzelfde uit: stilte.
Daarom bewijst het apart testen van elke tunnel zo weinig. Pingen naar het LAN-adres van de hub oefent de eerste beslissing, en pingen naar de hub vanaf het hoofdkantoor oefent de derde. Het pakket dat faalt heeft de gebruikerspool als bron en de tweede locatie als bestemming, dus schrijf die prefixes eerst op. Hier is de pool 10.80.0.0/24, het LAN van de hub 10.10.0.0/24 en het hoofdkantoor 10.20.0.0/24.
Duwn het verre prefix naar de externe client
Op een OpenVPN remote-access-server leert de client routes bij het verbinden. Zonder push stuurt een client met split-tunnel 10.20.0.50 naar zijn eigen gateway en komt het pakket nooit in de tunnel.
push "route 10.20.0.0 255.255.255.0"
Een gepushte route geldt bij het verbinden van de client, dus een gebruiker die online blijft ziet niets tot hij opnieuw verbindt. Controleer op de client: ip route get 10.20.0.50 op Linux, route print op Windows. De uitvoer hoort de tunnelinterface te noemen.
De push helpt de hub niet. Het is een bericht aan de client, geen route op de server en geen toestemming om door te sturen, dus een hub met de perfecte pushregel laat de stroom alsnog één hop later vallen. Dat is de gebruikelijke reden waarom mensen concluderen dat de push mislukte.
Geef de hub een echte uitgaande route
De hub heeft zijn eigen volgende hop nodig voor het prefix van het hoofdkantoor. Op een gerouteerde tunnel is dat een gewone route via de site-to-site-interface, en één commando toont zowel de gekozen route als de gekozen bron:
ip route get 10.20.0.50 from 10.80.0.25
sudo ip route add 10.20.0.0/24 via 172.30.0.2 dev s2s0
Als het site-to-site-deel zelf OpenVPN is, kan de route in die configuratie staan met het tunneladres van de peer als gateway: route 10.20.0.0 255.255.255.0 172.30.0.2. De gateway is niet optioneel. Laat je hem weg, dan valt de volgende hop terug op een implementatiestandaard, die verschilt tussen een client met één peer en een hub met meerdere peers.
Policy-gebaseerde IPsec is anders: de kernel van de hub stuurt het pakket naar zijn normale LAN-gateway en het beleid vangt het op weg naar buiten, dus een tunnelroute doet ofwel niets of leidt verkeer langs het beleid. Let op de bron in het commando hierboven, want 10.10.0.1 in plaats van het pooladres betekent dat de kernel een adres koos dat de verre kant zal weigeren. iroute is ook niet het antwoord; het vertelt de server welke client een subnet achter zijn eigen tunnel bezit, niet waar verkeer voor een derde locatie heen moet.
Breid de verre kant uit naar de gebruikerspool
Het hoofdkantoor dekt al het LAN van de hub, 10.10.0.0/24. De gebruikerspool is een tweede prefix en moet ook in de selectors staan, anders dekt geen beleid een antwoord dat aan 10.80.0.25 is gericht. Elke peer noemt hetzelfde paar prefixsets vanaf zijn eigen kant:
# strongSwan swanctl.conf, on the hub
local_ts = 10.10.0.0/24, 10.80.0.0/24
remote_ts = 10.20.0.0/24
# on the headquarters peer
local_ts = 10.20.0.0/24
remote_ts = 10.10.0.0/24, 10.80.0.0/24
De local_ts van het ene apparaat is de remote_ts van het andere. Kopieer je het hubblok naar het hoofdkantoor, dan is het paar omgekeerd, en komt de child SA nooit omhoog.
De oudere ipsec.conf syntaxis gebruikt een kommagescheiden leftsubnet. De lopende security association houdt de selectors die hij onderhandelde, dus herstel de tunnel na de wijziging. Een selector die om 10:00 is gewijzigd en wordt getest tegen een SA die om 09:40 omhoogkwam, faalt nog steeds, terwijl het configuratiebestand er de hele tijd correct uitziet.
Controleer dan de laatste hop. ip route get 10.80.0.25 op het verre eindpunt hoort de tunnel in te wijzen. Als de dienst een LAN-router als standaardgateway gebruikt, heeft die router ook de retourroute nodig, anders sterft het antwoord daar. tcpdump -ni eth1 host 10.80.0.25 op dat segment laat zien of het antwoord het eindpunt helemaal verliet.
Sta de stroom toe op de hub
Doorsturen moet aanstaan en het pad moet zijn toegestaan. Beperk de regels tot de twee prefixes in plaats van alles tussen de interfaces te accepteren.
sysctl -w net.ipv4.ip_forward=1
iptables -I FORWARD -i tun0 -o s2s0 -s 10.80.0.0/24 -d 10.20.0.0/24 -j ACCEPT
iptables -I FORWARD -i s2s0 -o tun0 -s 10.20.0.0/24 -d 10.80.0.0/24 -j ACCEPT
Reverse-path-filtering is de stille fout ernaast: met de twee benen op verschillende interfaces kan rp_filter=1 het antwoord laten vallen terwijl de teller van de acceptregel nooit beweegt. Vergelijk iptables -vnL FORWARD voor en na een poging. Een regel die nooit oploopt wordt niet bereikt, dus kijk een laag lager in plaats van hem te herschrijven.
Als slechts één groep transit nodig heeft, zet de route dan in een bestand per client onder client-config-dir in plaats van de globale push te verbreden. Source-NAT op de hub haalt ook de noodzaak van een verre retourroute weg, maar verbergt het adres van de gebruiker, zodat de logs van de verre locatie en adresgebaseerde regels gebruikers niet meer onderscheiden.
Controleer vanaf de client en draai daarna in omgekeerde volgorde terug
Test een TCP-poort, niet alleen ICMP, omdat een ping kan slagen terwijl de dienst geblokkeerd blijft. nc -vz 10.20.0.50 445 en traceroute -n 10.20.0.50 vanaf de client laten zien of de tweede hop het tunneladres van de hub is. Op de hub tcpdump -ni tun0 host 10.20.0.50 en hetzelfde filter op de site-to-site-interface: een verzoek op beide zonder antwoord op een van beide verplaatst het probleem naar de verre kant.
Test dan iets dat geblokkeerd moet blijven. Als ook een host die de pool nooit zou moeten bereiken antwoordt, heb je meer dan transit geopend en moet je de regels smaller maken. Een hub die alles naar elke spoke doorstuurt, slaagt voor de eerste test en faalt voor de tweede.
Houd een terugdraailijst bij, want er zijn vier objecten gewijzigd en drie zijn makkelijk te vergeten: de gepushte route, de route van de hub, de selectors en de firewallregels. Draai ze in omgekeerde volgorde terug, herstel de SA en laat één gebruiker opnieuw verbinden. Een gedeeltelijke terugdraai laat een route achter die naar een tunnel wijst die niet meer past, wat lastiger te lezen is dan de oorspronkelijke stilte. De OpenVPN 2.6-handleiding documenteert push, route en iroute voor jouw versie.