Tunnla två IPv6-nät över IPv4

Det finns tillfällen då man behöver koppla ihop två olika nätverk med varandra. Normalt sett så använder man då någon form av VPN-lösning. I det här fallet var behovet att koppla ihop två IPv6-nät med varandra som ligger på två olika ställen, med endast Internet som förbindelse.

IPv6 har ju den skillnaden att alla adresser är publika och behovet av NAT finns alltså inte och konceptet ”VPN-tunnel” blir även lite konstigt i det här fallet.

En del av ett IPv6-nätet ska alltså routas vidare och tunnlas till ett annat nät som inte har IPv6-native. Man kallar den här uppsättningen för ”6in4”-tunnel, där IPv6-trafik tunnlas i en IPv4-tunnel.

I såna här lägen passar Linux inbyggda funktion för tunnling in väldigt bra, en s.k. SIT-tunnel. Man skapar ett nytt, ganska korkat, nätverks-gränssnitt på en server och ett likadant på en annan server. All data som stoppas in i ena änden kommer ut i andra och vice versa. Linux-kernel har inbyggt stöd för tre olika sorters tunnling:

* IPIP tunnel. Är väldigt enkelt, men klarar bara IPv4 unicast. Alltså inte routinginformation eller andra protokoll än IPv4
* GRE-tunnel (Generic Routing Encapsulation), kan tunnla vilken trafik som helst, även IPv6. Finns stöd för hos Cisco och många andra, men är lite mer komplex och resurskrävande än SIT.
* SIT-tunnel (Simple Internet Transition), fungerar som en IPIP-tunnel, men för IPv6. Enkel att använda. Även SIT stöds av t.ex. Cisco och många andra fabrikat.

Det går bra att skapa en tunnel publikt över Internet om man vill, men i det här fallet använder jag mig av en befintlig VPN-koppling som finns. Principen är densamma oavsett.

För att trixa till det lite så sätter vi upp en ända med kommandot ”ip” och andra ändan med ”ifconfig” och ”route”. Kommandot ”ip” är modernare och att föredra, men i många fall finns det inte tillgängligt, som t.ex. om du kör Busybox (som många Linux-embedded router använder) eller MacOS.

Vi kör igång lite enkelt:

På server A skapar vi ett nytt nätverksgränssnitt som heter ”6client” (det kan heta vad som helst). Vi anger vår publika IP-adress som i det här fallet är 172.10.10.1, vi anger ”remote” som ”any”, vilket betyder att vi kan ha en dynamisk klient.

ip tunnel add 6client mode sit local 172.10.10.1 remote any
ip link set 6client up

På server B, sätter vi upp en likadan tunnel, men med ”ifconfig” istället. Vi anger IP-adressen för server A och vår egna publika IP-adress:
ifconfig gif0 tunnel 169.254.0.1 172.10.10.1

Mellan server A och server B finns det nu en tunnel, och kollar vi med ifconfig så ser det ut så här på respektive server:

servera:~# ifconfig 6client
6client Link encap:IPv6-in-IPv4
UP RUNNING NOARP MTU:1480 Metric:1
RX packets:5589 errors:0 dropped:0 overruns:0 frame:0
TX packets:4633 errors:168 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:632265 (632.2 KB) TX bytes:1829330 (1.8 MB)

serverb:~# ifconfig gif0
gif0: flags=8151<UP,POINTOPOINT,RUNNING,PROMISC,MULTICAST> mtu 1280
tunnel inet 169.254.0.1 --> 172.10.10.1

Det som är kvar är routing för IPv6. Server A har ett nätverk för IPv6 som heter:

2001:3200:27:6ec::/64 – alltså ett vanligt 64-prefix nät.

Vi skulle vilja routa vidare en del av det här nätet till server B. Vi gör ett /70-nät för server B som innehåller typ 28 triljarder IP-nummer:

2001:3200:27:6ec:100::/70

På server A tilldelar vi själva tunneln en IP-adress. En route kommer då automatiskt att sättas upp, men den tar vi bort och ersätter med en specialare för tunneln. Vi ser till att /70-nätet routas till 6client-gränssnittet:
ip addr add 2001:3200:27:6ec:100::1/70 dev 6client
ip route del 2001:3200:27:6ec:100::/70 dev 6client
ip route add 2001:3200:27:6ec:100::/70 via ::172.10.10.1 dev 6client

På server B gör vi motsvarande, men med ”ifconfig”. Vi gör även en standard-route som tar all IPv6-trafik och skickar via tunneln och server A:
ifconfig gif0 inet6 2001:3200:27:6ec:100::2/70
route -n add -inet6 default 2001:320:27:6ec:100::1

Enkelt! På server B ska vi nu ha full IPv6-åtkomst, men via server A:
serverb:~# traceroute6 -n www.sunet.se
traceroute6 to vision.sunet.se (2001:6b0:8:1::154) from 2001:470:27:6ec:500::2, 64 hops max, 12 byte packets
1 2001:3200:27:6ec:100::1 69.622 ms 66.100 ms 70.273 ms
2 2001:3200:27:6ec::1 69.726 ms 69.696 ms 69.717 ms
3 2001:3200:0:11e::1 70.112 ms 69.733 ms 70.029 ms
4 2001:7f8:d:fb::19 69.967 ms 69.914 ms 69.997 ms
5 2001:6b0:8:1::154 70.285 ms 69.844 ms 66.233 ms

Vi ser ovan att hopp nummer 2 är adressen för tunneln på server A.

Mer information om tunnlar kan du hitta här: http://www.linuxfoundation.org/collaborate/workgroups/networking/tunneling