Connecting a network to a global IPv6 space

    Some time ago, in the comments to the article “IPv6 gateway for the local network”, I was asked to talk about how I activated IPv6 in one of my projects. I'll start with a few words about the project itself. CareNet is the result of cooperation between two large Swedish universities: KTH Royal Institute of Technology and Karolinska Institutet. In short, CareNet is a system for monitoring palliative patients outside the hospital. A small device is installed at the patient’s house, which has Internet access and is connected via VPN to CareNet servers. The device includes an HDVC client, a set of sensors for monitoring the patient’s condition and means of access to the medical portal containing all the patient information. Medical information is available to both the patient and the doctor.

    But the article is about IPv6 activation, so we are more interested in not the client, but the central part of the CareNet infrastructure. It includes a number of routers and servers that are located at the KTH University site in Stockholm. The diagram gives an idea of ​​the scale of the network.



    For 20 weeks, my task was to maintain the indicated infrastructure in working condition and increase its functionality. One of the tasks I defined for myself was the activation of IPv6 in this small network topology. Moreover, in addition to deploying IPv6 within the network, I also wanted to connect CareNet to the global IPv6 space.

    Addressing


    I started by asking the university administration to give me a piece of the IPv6 lab range for my small sandbox. The prefix 2001: 6b0: 32 :: / 49 was solemnly delegated to me. At first I was offended and wanted to run several times and ask for more, but in the end, having dropped the addressing scheme this way and that on paper, I decided that 6x10 23 addresses should be enough.
    Having decided on the addressing, I configured the interfaces on the routers. Here it must be said that the routers in CareNet are unusual, built on the basis of the high-performance hardware-software Linux platform Bifrost. This is a university development now entering the commercial market. Interfaces between routers have a bandwidth of 10 Gb / s. For routing (control plane) the Quagga software package is responsible.

    Internal Routing, OSPFv3


    By adding IPv6 addresses to the router interfaces, I launched OSPFv3 as a dynamic routing protocol. Basic settings, one OSPF zone 0.0.0.0. There is no technical explanation why OSPF will not be selected. Personally, I choose by name. RIPng I do not like. Here IS-IS with pleasure, but Quagga does not support it.
    Quagga worked with the package for the first time, but got used to it instantly because the command interface is similar to the Cisco CLI. I give an example configuration of the ospf6d daemon for two routers:

    hostname VR-ospf6d

    !
    router ospf6
    router-id 192.16.126.9
    interface eth1 area 0.0.0.0 #интерфейс в сторону маршрутизатора HR

    interface eth2 area 0.0.0.0 #интерфейс в сторону маршрутизатора KR

    interface dummy0 area 0.0.0.0 #loopback

    !

    hostname KR-ospf6d

    !
    interface eth2 #интерфейс в сторону клиентов и серверной фермы

    ipv6 ospf6 passive #деактивация сообщений OSPF Hello

    !
    router ospf6
    router-id 192.16.126.10
    interface eth2 area 0.0.0.0 #интерфейс в сторону клиентов и серверной фермы

    interface eth0 area 0.0.0.0 #интерфейс в сторону маршрутизатора VR

    interface dummy0 area 0.0.0.0
    !

    Dynamic Address Allocation, DHCPv6


    Routing was activated, and the next question arose about dynamically allocating IPv6 addresses to servers in the farm and clients in access networks. It was decided to assign this task to the DHCPv6 server. I deployed two DHCPv6 servers: ISC DHCP and Dibbler. A contest was organized under the terms of which one of the servers that will serve the client first by allocating an IPv6 address to it will remain operational. Dibbler was quick, so ISC DHCP was destroyed. Example of setting ranges of allocated addresses:

    vp@dns:~$ cat /etc/dibbler/server.conf

    ...

    option dns-server 2001:6b0:32:0::66 #IPv6 адрес сервера DNS


    class {
    pool 2001:6b0:32:0::0000 - 2001:6b0:32:0::0fff #диапазон выделяемых адресов IPv6

    }
    client duid 0x000100011657fdc9be10f563c5bf {
    address 2001:6b0:32:0::69 #статический адрес Ipv6 для сервера SIP

    }
    ...


    Two interesting differences from the usual DHCP for IPv4:
    1. First, DHCPv6 does not provide the client with the default gateway address, which in our case is a router in Kista. The gateway itself must declare its existence in accordance with the Neighbor Discovery mechanism. RFC 2461 describes this mechanism in detail, I’ll just mention that the router should periodically send a Router Advertisement (RA) message, declaring itself the default gateway in this segment. In my case, for this it was necessary to supplement the configuration of the KR router:

      hostname KR-zebra

      !
      interface eth2 #интерфейс в сторону клиентов и серверной фермы

      no ipv6 nd suppress-ra #не подавлять сообщения RA

      ipv6 nd prefix 2001:6b0:32::/64 no-autoconfig #IPv6 префикс для сегмента

      !

    2. The second feature is on what basis the DHCPv6 server allocates static addresses. If in DHCPv4 it was enough just to set the MAC address of the device to which you need to allocate a permanent address, then in the DHCPv6 server configuration you will have to register the so-called DHCP Unique Identifier (DUID). I suggest to find it in the configuration given earlier independently. You can read about the DUID in RFC 3315 .

    External Routing, BGP


    Internal routing is functioning, clients have received addresses, it’s up to you to open IPv6 Internet access. Guessing that my immediate neighbor - AS 2839 (KTH-LAN) is already part of the global IPv6 space, I dared to ask its administrators to allow me to establish an additional BGP session with KTH-LAN to advertise my IPv6 prefix. After agreeing all the technical details, the IPv6 BGP neighborhood was established. It took me a couple of days to convince the autonomous system of the next further in the chain (SUNET) to update their incoming BGP filters and finally release my prefix into free float. Bgpd daemon configuration:

    hostname VR-bgpd

    !
    router bgp 8973 #номер автономной системы CareNet


    bgp router-id 192.16.126.1
    neighbor 2001:6b0:1:2::1 remote-as 2839 #IPv6 адрес BGP-соседа


    no neighbor 2001:6b0:1:2::1 activate
    !
    address-family ipv6
    network 2001:6b0:32::/49 #объявляемый префикс

    neighbor 2001:6b0:1:2::1 activate
    neighbor 2001:6b0:1:2::1 soft-reconfiguration inbound
    neighbor 2001:6b0:1:2::1 route-map only-default6-in in #входящий фильтр префиксов

    neighbor 2001:6b0:1:2::1 route-map only-carenet6-out out #исходящий фильтр префиксов

    exit-address-family
    !
    ipv6 prefix-list CARENET6 seq 5 permit 2001:6b0:32::/49 #объявляем только 2001:6b0:32::/49

    ipv6 prefix-list DEFAULT6 seq 5 permit ::/0 #принимаем только ::/0

    !
    route-map only-default6-in permit 10
    match ipv6 address prefix-list DEFAULT6
    !
    route-map only-carenet6-out permit 10
    match ipv6 address prefix-list CARENET6
    !

    In addition to filtering announced and received prefixes, it would be nice to activate identical filters directly for traffic crossing the border of the autonomous system, as a mechanism to counter “IP spoofing” attacks. A simple ACL ACL will do the trick.

    After setting up BGP and sorting out the filters, I opened the champagne and prepared to meet the first ICMPv6 answer, better known as ping, from ipv6.google.com. Route trace below:

    vp@dns:~$ traceroute6 ipv6.google.com

    traceroute to ipv6.l.google.com (2a00:1450:4010:c01::93) from 2001:6b0:32::66, 30 hops max, 24 byte packets
    1 kis-lanlink.carenet-se.se (2001:6b0:32::1) 1.13 ms 0.457 ms 0.49 ms
    2 lpp01m02-in-x93.1e100.net (2a00:1450:4010:c01::93) 0.944 ms 0.933 ms 1.115 ms
    3 br1g-cn6-p2p.gw.kth.se (2001:6b0:1:2::1) 1.261 ms 1.3 ms 1.091 ms
    4 * * *
    5 t1fre-ae5-v1.sunet.se (2001:6b0:1e:1::36) 1.467 ms 1.256 ms 1.239 ms
    6 se-fre.nordu.net (2001:948:0:f051::1) 1.718 ms 1.562 ms 1.463 ms
    7 se-tug.nordu.net (2001:948:1:1::3) 1.344 ms 1.315 ms 1.269 ms
    8 se-tug2.nordu.net (2001:948:1:5::3) 1.505 ms 1.359 ms 1.287 ms
    9 google-gw.nordu.net (2001:948:0:f008::3) 1.443 ms 1.616 ms 1.298 ms
    10 2001:4860::1:0:26ec (2001:4860::1:0:26ec) 1.896 ms 2.002 ms 1.911 ms
    11 2001:4860::8:0:26e5 (2001:4860::8:0:26e5) 41.025 ms 11.119 ms 11.02 ms
    12 2001:4860::2:0:2aaf (2001:4860::2:0:2aaf) 11.223 ms 11.455 ms 11.955 ms
    13 2001:4860:0:1::4d0 (2001:4860:0:1::4d0) 22.558 ms 21.472 ms 17.857 ms
    14 lpp01m02-in-x93.1e100.net (2a00:1450:4010:c01::93) 10.833 ms 10.878 ms 13.669 ms

    DNS for IPv6


    In the end, I’ll tell you how DNS was configured to work with IPv6 addresses. It was not necessary to install the DNS server from scratch, because the network already had a BIND server serving the IPv4 range. IPv6 entries have been added to the direct DNS zone to existing IPv4 addresses. Pretty straightforward and simple, but just in case, I’ll give an example configuration:
    vp@dns:~$ sudo cat /etc/bind/zones/external/carenet-se.se.db

    ...

    ;; Routers' loopacks
    vr IN A 192.16.126.9
    vr IN AAAA 2001:6b0:32:10::1
    ...


    But with the reverse zone (reverse DNS lookup) had to tinker. A separate file was created, named according to the canons 2.3.0.0.0.b.6.0.1.0.0.2.ip6.arpa. The name is formed from the 2001: 6b0: 32 :: / 49 prefix written in reverse order and supplemented with zeros. Further, reverse DNS records for all IPv6 systems on the network are added in a rather unfriendly and difficult to read format. Part of the configuration is shown below:

    vp@dns:~$ sudo cat /etc/bind/zones/2.3.0.0.0.b.6.0.1.0.0.2.ip6.arpa

    $TTL 600
    $ORIGIN 2.3.0.0.0.b.6.0.1.0.0.2.ip6.arpa. #маска

    @ IN SOA ns.carenet-se.se. adm.carenet-se.se. (
    2011120101;
    28800;
    604800;
    604800;
    86400);

    IN NS ns.carenet-se.se.
    IN NS ns.ssvl.kth.se.
    IN NS ns2.ssvl.kth.se.

    6.6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR ns.carenet-se.se.
    ...

    $ORIGIN 0.0.0.0.2.3.0.0.0.b.6.0.1.0.0.2.ip6.arpa.
    9.6.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR sip.carenet-se.se.
    4.9.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR log.carenet-se.se.
    ...

    $ORIGIN 0.1.0.0.2.3.0.0.0.b.6.0.1.0.0.2.ip6.arpa.
    1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR vr.carenet-se.se.
    ...


    Conclusion and additional information


    The goal is achieved, CareNet has become part of the global IPv6 domain. Detail the whole process of activating IPv6 I described in official documents of the project, are available on the website CareNet. You can also find circuits there. The project is academic, the information is open and does not contain any secrets. Thanks for attention.

    Also popular now: