IPv6, Canal Digital og Linux.

Canal Digital tilbyr, som en av ikke altfor mange norske ISPer ennå, nå IPV6 til kundene! De har derimot bare brukerguide for den trådløse ruteren de tilbyr. Jeg hadde allerede trådløs ruter, og bestemte meg for å sette opp en Linux-maskin som gateway mot Canal Digital. Linux har god støtte for IPV6, så dette burde være grei skuring, men det skulle vise seg at det er noen fallgruver. Disse skal jeg dokumentere her, slik at andre kanskje slipper å gå i dem.

Canal Digital tilbyr ipv6 vha DHCPV6 med prefix delegation. Dette betyr at man vha DHCPV6-protokollen får tildelt et helt nettverk med offisielle addresser, som man så igjen kan dele opp internt. Canal Digital gir deg et såkalt ::/48-nettverk, noe som gir deg plass til hele 65536 lokalnettverk av anbefalt størrelse (::/64). Det er ingen som helst grunn til å bruke noe annet enn ::/64 for lokalnettet, den størrelsen gjør alt lettere. Samtidig vil det *alltid* være stort nok.

Jeg valgte å sette opp wide-dhcpv6 i kombinasjon med radvd etter oppskriften her

Utside-interfacet mitt heter eth0, innside-interfacet eth1. Jeg har DHCP for ipv4 mot kanal digital, og fast ip-adresse på innsiden. Min /etc/network/interfaces inneholder da

iface eth0 inet dhcp

iface eth1 inet static
address 192.168.1.250
netmask 255.255.255.0

Ipv6 settes opp separat, med wide-dhcpv6-klienten. Siden jeg kjører Debian, finnes det oppstartsscript for denne, så det er bare å skru det på, med å putte følgende linje i /etc/default/wide-dhcpv6-client

INTERFACES="eth0"

Min /etc/wide-dhcpv6/dhcp6c.conf blir

interface eth0 { # external facing interface (WAN)
send ia-na 1;
send ia-pd 1;
request domain-name-servers;
request domain-name;
script "/etc/wide-dhcpv6/dhcp6c-script";
};
id-assoc pd 1 {
prefix ::/48;
prefix-interface eth1 {
sla-id 0;
sla-len 16;
};
};
id-assoc na 1 {

};

Denne definerer konfigurasjonen for eth0-interfacet mitt. Den spesifiserer:

  • send ia-na 1; spesifiserer at den skal be om en NA-adresse, dvs. en tildelt ip-adresse
  • send ia-pd 1; spesifiserer at den skal be om en Prefix Definition med id 1.
  • request-linjene sier at den skal be om navnetjenere samt hva domenenavnet vårt er.
  • scriptet er et script som kjøres når en tildeling er gjort, f.eks. for ekstern konfigurasjon. Default-scriptet som kommer med wide-dhcpv6-klienten på Debian håndterer å legge inn info i /etc/resolv.conf
  • id-assoc pd 1-definisjonen er definisjonen for PD-delegeringen med ID 1.
  • prefix ::/48; sier at vi skal be om en prefix av denne størrelsen. Dette er det Canal Digital tildeler uansett…
  • prefix-interface eth1-definisjonen definerer informasjon som skal legges til på innside-interfacet
  • sla-id 0; betyr at første subnett under definisjonen skal brukes, dvs. 0
  • sla-len 16; betyr at 16 bits etter prefix-definisjonen skal definere nettet. 48-16=64, så subnettet blir ::/64
  • id-assoc na 1-definisjonen er definisjonen for den tildelte utside-adressen. Her trenger det ikke å stå noen ting, men den må være der….

På eth1 må vi så sette opp radvd. Dette er en tjeneste for å sette opp stateless autoconfiguration. Kort fortalt forteller den alle klientene på nettverket at ruten til verden kan nåes gjennom den, og så gir den nettverks-definisjonen en klient kan bruke for å generere sin egen adresse på nettverket. Man må da sørge for at klienter har IPV6 og stateless autoconfiguration på. På Linux:

