Fiber7 an einem Linux Router

Konfiguration unter Linux

Dieser Artikel befasst sich mit der Konfiguration von IPv6 + Fiber7. Warum? Weil es zu IPv4 eigentlich nichts zu sagen gibt: DHCP Client starten, fertig. Mit IPv6 würde die Sache eigentlich gleich ausschauen, wenn man:
  • a) Wüsste was man tut ;-)
  • b) Die benötigte Software teil der Distribution ist

Ausgangslage

In diesem howto gehen wir von einem schon aufgeschalteten Fiber7 Account aus. IPv6 ist auf dem Router via SLAAC vermutlich schon aktiv, jedoch wollen wir IPv6 auch 'hinter' die Firewall bringen.

Verwendete Software

Um IPv6 zum fliegen zu bringen, brauchen wir:
  • Eine Linux Kiste mit einem einigermassen aktuellen Kernel (Ich verwende Slackware 14.1 mit 4.x, aber ab Kernel 2.6.x sollte es keine Probleme geben)
  • dhcpcd
  • radvd
  • wide-dhcpv6-client

Konfiguration von dhcpcd

Als erstes bringen wir dhcpcd bei, sich nicht um IPv6 zu kümmern. Neuere Versionen von dhcpcd sollten zwar mit IPv6 und der Prefix Delegation zurecht kommen, die in Slackware 14.1 enthaltene Version (6.0.5) kann dies jedoch nicht richtig und scheint auch sonst manchmal Probleme mit IPv6 zu haben (defaultroute vergessen zu konfigurieren, etc...).
Aus diesem Grund limitieren wir dhcpcd auf IPv4 und überlassen IPv6 SLAAC und wide-dhcpv6-client. Das disablen von IPv6 können wir über die ipv4only Option bewerkstelligen. Meine /etc/dhcpcd.conf schaut etwa so aus:

# Inform the DHCP server of our hostname for DDNS.
hostname
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
duid
# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit
# A list of options to request from the DHCP server.
option classless_static_routes
# Respect the network MTU.
# Some interface drivers reset when changing the MTU so disabled by default.
option interface_mtu
# A ServerID is required by RFC2131.
require dhcp_server_identifier
# A hook script is provided to lookup the hostname if not set by the DHCP
# server, but it should not be run by default.
nohook lookup-hostname
# We run wpa_supplicant from rc.inet1 and/or NM handles it on its own
nohook wpa_supplicant
# ipv6 is configured by the kernel
ipv4only

Konfiguration von SLAAC

Stateless address autoconfiguration ist normalerweise schon aktiv, jedoch müssen wir dem Kernel beibringen, dass er router advertisements auch akzeptieren soll, wenn forwarding enabled ist. Dies passiert via accept_ra=2. Ein Beispiel (eth1 = WAN):
# sysctl -w net.ipv6.conf.eth1.autoconf=1
# sysctl -w net.ipv6.conf.eth1.accept_ra=2

Zwischenstand

Das WAN Interface des Routers sollte nun soweit ready sein:
$ /sbin/ifconfig eth1 eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
      inet 212.51.155.68 netmask 255.255.255.0 broadcast 212.51.155.255
      inet6 2a02:168:2000:3:ec4:7aff:fe51:f0f0 prefixlen 64 scopeid 0x0<global>
      inet6 fe80::ec4:7aff:fe51:f0f0 prefixlen 64 scopeid 0x20<link>
      ether 0c:c4:7a:51:f0:f0 txqueuelen 1000 (Ethernet)

Und wir sollten IPv4 und IPv6 connectivity haben:
$ ping6 google.com
PING google.com(zrh04s06-in-x0e.1e100.net) 56 data bytes
64 bytes from zrh04s06-in-x0e.1e100.net: icmp_seq=1 ttl=58 time=0.502 ms
^C
$ ping gogole.com
PING google.com (173.194.40.65) 56(84) bytes of data.
64 bytes from zrh04s06-in-f1.1e100.net (173.194.40.65): icmp_seq=1 ttl=59 time=0.445 ms
^C

wide-dhcpv6-client installieren

Da unser WAN Interface bereit ist, können wir uns um das LAN Interface kümmern (eth0). Als erstes muss wide-dhcpv6-client installiert werden. Achtung: Wenn das Package nicht teil der verwendeten Distribution ist (und somit manuell kompiliert werden muss), sollte man die Debian Patches nicht vergessen. (Ohne die Kompiliert wide-dhclientv6 auf Slackware nichtmal).
Die Konfiguration von wide-dhcpv6-client ansich ist ziemlich trivial. Beispielconfig:
interface eth1 {
    # send a prefix delegation on eth1 (WAN)
    send ia-pd 0;
};

id-assoc pd 0 {
    # apply the received prefix delegation to eth0 (LAN)
    prefix-interface eth0 {
        sla-id 0; # pick the first delegation
        sla-len 16; # we expect a delegation of 16 bits (48-64)
        ifid 1; # configure eth0 to be ::1
    };
};
Dank dieser Konfiguration sendet wide-dhcpv6-client eine PD-Request auf eth1 (WAN) und konfiguriert eth0 (LAN) entsprechend.
Gestartet wird der Client via:
# dhcp6c -c /etc/wide-dhcpv6-client.conf -D -f eth1
..und schon einige Sekunden später sollte der Zauber auf eth0 gewirkt haben:
$ /sbin/ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
    inet 192.168.1.111 netmask 255.255.255.0 broadcast 192.168.1.255
    inet6 2a02:168:41cc::1 prefixlen 64 scopeid 0x0<global>

Falls dies nicht funktioniert, sollte man mal einen Blick auf seine ip6tables rules werfen. Tipp: Ist ev. Port 546 (udp) geblockt?! ;-)

ip6tables + forwarding konfigurieren

Die Konfiguration via ip6tables ist ziemlich simpel: Dank IPv6 gibts kein masquerade gefummel, juhe.
Folgende konfiguration Blockt erstmal alles grosszügig und forwarded 'related' traffic ins LAN:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [56:3444]
:OUTPUT ACCEPT [12610:1830286]
-A INPUT -s fe80::/64 -p udp -m udp --dport 546 -j ACCEPT # accept dhcpv6 reply
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # accept related connections
-A INPUT -i lo -j ACCEPT # accept everything on loopback
-A INPUT -p ipv6-icmp -j ACCEPT # accept ipv6 ping
-A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT # forward from internet to lan
-A FORWARD -i eth0 -o eth1 -j ACCEPT # forward all from lan to internet
COMMIT

Achja: Nun ists auch mal an der Zeit, das Forwarding zu enablen: # sysctl -w net.ipv6.conf.all.forwarding=1

radvd Konfiguration

Der Router sollte nun eigentlich schon tun, was ein Router so macht (routen). Damit die Clients im LAN auch von ihrem IPv6-Glück wissen, muss ihnen jemand davon erzählen. Da kommt radvd ins Spiel. Auch hier ist die Konfiguration ziemlich simpel, folgendes in /etc/radvd.conf sollte schon reichen:
interface eth0
    {
        AdvSendAdvert on;
        prefix ::/64
        {
            AdvOnLink on;
            AdvAutonomous on;
            AdvRouterAddr on;
        };
    };
radvd wird nun also im LAN (eth0) herumschreien - viel mehr als das Interface muss man ihm auch nicht beibringen da er den delegierten IPv6 Prefix selber aus eth0 auslesen kann.