Een gateway kan een reiziger zowel een IPv4- als een IPv6-virtueel adres geven, terwijl de buitenste tunnel nog steeds over IPv4 loopt. Dat zijn onafhankelijke beslissingen, en ze als één behandelen is waar dual-stack-plannen meestal uit elkaar vallen. De binnenste families van de client, de beschermde prefixen die hij kan bereiken, en het transport dat de inkapseling draagt, zijn drie afzonderlijke keuzes.

De meeste verwarring ontstaat doordat het woord dual stack wordt toegepast op een ontwerp dat maar op één plek dual stack is. Een dienst kan intern dual stack zijn, single stack op zijn buitenadres, en toch prima werken voor clients. Wat hij niet kan, is per ongeluk werken.

Twee families binnen, één pad buiten

De buitenste verbinding is IKE over UDP, en die heeft één bereikbare adresfamilie nodig vanaf waar de client zich bevindt. Een binnenste IPv6-adres vereist geen provider met IPv6, omdat het binnenste pakket lading is in het buitenste. Veel werkende uitrollingen dragen IPv6-prefixen over een uplink met alleen IPv4.

Wat het buitenste pad werkelijk beperkt, is bereikbaarheid en NAT-traversal. Als de gateway alleen een IPv4-adres aankondigt, kan een client op een netwerk met alleen IPv6 helemaal geen verbinding maken, ongeacht welke pools je hebt geconfigureerd. Kies de buitenste familie op basis van je clientpopulatie, niet op basis van het interne adresplan.

Geef de client een adres in elke familie

Om beide families vragen is één regel aan de clientkant, mits de gateway iets te verdelen heeft. Benoemde pools houden de bronnen gescheiden van de dienstnetwerken, en dat is de eigenschap die firewallregels zes maanden later leesbaar maakt.

pools {
  pool4 { addrs = 10.90.0.0/24 }
  pool6 { addrs = fd42:90::/64 }
}
connections {
  private-access {
    version = 2
    pools = pool4, pool6
    local  { auth = pubkey  certs = gateway.pem  id = vpn.example.com }
    remote { auth = pubkey  cacerts = ca.pem  vips = 0.0.0.0, :: }
    children {
      private { local_ts = 10.60.0.0/16, fd42:60::/48  remote_ts = dynamic }
    }
  }
}

De vips waarde vraagt om een adres uit elke familie, en de poollijst bepaalt waar die adressen vandaan komen. De strongSwan-documentatie over virtuele IP-adressen behandelt meerdere verzoeken en pooltoewijzing, inclusief het punt dat een client die om een specifiek adres vraagt slechts een voorkeur uitdrukt die de responder mag overrulen. Bouw geen toegangsregel die aanneemt dat de client altijd dezelfde waarde krijgt.

Genereer je eigen unieke lokale prefix in plaats van het voorbeeld te kopiëren. Twee organisaties die beide fd42::/16 het uitrollen, ontdekken de botsing bij de eerste onderlinge verbinding, en dat diagnosticeren is niet prettig.

Selectors beschrijven bestemmingen, niet bronnen

De lokale verkeersselectors van de child-SA zeggen welke beschermde netwerken achter de gateway liggen, en de remote-selectors beschrijven wat de client als bron mag gebruiken. Een virtueel pooladres hoort aan de bronkant van dat beleid; het in de bestemmingslijst zetten is een veelvoorkomende verkeerde lezing van de configuratie.

Beide families hebben retourroutes en toegestane doorsturing op de gateway nodig. Een prefix aan een selector toevoegen zonder route terug naar de pool levert een tunnel op die tot stand komt, één verkeersrichting doorlaat en het antwoord stil laat vallen. De selector is beleid, geen routing.

Houd de pools en de dienstprefixen in aparte blokken van je adresplan. Wanneer ze overlappen, kan een route die een beschermde host zou moeten bereiken op een pooladres passen en in de tunnel verdwijnen.

DNS en het antwoordpad bepalen of het af voelt

Antwoorden van de resolver zijn onafhankelijk van het transport waarmee de resolver wordt bereikt. Een naam kan een A-record, een AAAA-record of beide teruggeven, en de client kiest volgens zijn eigen voorkeursregels. Als een interne dienst een AAAA-record publiceert maar niets dat prefix routeert, proberen clients op dual-stack-netwerken eerst het IPv6-pad en blijven daar zitten tot het mislukt. Niets in de tunnelconfiguratie ziet er dan verkeerd uit.

Bepaal dus per naam welke families bruikbaar moeten zijn, en controleer dan dat het bijbehorende prefix in de selector staat en een retourroute heeft. Dat is een beslissing per dienst. Beide recordtypen ongedifferentieerd publiceren is hoe een werkende dienst met alleen IPv4 voor de helft van zijn gebruikers time-outs begint te krijgen.

Verifieer beide families voordat je het af noemt

Configuratie die laadt, is geen configuratie die werkt. Lees de toestand die de daemon meldt, bevestig de pooltoewijzingen en kijk dan naar de routes die de client daadwerkelijk heeft geïnstalleerd.

swanctl --list-sas
swanctl --list-pools
ip -6 addr show scope global
ip -6 route get fd42:60::10

De eerste twee opdrachten tonen de opgezette child-SA’s en welke pools nog adressen vrij hebben, zodat een plan dat voor de eerste client werkt en bij de tiende faalt zichtbaar wordt. De laatste twee tonen of de client een wereldwijd IPv6-adres uit de pool heeft gekregen en waar verkeer naar een beschermd prefix werkelijk heen zou gaan. Vergelijk het toegewezen adres met de pool die je hebt geconfigureerd, niet met het adres waarop je hoopte. Als de responder onder zijn beleid een andere waarde heeft gekozen, moeten de routes en firewallregels nog steeds bij zijn keuze passen.

Test daarna één beschermde host per familie, en test een naam die naar beide resolvet. Een test met één familie zegt je niets over de helft van het plan die je niet hebt geoefend, en daar zit meestal de ontbrekende route.

Gerelateerde artikelen