Uwaga: Ta konfiguracja nie działa prawie od dwóch lat, należy ją więc traktować jako przykładową.
6BONE jest ogólnoświatową siecią komputerów wykorzystujących protokół IPv6 to komunikacji między sobą. Sieć ta jest oparta w większości o połączenia tunelujące IPv6 w protokole IPv4. 6BONE służy praktycznie wyłącznie do badania zachowania IPv6 w różnych warunkach i dominującą w nim usługą jest ping oraz traceroute. Podłączenie się do 6BONE to przede wszystkim okazja do poznania wielu aspektów działania sieci opartych o protokół IP, wykorzystania w praktyce rutingu dynamicznego opartego o BGP itp.
Protokół IPv6 w codziennych zastosowaniach nie różni się bardzo od nowoczesnych implementacji IPv4. Podłączenie się do 6BONE wymaga wiedzy teoretycznej i praktycznej w tym zakresie. Pisząc o nowoczesnych implementacjach mam tu na myśli przede wszystkim ruting CIDR, pojęcie prefiksów, długości prefiksu itp. Krótkie wprowadzenie na ten temat można znaleźć w moim artykule ,,Ruting IP w Linuxie 2.2'' (patrz strona o CBQ).
Wiele informacji o samym IPv6 można znaleźć na stronach: www.ipv6.org, www.6bone.net i innych, poświęconych IPv6 oraz 6BONE.
Obsługa IPv6 jest dostępna w Linuxach nowszych niż 2.1.8. W praktyce należy używać wersji 2.2 lub 2.3, możliwie jak najnowszych, ponieważ w międzyczasie usunięto wiele błędów w obsłudzie IPv6.
Szczególnie polecam skorzystanie z pakietów RPM dostępnych w dystrybucji PLD, ponieważ zarówno dostępny w niej kernel, biblioteki i oprogramowanie domyślnie obsługują IPv6.
Podczas konfiguracji kernela należy włączyć następujące opcje:
Sekcja | Opcja | Ustawienie |
---|---|---|
Code maturity level options | Prompt for development and/or incomplete code/drivers | Yes |
Networking options | IP: tunneling | Yes |
Networking options | The IPv6 protocol (EXPERIMENTAL) | Yes |
Networking options | IPv6: enable EUI-64 token format | Yes |
Networking options | IPv6: disable provided based addresses | Yes |
Wszystkie opcje wkompilowałem do kernela na stałe. Niektóre z nich nie chciały działać jako moduły, w szczególności tunneling.
W momencie pisania tego tekstu faktycznym standardem jest glibc-2.1, które posiada wszystkie niezbędne do IPv6 funkcje. Ponadto potrzebne są aplikacje do konfiguracji interfejsów. Jeśli chodzi o IPv4, wielu administratorów używa ifconfig, który w odpowiednio aktualnej wersji umożliwia również operacje na adresach IPv6. Zasłużoną popularność zdobył sobie także program iproute2 Aleksieja Kuźniecowa. Ze względu na to, że iproute2 umożliwia wiele rzeczy, których nie da się zrobić przy pomocy ifconfig, osobiście używam wyłącznie iproute2, zarówno do IPv4 i do IPv6. Poniższe wskazówki zakładają wyłączne korzystanie z iproute2.
I tutaj po raz kolejny warto zapoznać się z PLD, ponieważ jest ono całkowicie oparte o iproute2, zawiera także wszystkie niezbędne pliki konfiguracyjne opisane poniżej.
Do pliku /etc/hosts należy dodać:
::1 ipv6-localhost ipv6-loopback fe00::0 ipv6-localnet ff00::0 ipv6-mcastprefix ff02::1 ipv6-allnodes ff02::2 ipv6-allrouters ff02::3 ipv6-allhosts
Rekordy dotyczące IPv6 w pliku /etc/protocols są zdefiniowane w RFC 2292. Należy do niego dodać następujące pozycje:
hopopt 0 # hop-by-hop options for ipv6 ipv6 41 # ipv6 ipv6-route 43 # routing header for ipv6 ipv6-frag 44 # fragment header for ipv6 esp 50 # encapsulating security payload for ipv6 ah 51 # authentication header for ipv6 ipv6-icmp 58 # icmp for ipv6 ipv6-nonxt 59 # no next header for ipv6 ipv6-opts 60 # destination options for ipv6
Ciekawą właściwością IPv6 jest to, że hosty w sieci lokalnej mogą się porozumiewać między sobą praktycznie bez żadnej dodatkowej konfiguracji, poza podniesieniem interfejsu. Przyznawanie specjalnych, prywatnych adresów jest niepotrzebne, dzięki automatycznie konfigurowanym adresom tzw. link-local, działających w obrębie jednego segmentu sieci lokalnej. Adres link-local te można zobaczyć poleceniem ip addr show scope link, zaczyna się on od prefiksu fe80::. Znając adres link-local drugiego hosta w sieci lokalnej można z nim nawiązać łączność, co można sprawdzić np. przy pomocy pinga.
Adresy link-local nie są nigdy przekazywane przez rutery, w związku z czym nie można przy pomocy korzystać z 6BONE. Do tego celu trzeba uzyskać pulę adresów o zasięgu globalnym (scope global), przy czym obecnie zaczynają się one zawsze od prefiksu 3ffe: (adresy 6BONE) lub 2001: (adresy IANA). Przydziałem adresów tego typu zajmuje się regionalny koordynator pNLA (pseudo Next Level Aggregation), którym w chwili obecnej jest Rafał Maszkowski (kontakt emailem pod adresem <6tunnels@sunsite.icm.edu.pl>). pNLA przydziela pule o długości prefiksu 48 bitów (po 280 adresów). W przypadku posiadania kilku tuneli warto jednak uruchomić dla swojej puli rozgłaszanie przy pomocy dynamicznego protokołu rutingu BGP 4+, co pozwoli na pełne wykorzystanie możliwości 6BONE.
Prostszym rozwiązaniem jest uzyskanie mniejszej puli adresów od kogoś, posiadającego pulę /48, podłączenie się do niego statycznym tunelem i działanie w ramach jego Systemu Autonomicznego (Autonomous System). Jeden i drugi wariant zapewnia przyłączenie do 6BONE, z tym że w przypadku tunelu statycznego należy się raczej nastawić na połączenie tylko do jednego AS i brak możliwości eksperymentowania z dynamicznym rutingiem.
Mając adresy globalne, można przystąpić do konfiguracji interfejsu na danym hoście. W obecnie preferowanym przez polskie 6BONE wariancie jest to zwykłe, numerowane (numbered) połączenie punkt-punkt. W przeszłości testowaliśmy różne inne, nieraz dość egzotyczne, konfiguracje, ale połączenia numerowane adresami globalnymi wydają się być najbardziej uniwersalne i najlepiej rozumiane przez demony BGP.
Konfiguracja tunelu IPv6 w IPv4 składa się z trzech kroków. Pierwszym jest określenie końców tunelu w IPv4.
$ ip tunnel add pipeta mode sit remote 149.156.137.250 local 195.116.211.27
Powyższa linijka jest częścią mojej działającej konfiguracji. Tworzy nowy interfejs sieciowy o nazwie pipeta, działający w trybie SIT (Simple Internet Transition), co jest linuksowym określeniem tunelu typu ,,IPv6 po IPv4''. Tunel zaczyna się na moim hoście 195.116.211.27 (mam kilka równoprawnych interfejsów, więc konieczne jest sprecyzowanie który jest końcem tunelu). Kończy się na hoście 149.156.137.250. Następna czynność to podniesienie interfejsu:
$ ip link set pipeta up
W kolejnym kroku musimy przydzielić nowemu tunelowi jakiś adres IPv6:
$ ip addr add 3ffe:8010:3::2:0:1/126 dev pipeta
To wymaga pewnego komentarza. W przypadku tunelu statycznego adres swojego tunelu otrzymasz zapewne od administratora Systemu Autonomicznego, który cię podłącza. W przypadku własnej puli warto na adresy tuneli przeznaczyć jakąś niedużą sieć, na przykład o długości prefiksu 96 bitów (nota bene ma ona wielkość 32 bitów, czyli dokładnie tyle ile cały współczesny Internet). Sieci o takiej długości można także przydzielać np. interfejsom Ethernet do sieci lokalnej.
Przykładowo, mój interfejs eth0 może mieć adres 3ffe:8010:3::0:0:3/96 (dwa zera można tak naprawdę pominąć). Następna ,,duża'' sieć /96 będzie miała adres ::1:0:0/96, a następna ::2:0:0/96. Z tej ostatniej wydzielamy właśnie małą, dwubitową podsieć /126, zawierającą dwa adresy interfejsów.
Zawsze w przypadku tunelu statycznego (lub przed uruchomieniem BGP) warto ustawić także ruting domyślny na sieci 6BONE:
$ ip route add 3f00::/8 via 3ffe:902:3::2:0:1
Jak widać, powyższa trasa domyślna ma niewiele wspólnego ze znanym z IPv4 0.0.0.0/0. Wynika to stąd, że część prefiksów w IPv6 jest zastrzeżona (jak fe80::) i ruting domyślny musi być bardziej specyficzny.
Jeśli drugi koniec tunelu jest skonfigurowany, to powinniśmy być w stanie przynajmniej go pingować (ping6 jest częścią pakietu iputils, również autorstwa Kuźniecowa):
$ ping6 3ffe:902:3::1:0:1 PING 3ffe:902:3::1:0:1(pipeta.chemia.pk.edu.pl) 56 data bytes 64 bytes from pipeta.chemia.pk.edu.pl: icmp_seq=0 time=73.9 ms 64 bytes from pipeta.chemia.pk.edu.pl: icmp_seq=1 time=10.0 ms 64 bytes from pipeta.chemia.pk.edu.pl: icmp_seq=2 time=9.5 ms 64 bytes from pipeta.chemia.pk.edu.pl: icmp_seq=3 time=18.6 ms
Analogicznie można również spróbować traceroute6 do swojego sąsiada oraz gdzieś dalej. W tym ostatnim wypadku nie trzeba szukać jakiegoś ,,działającego'' adresu, wystarczy spróbować skrócić jakiś znany prefiks i zobaczyć dokąd doprowadzi:
$ traceroute6 3ffe::1 traceroute to 3ffe::1 (3ffe::1) from 3ffe:8010:3::ffff:ffff:9, 30 hops max, 16 byte packets 1 ceti-ipv6.icm.edu.pl (3ffe:8010:3::ffff:ffff:a) 23.077 ms 24.328 ms 33.533 ms 2 3ffe:1400:0:ff00::12 (3ffe:1400:0:ff00::12) 168.333 ms 167.384 ms * 3 uni-c-if.6r1.doc.london.ip6.pipex.net (3ffe:1100:0:c05::1) 222.768 ms * ...itd...
Powyższe adresy ::ffff:ffff:x są prawdziwymi adresami moich interfejsów, zupełnie legalnymi z punktu widzenia adresacji IPv6. Żałuję tylko, że nie skonfigurowałem tuneli na adresach typu ::dead:beef:x ;)
W razie problemów z łącznością niezawodnym narzędziem jest tcpdump. Można go używać na dwa podstawowe sposoby -- jeśli nie działa łączność między końcami tuneli to należy sprawdzić, czy pakiety IPv4 poprawnie przenoszą enkapsulowane IPv6:
$ tcpdump src or dst host 149.156.137.250 Kernel filter, protocol ALL, datagram packet socket tcpdump: listening on eth0 21:37:03.644653 echo2.cyf.ceti.com.pl > pipeta.chemia.pk.edu.pl: v6-in-v4 3ffe:8010:3::3 > 3ffe:8010:3::1:0:1 icmpv6: echo request (DF) [tos 0x10] 21:37:03.655184 pipeta.chemia.pk.edu.pl > echo2.cyf.ceti.com.pl: v6-in-v4 3ffe:8010:3::1:0:1 > 3ffe:8010:3::3 icmpv6: echo reply (DF) [tos 0x10]
Jeśli łączność w warstwie IPv4 jest poprawna, to można przyjrzeć się łączności w warstwie IPv6. Już w powyższym wypadku tcpdump wyświetlał poprawnie zawartości przenoszonych po IPv4 pakietów, ale możliwe jest także nasłuchiwanie samych pakietów IPv6:
$ tcpdump -vv -s512 icmpv6 Kernel filter, protocol ALL, datagram packet socket tcpdump: listening on eth0 21:40:10.261292 3ffe:8010:3::3 > 3ffe:8010::1 (len 64, hop 64) icmpv6: echo request 21:40:10.284221 3ffe:8010::1 > 3ffe:8010:3::3 (len 64, hop 63) icmpv6: echo reply
Należy podkreślić, że w obu wypadkach należy posiadać wersję tcpdumpa ,,rozumiejącą'' IPv6. Wersja taka jest np. rozprowadzana w pakietach PLD.
Adresy IPv6 są przechowywane w rekordach AAAA (w odróżnieniu od rekordów A dla IPv4). Są one obsługiwane przez BIND 4.9.7 oraz 8.1.2. Dla potrzeb IPv6 warto stworzyć w swojej domenie poddomenę ipv6 (np. ipv6.ceti.com.pl) i w niej dodawać adresy maszyn podłączonych do 6BONE. Poniższe przykłady dotyczą BIND 8, przykłady dla wersji 4.9.7 można znaleźć na stronie http://www.visc.vt.edu/ipv6/doc/dns.html.
Wpis w /etc/named.conf:
zone "ipv6.ceti.com.pl" { type master; file "ipv6.hosts"; };
Plik ipv6.hosts:
@ IN SOA tau.ceti.com.pl. hostmaster.tau.ceti.com.pl. ( 1998040301 21600 7200 1209600 172800 ) IN NS tau.ceti.com.pl. IN NS zatoka.icm.edu.pl. IN MX 10 tau.ceti.com.pl. IN MX 20 alfa.ceti.com.pl. IN MX 30 pipeta.chemia.pk.edu.pl. druid IN AAAA 3ffe:902:3::2 inny_host IN AAAA 3ffe:902:3::3 inny_host IN AAAA 3ffe:902:3::4
Do mapowania adresów IPv6 na nazwy kanoniczne służy domena IP6.INT, w której adres jest zapisywany od końca, cyferka po cyferce. Delegację domen w IP6.INT prowadzi węzeł od którego otrzymujemy podsieć, w naszym przypadku pNLA. Przykładowo, dla sieci 3ffe:0902:0003::/48 delegowana jest domena 3.0.0.0.2.0.9.0.e.f.f.3.ip6.int. Dla znajdującego się w tej sieci hosta 3ffe:902:3::2 należy stworzyć rekord:
2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR druid.ipv6.ceti.com.pl.
Jak można się domyślić, po połączeniu łańcucha cyfr odpowiadającego adresowi hosta z łańcuchem odpowiadającym adresowi delegowanej sieci całość powinna mieć długość 32 cyferek. Przykładowe pliki dla BIND 8 znajdują się poniżej:
Wpis w /etc/named.conf:
// 3ffe:902:3::2 zone "3.0.0.0.2.0.9.0.e.f.f.3.ip6.int" { type master; file "3ffe:902:3"; };
Plik /var/named/3ffe:902:3:
@ IN SOA tau.ceti.com.pl. hostmaster.tau.ceti.com.pl. ( 1998040601 ; YYYYMMDDxx 86400 7200 1209600 21600 ) IN NS tau.ceti.com.pl. IN NS zatoka.icm.edu.pl. ; hosty w domenie 3.0.0.0.2.0.9.0.e.f.f.3.ip6.int 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR zatoka.ipv6.icm.edu.pl. 2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR druid.ipv6.ceti.com.pl.
Po skonfigurowaniu DNSu i odwrotnego DNSu programy powinny prawidłowo rozwiązywać zarówno nazwy hostów w domenie ipv6. oraz adresy w domenie odwrotnej.
Pierwsze dwie strony są częsciowo nieaktualne (szczególnie w sekcjach dotyczących uzyskiwania adresów IPv6), ale zawierają wiele przydatnych informacji na temat oprogramowania IPv6 pod Linuxa.