Eine eigenes Freifunk-Netz aufzubauen ist eine tolle Sache. Bis zum Erreichen der kritischen Masse ist man innerhalb des eigenen Neztes jedoch vergleichsweise einsam. Wäre es also nicht noch viel toller, wenn man alle bestehenden Freifunk-Netze miteinander verbinden könnte?
Dies ist tatsächlich möglich. Die existierende Lösung nennt sich Inter City VPN (IC-VPN) und ist ein Transportnetz, welches von Pionieren der Freifunk-Szene geschaffen wurde. Zum Zeitpunkt der Veröffentlichung dieses Artikels befinden sich bereits mehr als 50 Freifunk-Gemeinden innerhalb des Verbundes. Der Anschluss des eigenen Freifunk-Netzes an das IC-VPN ist Inhalt der folgenden Anleitung. Diese wurde aus verschiedenen Quellen zusammengetragen und basiert im Kern auf den Instruktionen der Seite IC-VPN im Freifunk-Wiki. Die Konfiguration des Routing-Dämonen bird wurde von einer Vorlage aus Hamburg abgeleitet.
Als Grundlage für die Vernetzung dienen verschlüsselte VPN-Verbindungen via tinc, einem leichtgewichtigen VPN-Dämonen. Zusätzlich werden mittels des Border Gateway Protocols (BGP) Routen ausgetauscht, um Pakete über das Transportnetz korrekt zustellen zu können. Hierfür verwenden wir den Routing-Dämonen bird. Ein drittes Element ist die Einbindung aller DNS-Server, um Host-Namen auch unter den Domains anderer Freifunk-Gemeinden aufzulösen. Hierfür werden wir die Konfiguration des zuvor eingerichteten DNS-Proxy dnsmasq erweitern.
Um die Verbindungsdaten der anderen Gemeinden nicht manuell eingeben und fortwährend aktualisiern zu müssen, werden wir weiterhin auf die Daten in den öffentlichen Git-Ablagen icvpn, icvpn-meta und icvpn-scripts auf github.com zurückgreifen. Über diese Ablagen sowie das Freifunk Wiki werden wir zusätzlich unsere eigene Gemeinde für das IC-VPN “registrieren”.
In den folgenden Schritten wird von der Installation auf einem bestehenden Internet-Gateway ausgegangen. Die beschriebenen Schritte wurden unter Debian Wheezy ausgeführt und getestet. Für die Konfiguration wurde von den Daten des Freifunk 3Ländereck ausgegangen. Die Einrichtung erfolgt als Benutzer root.
Registrierung im Freifunk-Wiki
Wie bei Freifunk üblich, erfolgt die Registrierung für das IC-VPN ganz unförmlich über das Freifunk-Wiki. Unsere Daten tragen wir in die große Tabelle am Ende der zugehörigen Wiki-Seite ein. Um das Pflegen der Liste zu erleichtern, sollte der Eintrag in alphabetischer Reihenfolge nach dem Namen des Gateways vorgenommen werden:
Stadt / City | dreilaendereck1 |
AS | 65043 |
IPv4 (Transfernetz / Transitnetwork) | 10.207.0.75 |
IPv6 (Site-Local) | fec0::a:cf:0:be |
Public IP | gw1.freifunk-3laendereck.de |
Admin | icvpn@freifunk-3laendereck.de |
Announciert / announces | 10.119.0.0/16, fdc7:3c9d:b889:a272::/64 |
Mit dem Eintrag registrieren wir unser erstes IC-VPN-Gateway unter der Bezeichnung “dreilaendereck1″ (der Titel der Kopfzeile ist ein wenig irreführend). Als Kennzahl für unser “Autonymous System” (AS) wählen wir die Nummer 65043. Diese Nummer bezeichnet unser lokales Freifunk-Netz und wird später von allen unseren IC-VPN-Gateways geteilt. Es scheint sich die Konvention festgesetzt zu haben, Nummern >65000 zu verwenden. Die gewählte Nummer darf noch nicht in Verwendung sein. Eine Tabelle mit den bereits vergebenen AS-Nummern findet man auf einer separaten Wiki-Seite. Dort sollte man zusätzlich einen Eintrag für die eigene Gemeinde vornehmen.
Als IPv4- und IPv6-Adressen für das Gateway wählen wir 10.207.0.75 bzw. fec0::a:cf:0:be. Die erste Adresse entstammt dem Transportnetz 10.207.X.0/16, letztere dem Transportnetz fec0::a:cf:X:0/112. Für den Platzhalter X wird eine einheitliche Wahl nach Land vorgeschlagen. Leider ist diese nicht dokumentiert. Für Deutschland hat sich in beiden Fällen die Zahl “0” durchgesetzt. Ansonsten orientiert man sich am besten an den bestehenden Einträgen bzw. schafft einen “Präzidenzfall”. Wie im Fall der AS-Nummer müssen beide Adressen noch unbelegt sein. Dies überprüft man am besten durch Durchsuchen der ganzen Wiki-Seite. Im Gegensatz zur AS-Nummer werden die Adressen zwischen den eigenen Gateways nicht geteilt.
Als Public IP geben wir für unser Gateway den vollständigen Domain-Namen (Internet!) an; darunter noch eine Kontaktaddresse für den Fall der Fälle. Als letztes folgen die Freifunknetze (IPv4 und IPv6), welche wir über das IC-VPN integrieren möchten.
Konfiguration des tinc-VPN-Dämonen
Damit sind wir soweit, dass wir mit der eigentlichen Einrichtung unseres IC-VPN-Gateways beginnen können. Bevor wir loslegen, müssen wir jedoch zuerst noch den VPN-Dämonen tinc installieren. Da unter Debian Wheezy ein funktionsfähiges Paket existiert, gelingt dies mit:$ apt-get install tinc
Weiterhin beziehen wir die öffentliche Git-Ablage mit den Schlüsseln der Peers, welche am IC-VPN teilnehmen. Das Verzeichnis der Ablage dient uns gleichzeitig zur Aufnahme weiterer Konfigurationsdateien:
Da die Kommunikation über tinc verschlüsselt erfolgt, generieren wir als nächstes ein RSA-Schlüsselpaar. Dieses dient gleichzeitig zur Authentifizierung:
$ cd /etc/tinc
$ git clone https://github.com/freifunk/icvpn
$ tincd -n icvpn -K
Als Dateinamen akzeptieren wir die Vorgaben (rsa_key.priv für den privaten und rsa_key.pub für den öffentlichen Schlüssel). Beide Dateien werden automatisch im Verzeichnis /etc/tinc/icvpn abgelegt. Der Zugriff ist standardmäßig auf den Benutzer root beschränkt.
Um tinc grundlegend zu konfigurieren, erstellen wir eine Basiskonfiguration in der Datei /etc/tinc/icvpn/tinc.conf.header. Diese spezifiziert den Namen der Host-Konfigurationsdatei unseres Gateways (“Name = dreilaendereck1″) sowie den privaten RSA-Schlüssel (“PrivateKeyFile = “…”). Mit der Option “Mode = Switch” teilen wir tinc mit, dass es sich wie ein Ethernet-Switch verhalten soll. Den Ping Timeout erhöhen wir großzügig auf 30 s. Als Port verwenden wir die Nummer 656. Mit “Hostnames = Yes” erlauben wir die Auflösung von IP-Adressen in Domain-Namen. Dies erleichtert später die Interpretation der Log-Dateien:
Name = dreilaendereck1 PrivateKeyFile = /etc/tinc/icvpn/rsa_key.priv Mode = Switch PingTimeout = 30 Port = 656 Hostnames = yes
Den Inhalt der Datei kopieren wir manuell in die eigentliche Konfigurationstatei /etc/tinc/icvpn/tinc.conf:
$ cp icvpn/tinc.conf.header icvpn/tinc.conf
Um notwendige Netzwerkmanipulationen automatisch durchzuführen, erstellen wir das Skript /etc/tinc/icvpn/tinc-up, welches von tinc nach erfolgtem Verbindungsaufbau aufgerufen wird. In diesem aktivieren wir zuerst die Schnittstelle (“ip link set …”). Danach weisen wir der Schnittstelle eine IPv4 (“ip addr add…”) sowie IPv6-Addresse (“ip -6 addr add…”) zu. Diese müssen identisch mit den zuvor für den Router registrierten Adressen innerhalb des IC-VPN-Transportnetzes sein:
#!/bin/sh /sbin/ip link set dev $INTERFACE up /sbin/ip addr add dev $INTERFACE 10.207.0.75/16 broadcast 10.207.255.255 scope link /sbin/ip -6 addr add dev $INTERFACE fec0::a:cf:0:be/96 preferred_lft 0
Analog erstellen wir das Skript /etc/tinc/icvpn/tinc-down, welches von tinc nach Terminierung der Verbindung aufgerufen wird. In ihm werden der Netzwerkschnittstelle alle IP-Adressen wieder entzogen und die Schnittstelle im Anschluss deaktiviert:
#!/bin/sh /sbin/ip addr del dev $INTERFACE 10.207.X.Y/16 broadcast 10.207.255.255 /sbin/ip -6 addr del dev $INTERFACE fec0::a:cf:X:Y/96 /sbin/ip link set dev $INTERFACE down
Zuletzt machen wir die beiden Skripte ausführbar:
$ chmod 755 /etc/tinc/icvpn/tinc-*
Um die tincd-Konfiguration automatisch um die Peers zu ergänzen, installieren wir das folgende Skript unter /usr/local/bin/update-tincd-icvpn. Es überprüft zuerst die entfernte Git-Ablage auf Änderungen und gleicht diese gegebenenfalls lokal ab. Im Anschluss wird die Konfigurationsdatei tinc.conf auf Basis der Grundkonfiguration tinc.conf.header erstellt. Zusätzlich wir der Basiskonfiguration für jeden Host im hosts-Verzeichnis eine “ConnectTo”-Zeile hinzugefügt. Zuletzt wird tincd mittels des Signals HUP aufgefordert, die Konfiguration neu zu laden:
TINC_ICVPN=/etc/tinc/icvpn # IC-VPN configuration file TINC_CONF=tinc.conf # IC-VPN configuration file header TINC_CONF_HEADER=tinc.conf.header # IC-VPN host file directory TINC_HOSTS=hosts function getCurrentVersion() { # Get hash from latest revision git log --format=format:%H -1 } cd $TINC_ICVPN # Get current version hash GIT_REVISION=$(getCurrentVersion) # Automagically commit local changes # This preserves local changes git commit -m "CRON: auto commit" # Pull latest changes from upstream git fetch git merge origin/master -m "Auto Merge" # Get new version hash GIT_NEW_REVISION=$(getCurrentVersion) if [ $GIT_REVISION != $GIT_NEW_REVISION ] then # Start with header file for tinc configuration cp $TINC_CONF_HEADER $TINC_CONF # Iterate through hosts in host directory for HOST in $TINC_HOSTS/*; do # Skip hosts without address grep -q '^Address' -- "$HOST" || continue # Add ConnectTo line for current host echo "ConnectTo = ${HOST##*/}" >> $TINC_CONF done # Reload updated configuration echo "Reload tincd configuration." kill -HUP $(pidof tincd) fi
Mit dem folgenden Befehl machen wir das Skript ausführbar:
$ chmod 750 /usr/local/bin/update-tincd-icvpn
Damit es in Zukunft regelmäßig (in unserem Fall stündlich) ausgeführt wird, fügen wir der Datei /etc/crontab die folgenden Zeilen hinzu:
# Update tincd IC-VPN peers every hour. 12 * * * * root update-tincd-icvpn > /dev/null
Um cron zur Übernahme der Änderung zu bewegen, starten wir den Dämonen im Anschluss neu:
$ /etc/init.d/cron restart