$ cat /proc/sys/net/ipv6/conf/all/disable_ipv6
0
$ cat /proc/sys/net/ipv6/conf/all/accept_ra
1

Min /etc/radvd.conf tar jeg rett fra eksempelet:

interface eth1 # LAN interface
{
AdvManagedFlag off; # no DHCPv6 server here.
AdvOtherConfigFlag off; # not even for options.
AdvSendAdvert on;
AdvDefaultPreference high;
AdvLinkMTU 1280;
prefix ::/64 #pick one non-link-local prefix assigned to the interface and start advertising it
{
AdvOnLink on;
AdvAutonomous on;
};
};

Dette skulle egentlig virket. Men da jeg hadde satt det opp, forsvant prefixet hver halvtime, og i et kvarter deretter, før det så begynte å virke igjen. Så følg med, for her kommer det du ikke finner i noen annen guide!

Aller først skrudde jeg på debug og restartet klienten. Dette gjorde jeg med å endre i /etc/init.d/wide-dhcpv6-client og legge til opsjonene -d -D (etter ) i linjen for start-stop-daemon i start-seksjonen:

start-stop-daemon --start --quiet --pidfile $DHCP6CPID \
--oknodo --exec $DHCP6CBIN -- -d -D -Pdefault $INTERFACES

Jeg skal spare deg for hele feilsøkingen, men til slutt endte jeg opp med å lese kildekoden for å finne ut hva som egentlig skjedde. Da fant jeg en bug i kildekoden! Det finnes to måter å løse denne på:

  • Fikse kildekoden
  • Nettverket og rutingen virker også uten denne utside-adressen, fordi rutingen går via link-local-adresser. Det går alså an å fjerne send-ia na 1;, og alt vil virke ruting-messig.

Patchen er meget enkel (dette er en unified diff):
diff -ru wide-dhcpv6-20080615.old/addrconf.c wide-dhcpv6-20080615.new/addrconf.c
--- wide-dhcpv6-20080615.old/addrconf.c 2008-06-15 09:48:40.000000000 +0200
+++ wide-dhcpv6-20080615.new/addrconf.c 2014-12-02 07:48:07.000000000 +0100
@@ -173,7 +173,7 @@
sacreate ? "create" : "update",
in6addr2str(&addr->addr, 0), addr->pltime, addr->vltime);

- if (sa->addr.vltime != 0)
+ if (sa->addr.vltime != 0 && sacreate)
if (na_ifaddrconf(IFADDRCONF_ADD, sa) < 0) return (-1);

Det som manglet var en sjekk på om sacreate-variabelen var «true» før man prøvde å legge til adressen på interfacet. Er den false, eksisterer adressen fra før, og kallet for å legge den til vil feile. Funksjonen dette er definert i, update_address, vil returnere med -1, og resten av funksjonen ble ikke utført. Denne fiksen var relativt lett, fordi tilsvarende update_prefix-funksjon er nesten helt lik, og har denne testen.

Når denne fiksen ble utført, gikk fornyelsene av utside-addressene også greit, og problemet var løst!

3 kommentarer

  1. Hei!

    Tusen takk for strålende guide! Har blitt noe frustrert i løpet av dagen med å få opp IPv6 fra Telenor Fiber. Med guiden din gikk det meget bedre. 🙂

    Et par ting:
    – Syntaxen i /etc/wide-dhcpv6/dhcp6c.conf er tydeligvis endret. Nå må det legges til en variabel i linjen «prefix ::/48;», slik som dette «prefix ::/48 3000 ;».
    – I /etc/sysctl.conf må to linjer aktiveres/endres/legges til: net.ipv6.conf.all.forwarding=1 (Aktivere forwarding, såklart)
    net.ipv6.conf.eth0.accept_ra=2 (Første booleanske verdi med tre muligheter? Må settes for å ta i mot RA selv om forwarding er aktivert.)

    Takk igjen! Uten denne ville jeg kanskje gitt opp, eller gått tilbake til Tunnelbroker som jeg i det minste klarte å sette opp riktig 😉

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.

Dette nettstedet bruker Akismet for å redusere spam. Lær om hvordan dine kommentar-data prosesseres.