Freifunk-Gateway aufsetzen/babeld: Unterschied zwischen den Versionen

Aus Freifunk Franken
Wechseln zu:Navigation, Suche
 
(77 dazwischenliegende Versionen von 11 Benutzern werden nicht angezeigt)
Zeile 4: Zeile 4:


== Funktion ==
== Funktion ==
Babel wird als Layer 3 Routingprotokoll in der Freifunk Franken Backbone verwendet. So werden alle Gateways über das Protokoll direkt oder indirekt miteinander verbunden. Babel tauscht gegenseitig die Routen der Gateways aus, so das jedes Gateway weiß über welchen Weg es eine andere Hood erreichen kann.
Babel wird als Layer 3 Routingprotokoll in der Freifunk Franken Backbone verwendet. So werden alle Gateways über das Protokoll direkt oder indirekt miteinander verbunden. Babel tauscht gegenseitig die Routen der Gateways aus, so das jedes Gateway weiß über welchen Weg es eine andere Hood erreichen kann. Das eigentliche Routing übernimmt der Linuxkernel. Babel ist nur für den Austausch der Informationen zuständig.


== Vorsicht ==
== Vorsicht ==
Zeile 10: Zeile 10:


IP Adressen dürfen nur announced werden, wenn sie auch erreicht werden können.
IP Adressen dürfen nur announced werden, wenn sie auch erreicht werden können.
Wer das Subnetz für Hood A announced muss Hood A auch erreichen können.
Wer das Subnetz für eine Hood announced, muss diese Hood auch erreichen können.


== Installation ==
== Installation ==


Babel kann direkt aus der Distribution installiert werden.
babeld kann aktuell meist '''NICHT''' aus der Distribution installiert werden. Die dort ausgelieferte Version ist zu alt.


<code>
babeld muss daher selbst kompilieret und installiert werden.
apt-get install babeld
</code>


Debian liefert eine recht alte Version mit.  
Empfohlen ist aktuell die Version '''1.10''', mindestens muss jedoch '''1.9.0''' installiert werden.
Es ergibt Sinn Babel aus dem Git selbst zu bauen (Version  >=1.8.2):
Ein Patch wie für 1.9.0/1.9.1 ist (derzeit) nicht mehr nötig.
Getestet wird aktuell 1.12.1, hier müssen submodule hinzugefügt werden (was auch immer das ist...)


https://github.com/jech/babeld
Kurzanleitung fürs bauen und installieren der aktuell empfohlenen Version:
<pre>
git clone https://github.com/jech/babeld
cd babeld
git checkout babeld-1.10
# nötig für nach 1.10
git submodule init
git submodule update
 
make clean
make
sudo make install
</pre>
 
Dafür sind in Debian die Pakete '''git''' und '''build-essential''' nötig.


=== Änderungen ab Babel 1.8.0 ===
=== Änderungen ab Babel 1.8.0 ===
* Die Option 'wired true' gibt es nicht mehr, dafür gibt es jetzt Interface-Typen. Am sinnvollsten für GRE-Tunnel ist wohl 'type tunnel'
* Die Option 'wired true' gibt es nicht mehr, dafür gibt es jetzt Interface-Typen. Am sinnvollsten für GRE oder wireguard Tunnel ist wohl 'type tunnel'
* Die neueste Version von BabelWeb (0.4.0) ist nicht mit Babel 1.8.0 kompatibel. Daher muss BabelWeb aus dem [https://github.com/kerneis/babelweb develop Branch] installiert werden.
* Die neueste Version von BabelWeb (0.4.0) ist nicht mit Babel 1.8.0 kompatibel. Daher muss BabelWeb aus dem [https://github.com/kerneis/babelweb develop Branch] installiert werden oder man nutzt Simple-Babelweb (Eigenentwicklung aus der Community in PHP geschrieben).
 
=== systemd service für babeld ===
Bei Debian Stretch wird babeld noch mit einem SysVinit Skript ausgeliefert.
Es kann sinnvoll sein, dieses durch einen passenden systemd Service auszutauschen.
Wird babeld ausschließlich aus den Quellen installiert (siehe oben), ist kein init-Skript installiert, in diesem Fall '''muss''' dieser systemd Service verwendet werden.
 
Die Service Datei wird unter <code>/etc/systemd/system/babeld.service</code> abgelegt.
<pre>
[Unit]
Description=babeld Routing Daemon
After=network.target
 
[Service]
Type=simple
EnvironmentFile=/etc/default/babeld
ExecStart=/usr/local/bin/babeld $DAEMON_ARGS $INTERFACES
Restart=on-abort
 
[Install]
WantedBy=multi-user.target
</pre>
 
 
Ggf. muss die Datei <code>/etc/default/babeld</code> manuell angelegt werden:
<pre>
# Defaults for babeld initscript
# sourced by /etc/init.d/babeld
 
# List of interfaces on which the protocol should operate
INTERFACES=""
 
# Additional arguments
DAEMON_ARGS="-S /var/lib/babeld/state"
</pre>


== Beispielkonfiguration ==
== Beispielkonfiguration ==
Zeile 40: Zeile 87:


# Überschneidung der Tabellen für Source-Specific IPv4 Routing und der fff-Tabelle verhindern
# Überschneidung der Tabellen für Source-Specific IPv4 Routing und der fff-Tabelle verhindern
first-table-number 100
first-table-number 100 # Achtung! Ab babeld-1.10 muss diese Zeile entfernt werden, sonst startet babeld nicht mehr!


#Defaultwerte für die Schnittstellen setzen:
# Defaultwerte für die Schnittstellen setzen:
default type tunnel max-rtt-penalty 128
default type tunnel max-rtt-penalty 128


#Falls einzelne Schnittstellen abweichend konfiguriert werden müssen:
#Interface definieren auf denen Babeld läuft
#interface IF2 type wired rxcost 1234
#interface <GRE/WG Interfacename>
#... einfach weiterführen für mehr Interfaces.


#Schnittstellenspezifische Optionen setzen:
#interface <IFNAME> type wired rxcost 4096


export-table 10
export-table 10
Zeile 54: Zeile 102:


# redistribute rules
# redistribute rules
## Filter für lokalen Routen, die im Babel announced werden.
## Filter für lokalen Routen (siehe ip route show tab local), die im Babel announced werden.
redistribute local ip 10.50.0.0/16
redistribute local ip 10.50.0.0/16
redistribute local ip 10.83.0.0/16
redistribute local ip 10.83.0.0/16
redistribute local ip fd43:5602:29bd::/48
redistribute local ip fd43:5602:29bd::/48
redistribute local deny
redistribute local deny
## Filter für Routen aus fff, die announced werden sollen.
redistribute ip 10.50.0.0/16
redistribute ip 10.50.0.0/16
redistribute ip 10.83.0.0/16
redistribute ip 10.83.0.0/16
Zeile 64: Zeile 113:


local-port 33123
local-port 33123
#local-port-readwrite 34567 #funktioniert anscheinend nicht!
</pre>
</pre>


Man kann alle Peering-Interfaces mit default abfangen (wie oben geschehen) oder für jedes Peering-Interface eine eigene Zeile verwenden.
Jedes Interface, auf dem babeld laufen soll, bekommt einen eigenen
<code>interface <IFNAME> [optionen]</code> Block.


Die Interfaces, die babel verwenden soll müssen auch in der /etc/default/babeld eingetragen werden - durch Leerschläge getrennt:
Routen die man manuell in die fff Table einträgt und redistributen (announcen) möchte, müssen mit proto static eingetragen werden. Dies gilt z.B. für die Routen in das Netz einer Hood oder auch für die default Route, so man diese announcen möchte. Beispiel:


/etc/default/babeld
<pre>
<pre>
...
...
# List of interfaces on which the protocol should operate
up ip route replace 10.x.x.x/yy dev $IFACE proto static table fff
INTERFACES=""
down ip route del 10.x.x.x/yy dev $IFACE proto static table fff
...
...
</pre>
</pre>


Routen die man manuell in die fff Table einträgt und redistributen (weiterverteilen) will, müssen als proto static eingetragen haben. Dies gilt z.b. für die Batman Routen oder auch für die default route (z.b. im VPN Up Script wenn man dies verwendet). Beispiel:
Abschließend muss der babeld-Dienst aktiviert und gestartet werden.
 
<pre>
<pre>
...
systemctl enable babeld
post-up ip route replace 10.X.X.X/XX dev $IFACE proto static table fff
systemctl start babeld
...
</pre>
</pre>


== IP Adressen für Peering ==
== IP Adressen für Peering ==
=== IPv4 ===
=== IPv4 ===
Es sollte für jeden Server die selbe Adresse verwendet werden auf jedem Interface. Sinnvollerweise aus dem 10.83.252.X Netz:
Es sollte für jedes Interface die selbe Adresse verwendet werden, um IP Adressen zu sparen.
Die Adressen sollten in folgendem Netz liegen und reserviert werden:
https://wiki.freifunk-franken.de/w/Portal:Netz#10.83.252.0.2F22_.28Master_IPs.29
https://wiki.freifunk-franken.de/w/Portal:Netz#10.83.252.0.2F22_.28Master_IPs.29


Dabei ist es am sinnvollsten, die Adresse als /32 an das Interface zu hängen und Babel die Routen übernehmen zu lassen.
Dabei ist es am sinnvollsten die Adresse als /32 an das Interface zu hängen und Babel die Routen übernehmen zu lassen.
Hierbei ist es dann auch egal, aus welchem der beiden Prefixe die Adresse stammt (10.83.x.y bzw. 10.50.x.y).
Hierbei ist es dann auch egal, aus welchem der beiden Prefixe die Adresse stammt (10.83.x.y bzw. 10.50.x.y).
Außerdem ist es bei dieser Konfiguration ebenfalls nicht nötig, die Adresse des Partners als Pointopoint anzuhängen.
Außerdem ist es bei dieser Konfiguration ebenfalls nicht nötig, die Adresse des Partners als Pointopoint anzuhängen.
Zeile 104: Zeile 151:
Damit ein Router sinnvoll auf ICMPv6 antworten kann, ist außerdem eine Adresse aus dem fc00::/7 oder eine öffentliche IPv6 nötig. Dafür kann beispielsweise eine IP aus [[Portal:Netz/IPv6#Transfer-IPs|diesem]] Netz verwendet werden.
Damit ein Router sinnvoll auf ICMPv6 antworten kann, ist außerdem eine Adresse aus dem fc00::/7 oder eine öffentliche IPv6 nötig. Dafür kann beispielsweise eine IP aus [[Portal:Netz/IPv6#Transfer-IPs|diesem]] Netz verwendet werden.


Sollte das Netz nicht alleine für diese Verbindung existieren, bietet es sich auch hier an, die Adresse einfach als /128 an das Interface zu hängen.
Diese Adresse kann dann einfach an das Loopback Interface (oder ein anderes passendes Interface) gehängt werden.
Für die Peeringinterfaces genügt die Link Local Adresse.


== macvtap ==


== GRE ==
Ist das Interface in einer VM, die macvtap auf dem Host verwendet, um ein physikalisches Interface zu verwenden, kann es Probleme mit Multicast geben.
(gilt nicht bei GRE (das verwendet ja auch kein macvtap :P) in einer VM sondern nur wenn das physikalische Interface verwendet wird, also eth0 oder eth1.6 oder... in den meisten Standardfällen daher uninteressant).


Da GRE ein sehr schnelles Tunnelprotokoll ist und wenig Overhead erzeugt macht es Sinn Gateways (sofern beide Seiten eine feste IP haben und nicht hinter NAT stecken) per GRE Tunnel zu verbinden und darüber Babel laufen zu lassen. Alternativ kann z.b. wireguard verwendet werden wenn eine Seite hinter einem NAT steckt und/oder keine feste IP hat (bei dezentralen Gateways oft der Fall).
Näheres [https://superuser.com/questions/944678/how-to-configure-macvtap-to-let-it-pass-multicast-packet-correctly hier]
Theoretisch kann man natürlich auch OpenVPN oder fastd oder einen ganz anderen Layer 3 Tunnel verwenden, ob dies Sinn macht muss jeder für sich entscheiden.


=== Interface anlegen ===
In libvirt kann die Option trustGuestRxFilters='yes' an das entsprechende Interface gepackt werden, damit Multicast funktioniert:
Da Babel über IPv6-Multicasts kommuniziert, müssen den GRE-Tunnel noch link-local Adressen gegeben werden, da GRE-Tunnel auf Layer3 arbeiten und somit keine MAC-Adresse haben -> link-local kann nicht aus MAC automatisch generiert werden.
Am besten generiert man sich die link-local zufällig.


Siehe: http://wiki.hwmn.org/w/GRE_Tunnel#Babel_support
<pre>
    <interface type='direct' trustGuestRxFilters='yes'>
      <source dev='enp1s0' mode='vepa'/>
      <model type='virtio'/>
      [..]
    </interface>
</pre>


== local-port ==
Mithilfe der Option "local-port" kann babeld einen lokalen TCP Socket öffnen, über den von babeld Statusinformationen abgefragt werden können.
Dieser Socket ist dann unter ::1 (IPv6 Localhost) erreichbar.


Die Schnittstellenkonfiguration sollte dann etwa so aussehen:
Mithilfe von netcat kann eine TCP Verbindung aufgebaut werden.
Vorsicht: netcat muss IPv6 unterstützen, um sich mit ::1 verbinden zu können. netcat-traditional kann das nicht. Daher muss ggf. netcat-openbsd installiert werden.


<pre>
<pre>
auto DEVICENAME
$ nc ::1 33123
iface DEVICENAME inet static
BABEL 1.0
  address 10.83.252.x/32
version babeld-1.9.1
 
host aquarius.sgstbr.de
  #IPv4 GRE
my-id 50:7e:d5:d3:7b:46:59:7a
  #pre-up ip -4 tunnel add $IFACE mode gre local EIGENEPUBLICIP remote REMOTEPUBLICIP ttl 255
ok
  #IPv6 GRE
  pre-up ip -6 tunnel add $IFACE mode ip6gre local EIGENEPUBLICIP remote REMOTEPUBLICIP ttl 255
 
  up ip link set dev $IFACE multicast on
 
  post-up ip rule add iif $IFACE table fff
  post-down ip rule del iif $IFACE table fff
 
  post-down ip tunnel del $IFACE
 
iface DEVICENAME inet6 static
  address fe80::IRGENDWAS/64
 
  post-up ip -6 rule add iif $IFACE table fff
  post-down ip -6 rule del iif $IFACE table fff
</pre>
</pre>


Aus der alten Anleitung, bitte überarbeiten:
Schickt man ein "dump" an den Server, antwortet der Server mit allem, was er so weiß.
=== GRE-Tunnel zu anderen Gateways ===
Um die einzelnen Hoods miteinander zu verbinden, werden die jeweiligen Gateways über GRE-Tunnel miteinander verbunden. Es reicht dabei nicht, den GRE Tunnel nur auf einem Gateway einzurichten, vielmehr müssen beide zu verbindende Gateways konfiguriert werden. Hierfür muss man mit dem Admin des jeweiligen Tunnelpartners in Kontakt treten => [[Server]].
 
Der GRE-Tunnel wird in /etc/network/interfaces...
<code>
vi /etc/network/interfaces
</code>
 
...mit folgenden noch auf das Gateway anzupassenden Einträgen deklariert:
<pre>
<pre>
auto <tunnel>
$ nc ::1 33123
iface <tunnel> inet static
BABEL 1.0
address <Eigene IPv4 (Freifunk Netz)>
version babeld-1.9.1
pre-up ip -4 tunnel add $IFACE mode gre local <Eigene IPv4 (Internet)> remote <IPv4 des Tunnelpartners (Internet)> ttl 255
host aquarius.sgstbr.de
#pre-up ip -6 tunnel add $IFACE mode ip6gre local <Eigene IPv6 (Internet)> remote <IPv6 des Tunnelpartners (Internet)> ttl 255
my-id 50:7e:d5:d3:7b:46:59:7a
 
ok
up ifconfig $IFACE multicast
dump
pointopoint <IPv4 des Tunnelpartners (Freifunk Netz)>
add interface ens7 up true ipv6 fe80::5054:ff:fe81:f31b
post-up iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o $IFACE -j TCPMSS --clamp-mss-to-pmtu
add interface gre_nue2gw1 up true ipv6 fe80::a04b:9c94:2ab9:555e ipv4 10.83.252.31
post-up ip rule add iif $IFACE table fff
[..]
post-up ip -6 rule add iif $IFACE table fff
post-up ip rule add from 10.50.0.0/16 table fff
post-up ip rule add to 10.50.0.0/16 table fff
post-down ip rule del iif $IFACE table fff
post-down ip -6 rule del iif $IFACE table fff
post-down ip rule del from 10.50.0.0/16 table fff
post-down ip rule del to 10.50.0.0/16 table fff
post-down iptables -t mangle -D POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o $IFACE -j TCPMSS --clamp-mss-to-pmtu
post-down ip tunnel del $IFACE
</pre>
</pre>


Der Tunnelname, die Internetadresse beider Tunnelpartner und die Freifunkadresse beider Tunnelpartner  müssen hierbei eingefügt werden. Für GRE-Tunnel wurde der Adressbereich 10.50.252.0/22 in [[Portal:Netz]] reserviert, in denen beiden Tunnelpartnern eine dezidierte IPv4 zugewiesen wird. Das Vorgehen wurde gewählt, um auch Hood-übergreifend Tunnel erstellen zu können. Hier verwendete IP-Adressen '''müssen''' in die Tabelle eingetragen werden und so als belegt gekennzeichnet werden.
* '''interface''' beschreibt Interfaces, für die babeld konfiguriert ist
* '''neighbour''' beschreibt Nachbarn, die babeld auf einem Interface sieht
* '''xroute''' beschreibt Routen, die babeld selbst announced
* '''route''' beschreibt Routen, die babeld von einem Nachbar sieht


'''Beispiel:'''
Mehr zum local-port kann in der man-Page nachgelesen werden.
Um als fff-nue1 einen Tunnel zu ro1 aufzubauen, können die IP-Adressen wie folgt gewählt werden:
<pre>
<tunnel>                                  ro1
<Eigene IPv4 (Freifunk Netz)>            fff-nue1      10.50.252.1
<IPv4 des Tunnelpartners (Freifunk Netz)> ro1          10.50.252.0
<Eigene IPv4 (Internet)>                  fff-nue1      31.172.33.99
<IPv4 des Tunnelpartners (Internet)>      ro1          176.126.221.7
</pre>


In der Partnerkonfiguration für ro1 werden die Rollen entsprechend vertauscht:
Selbstverständlich kann man auch die Ausgabe von netcat in ein anderes Programm wie "grep" pipen.
Die Eingabe von "dump" (auf stdin) funktioniert wie gewohnt.
<pre>
<pre>
<tunnel>                                  fff-nue1
$ nc ::1 33123 | grep xroute
<Eigene IPv4 (Freifunk Netz)>            ro1          10.50.252.0
dump
<IPv4 des Tunnelpartners (Freifunk Netz)> fff-nue1      10.50.252.1
add xroute 10.83.252.0/32-::/0 prefix 10.83.252.0/32 from ::/0 metric 0
<Eigene IPv4 (Internet)>                  ro1          176.126.221.7
add xroute fd43:5602:29bd:ffff::42/128-::/0 prefix fd43:5602:29bd:ffff::42/128 from ::/0 metric 0
<IPv4 des Tunnelpartners (Internet)>      fff-nue1      31.172.33.99       
</pre>
</pre>


Der Tunnel kann über den Aufruf von
== Testen der Konfiguration ==
<code>
Es kann in der Routingtabelle geguckt werden ob hier bereits Routen vorhanden sind:
ifup <tunnel>
</code>
...aufgebaut werden, wobei <tunnel> der Name des GRE-Interfaces ist (im Beispiel ro1)


Nach Aufruf von ifconfig..
<code>
ifconfig
</code>
sollten wir einen Eintrag für den Tunnel (in diesem Beispiel ro1) vorfinden:
<pre>
<pre>
.
ip route show tab fff
.
ip -6 route show tab fff
.
ro1      Link encap:UNSPEC  HWaddr B0-7B-1C-73-30-30-3A-35-00-00-00-00-00-00-00-00 
          inet addr:10.50.252.1  P-t-P:10.50.252.0  Mask:255.255.255.255
          inet6 addr: fe80::200:5efe:b07b:1c73/64 Scope:Link
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1476  Metric:1
          RX packets:160913 errors:0 dropped:0 overruns:0 frame:0
          TX packets:146654 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:66984353 (63.8 MiB)  TX bytes:10675001 (10.1 MiB)
.
.
.
</pre>
</pre>
<br>


== Wireguard ==


Alternativ zum oben beschriebenen GRE Protokoll kann ein Babel Tunnel auch mit dem Wireguard Protokoll aufgebaut werden. Insbesondere ist dies erforderlich, wenn eine Seite hinter einem NAT steckt und/oder keine feste IP hat (bei dezentralen Gateways oft der Fall).
Wie oben beschrieben kann mithilfe des local-port der aktuelle Status von babeld abgefragt werden.
Dabei sollte vor allem geschaut werden, ob
* alle Interfaces, auf denen babeld Routen austauschen soll gelistet sind
* alle Nachbarn gelistet sind und deren rx/txcost und "reach" normal sind
* alle Routen gelistet sind, die selbst announced werden sollen
* Routen von Nachbarn sichbar sind.


=== Installation ===
== Richtlinien für Babel Penalty (rxcost) ==
* Tunnel zwischen Routern in Rechenzentren: 96
* Ethernet: 96
* Richtfunk
** >100Mbit: 256
** 30-100Mbit: 512
** 10-30Mbit: 1024
** bis 10Mbit: 4096
* Tunnel: 4096 - 16384


Wireguard ist eine recht junge Software und deshalb noch nicht in Debian 9 enthalten. In die Apt Paketverwaltung muss der "unstable" Zweig eingebunden werden. Dies erfolgt nachrangig, damit bei "apt-get upgrade" keine Pakete aus dem unstable Zweig installiert werden, die schon im Hauptzweig existieren.
Je nach Situation können Links auch schlechter hier angegeben bewertet werden. Auf eine Aufwertung sollte jedoch verzichtet werden.
Pro Link sollte maximal 16384 verwendet werden, damit auch bei vielen Hops das Maximum von 65535 nicht erreicht wird.


<code>
echo "deb <nowiki>http://deb.debian.org/debian/</nowiki> unstable main" > /etc/apt/sources.list.d/unstable.list<br>
printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable<br>
apt-get update<br>
apt-get install wireguard linux-headers-amd64
</code>


=== Interface anlegen ===
'''Begründung:'''


Die Schnittstellenkonfiguration sollte weitgehend genauso aussehen, wie bei GRE beschrieben. Auch die beiden fürs Gateway reservierten IP-Adressen (IPv4 und IPv6) sowie die willkürlich gewählte Link-Local-Adresse (fe80::...) können für GRE und Wireguard gemeinsam verwendet werden.
Wir wollen Richtfunkverbindungen (z.B. Marterlach -> St. Markus -> Hardhöhe -> Neunhof) gegenüber VPN (z.B. Marterlach -> per VPN zu einem HetznerGW -> per VPN nach Neunhof) bevorzugen, obwohl der Weg mehr Hops hat.


<code>
== Metriken anpassen ==
vi /etc/network/interfaces
=== Default Route auf einen Server bevorzugen ===
</code>
Die Kosten für eine Route können nicht per Filter verringert werden, sonst wäre das System nicht mehr Loopfrei.
Es können aber stattdessen alle anderen Routen entsprechend teurer gemacht werden.


auto DEVICENAME
Dies erreicht man durch einen Filter in der Babel Config.
iface DEVICENAME inet static
  address 10.83.252.x/32
  <s>#IPv4 GRE</s>
  <s>#pre-up ip -4 tunnel add $IFACE mode gre local EIGENEPUBLICIP remote REMOTEPUBLICIP ttl 255</s>
  <s>#IPv6 GRE</s>
  <s>pre-up ip -6 tunnel add $IFACE mode ip6gre local EIGENEPUBLICIP remote REMOTEPUBLICIP ttl 255</s>
  pre-up ip link add $IFACE type wireguard
  pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf
  ...
  <s>post-down ip tunnel del $IFACE</s>
  post-down ip link del $IFACE
  ...


Hierbei wird angenommen, dass die Wireguard-Konfigurationsdateien unter den Dateinamen <DEVICENAME>.conf abgespeichert werden:
Es wird ein Inputfilter benötigt, der auf ip 0.0.0.0/0 eq 0 greift. Das bedeutet, dass der Filter für alle Routen gilt, die innerhalb von 0.0.0.0/0 liegen (also _alle_ Routen) und die Prefixlänge 0 haben.


<code>
Dann muss das zu bevorzugende Interface ohne zusätzliche Penalty (== Kostenerhöhung) hinzugefügt werden.
vi /etc/wireguard/<DEVICENAME>.conf
</code>


# /etc/wireguard/wg-test.conf
Die Regeln werden analog zu iptables von oben nach unten abgearbeitet, beim ersten Match die passende Aktion ausgeführt.
[Interface]
PrivateKey = UBnpiQhEz2S192d8nmFmr2rm3UU+NKpKiBy28fyVa3s=
ListenPort = 51820
[Peer]
PublicKey = ZAleBcuJ4O9m2hfmz5bnqM0POCAIHQSsnWVBzreJaWw=
AllowedIPs = 0.0.0.0/0, ::/0


Dabei ist "PrivateKey" der eigene private Schlüssel, "PublicKey" der öffentliche Schlüssel der Gegenstelle. "ListenPort" ist der Port, auf dem die Pakete der Gegenstelle empfangen werden. "AllowedIPs" sind alle IPs IPv4 und IPv6.
<pre>
 
in ip 0.0.0.0/0 eq 0 if IFNAME1 allow
Die Schlüssel können mit folgender Aufrufkette in zwei Dateien "wg-private.key" und "wg-public.key" im aktuellen Verzeichnis erzeugt werden. Diese Schlüssel sollten außerhalb des Servers gesichert werden! Danach können die beiden Dateien gelöscht werden.
in ip 0.0.0.0/0 eq 0 if IFNAME2 metric 384
in ip 0.0.0.0/0 eq 0 metric 2048
</pre>


Weitere Details finden sich in der Babeld Man-Page:
<code>
<code>
wg genkey | tee wg-private.key | wg pubkey > wg-public.key
man babeld
</code>
</code>


Weil in der Konfigurationsdatei der geheime private Schlüssel im Klartext steht, empfiehlt es sich anderen Nutzern außer "root" das Lesen zu verbieten.
=== Route die man announced abwerten ===
 
Es ist auch möglich, routen die man extern announced abzuwerten um darüber weniger wahrscheinlich ausgewählt zu werden.


<code>
<pre>
chmod go-r /etc/wireguard/<DEVICENAME>.conf
out ip 10.83.x.x/22 eq 22 metric 512
</code>
</pre>
Bedeutung: Routen die innerhalb 10.83.x.x/22 liegen und exakt Prefixlänge 22 haben, die an Nachbarn weitergegeben werden sollen ('''out'''), bekommen 512 Kosten zusätzlich und werden dann weitergegeben.


Abschließend müssen auch Wireguard Interfaces genauso wie GRE Interfaces in die Datei "/etc/default/babeld" eingefügt werden.
== Filter Regeln ==


=== Tests ===
=== Public IPv6 ===
Auch öffentliche IPv6 Adressen, die innerhalb des Freifunks verwendet werden, müssen im Babel Netz announced werden. Dazu müssen sie im Filter freigeschaltet werden. Dies kann z.b. mit folgenden Abschnitt in der /etc/babeld.conf gemacht werden:


Nach Aufruf von "ifconfig" sollten wir einen Eintrag für den Tunnel (in diesem Beispiel wg-test) vorfinden.
<pre>
[...]
redistribute local ip 2001:db8:aaaa::/56
..
redistribute ip 2001:db8:aaaa::/56
[...]
</pre>


Der Aufruf "wg show" gibt etwas aus, mindestens den Namen der konfigurierten Interfaces, deren Ports und Keys. Falls auch die Gegenstelle schon erreichbar ist, werden weitere Informationen angezeigt. Beispiel:
Es handelt sich hier nur um Filterregeln. Alles was innerhalb das hier eingetragenen Subnetzes als "proto static" in die Routingtabelle eintragen wird, wird Babel an seine Nachbarn announcen.


interface: wg-test
=== Nur default routen lernen ===
  public key: PecwpxwnSKPs4Gp39gvQzxdbZxQBCupB5Oo9OVM/5ko=
  private key: (hidden)
  listening port: 51820
peer: ZAleBcuJ4O9m2hfmz5bnqM0POCAIHQSsnWVBzreJaWw=
  endpoint: 193.202.123.89:51820
  allowed ips: 0.0.0.0/0, ::/0
  latest handshake: 37 seconds ago
  transfer: 125.24 MiB received, 140.72 MiB sent


Ob das Wireguard Modul geladen ist, kann mit dem Aufruf "lsmod | grep wireguard"  ermittelt werden. Beispiel:
In manchen Fällen (z.b. reine HotSpot Netze ohne weiteres peering oder Netzinseln die man komplett selbst betreibt) macht es u.U. Sinn nur default routen zu lernen. Damit bleibt die Routingtabelle klein und babeld läuft hoffentlich stabiler (noch im Test, Erfahrung folgt). Beachtet das routen immer more specific ausgewählt werden, sobald über ein anderes Interface eine Freifunk-Fulltable rein kommt, wird diese immer bevorzugt behandelt.


wireguard            221184  0
Der Syntax der Filter sieht so aus:
ip6_udp_tunnel        16384  1 wireguard
udp_tunnel            16384  1 wireguard


== macvtap ==
babeld.conf
<pre>
in ip 0.0.0.0/0 eq 0  allow
in ip ::/0 eq 0  allow
in if wg_wg0  deny
in if wg_wg1  deny
</pre>


Ist das Interface in einer VM, die macvtap auf dem Host verwendet, um ein physikalisches Interface zu verwenden, kann es Probleme mit Multicast geben.
uci Syntax für [[OpenWrt]]:
(gilt nicht bei GRE (das verwendet ja auch kein macvtap :P) in einer VM sondern nur wenn das physikalische Interface verwendet wird, also eth0 oder eth1.6 oder... in den meisten Standardfällen daher uninteressant).
<pre>
config filter
option type 'in'
option ip '0.0.0.0/0'
option eq '0'
option action 'allow'


Näheres [https://superuser.com/questions/944678/how-to-configure-macvtap-to-let-it-pass-multicast-packet-correctly hier]
config filter
option type 'in'
option ip '::/0'
option eq '0'
option action 'allow'


In libvirt kann die Option trustGuestRxFilters='yes' an das entsprechende Interface gepackt werden, damit Multicast funktioniert:
config filter
option type 'in'
option if 'wg_wg0'
option action 'deny'


<pre>
config filter
    <interface type='direct' trustGuestRxFilters='yes'>
option type 'in'
      <source dev='enp1s0' mode='vepa'/>
option if 'wg_wg1'
      <model type='virtio'/>
option action 'deny'
      [..]
    </interface>
</pre>
</pre>


== Testen der Konfiguration ==
Zuerst werden die default routen sowohl für IPv4 und IPv6 erlaubt, danach wird alles andere auf den Peeringinterfaces zur Außengrenze dieser Insel verboten.
Es kann in der Routingtabelle geguckt werden ob hier bereits routen vorhanden sind:


=== Mit bestimmer IP antworten - src in der Route ===
Möchte man erreichen das der Router mit einer bestimmten IP antwortet kann man an der Route ein src von babeld dran hängen lassen, eine route kann dann z.b. so aussehen:
<pre>
<pre>
ip ro sh tab fff
2001:db8::/64 via fe80::c11:12:15:d dev gre_test proto babel src 2001:db8:1::1 metric 1024 onlink pref medium
ip -6 ro sh tab fff
</pre>
</pre>
Sollte nun von 2001:db8::/64 ein Traceroute über diesen Router gehen, der mit IP Rules in die Tabelle zu dieser Route guckt, wird er immer mit 2001:db8:1::1 antworten.


man kann sich mit nc mit Babel verbinden und sich Diagnoseausgaben anschauen:
Dazu muss ein install Filter in der babeld config verwendet werden. Um oberes zu erreichen sieht das z.b. so aus:
<pre>
<pre>
nc ::1 33123
install ip ::/0 ge 0 pref-src 2001:db8:1::1
</pre>
</pre>
um mehr zu sehen, einfach dump eingeben und Enter drücken.


Per Script kann man das ganze z.b. so aufrufen:
UCI Syntax:
<pre>
<pre>
echo "dump" | nc ::1 33123 -q 0
config filter                   
        option type 'install'
        option ip '::/0' 
        option ge '0'   
        option action 'pref-src 2001:db8:1::1'
</pre>
</pre>
durch -q 0 wird nc direkt wieder beendet


Damit nc mit ipv6 funktioniert muss nc von den bsd Tools installiert werden:
über ip ::/0 ge 0 kann dies natürlich auch auf bestimme Netze eingegrenzt werden wenn dies gewünscht ist, in diesem Beispiel trifft der Filter auf alle Netze zu.
 
== Nur bestimmte Routen lernen ==
 
Wichtig z.b. für gefilterte Peerings
 
<pre>
<pre>
apt-get install netcat-openbsd
in ip 192.168.0.0/24 eq 24 if wg_blub allow
in ip 192.168.3.0/24 eq 24 if wg_blub allow
in ip 2001:db8:1::/48 eq 48 if wg_blub allow
in if wg_blub deny
</pre>
</pre>


Für eine bessere Übersicht hilft auch das Webinterface weiter (siehe weiter unten)
== Logfile ==
Dies ist nur bis babel 1.9.2 nötig, ab babel 1.10 sollte dieses Problem gefixt sein und dieser Workaround kann ignoriert werden!


== Richtlinien für Babel Penalty bei dezentralen Hoods ==
Gerade wenn ein Nachbar bird2 verwendet, wird das syslog u.U. enorm schnell sehr voll. Man kann hier z.b. das logging ganz abschalten indem man in die /etc/babeld.conf folgende Zeile einfügt:
* Ethernet: 96
* Richtfunk
** >100Mbit: 256
** 30-100Mbit: 512
** 10-30Mbit: 1024
** bis 10Mbit: 4096
* VPN: 4096 - 16384


Je nach Situation können Links auch schlechter hier angegeben bewertet werden. Auf eine Aufwertung sollte jedoch verzichtet werden.
<pre>
Pro Link sollte maximal 16384 verwendet werden, damit auch bei vielen Hops das Maximum von 65535 nicht erreicht wird.
log-file /dev/null
</pre>


== WebUI für Babel ==


'''Begründung:'''
'''Die Installation eines WebUIs ist nicht für den Betrieb eines Gateways nötig, kann aber hilfreich sein'''


Wir wollen Richtfunkverbindungen (z.B. Marterlach -> St. Markus -> Hardhöhe -> Neunhof) gegenüber VPN (z.B. Marterlach -> per VPN zu einem HetznerGW -> per VPN nach Neunhof) bevorzugen, obwohl der Weg mehr Hops hat.
=== Simple-Babelweb ===


== Metriken anpassen ==
Simple-Babelweb ist eine sehr einfache PHP Seite, die den Babeld local-port auswertet und die Routen als Webseite darstellen kann.
=== Default Route auf einen Server bevorzugen ===
Das PHP Script findet man hier:
Da es nicht möglich ist, im Babel die Route zu bevorzugen (sonst wäre das System nicht mehr Loopsicher), können wir nur alle anderen default routen abwerten.
https://github.com/rohammer/Simple-Babelweb


Dies machen wir durch einen Filter in der Babel Config.
Die Installation funktioniert analog zu jeder anderen PHP-basierten Webseite.


Wir brauchen einen Inputfilter, der auf ip 0.0.0.0/0 eq 0 greift. Dazu das bevorzugte Interface ohne Penalty und alle anderen mit einem Penalty. Das ganze kann z.b. so aussehen
Simple-Babelweb ist eine Eigenentwicklung der Freifunk Franken Community. Es wird aktiv dran weiter entwickelt.


<pre>
Beispiel: http://fff-gw-geo.freifunk-geo.de/Simple-Babelweb/
in ip 0.0.0.0/0 eq 0 if IF1 allow
in ip 0.0.0.0/0 eq 0 if IF2 metric 384
in ip 0.0.0.0/0 eq 0 metric 2048
</pre>


Zuerst wird auf das IF1 kein Penalty gegeben, danach auf IF2 ein Penalty von 384 und anschließend auf alle weiteren Interfaces ein Penalty von 2048.
Es ist auch ein einfaches Looking Glass https://de.wikipedia.org/wiki/Looking_Glass_(Internet) integriert.


== WebUI für Babel ==
=== Babelweb 0.4.0 ===


=== Babelweb ===
Babelweb wird nicht mehr gepflegt und ist relativ langsam. Wenn ein WebUI für die Anzeige von Routen gewünscht ist, sollte die PHP Version von oben verwendet werden.


<div class="mw-collapsible mw-collapsed">
Für Babel gibt es ein WebUI. Quellen: https://github.com/kerneis/babelweb
Für Babel gibt es ein WebUI. Quellen: https://github.com/kerneis/babelweb


Zeile 524: Zeile 529:
</pre>
</pre>


=== Babelweb in PHP ===
</div>
 
Eine alternative ist das Babelweb in PHP
 
Einfach diese File herunterladen und in das Webroot eines Webservers packen. PHP muss installiert sein:
 
https://github.com/rohammer/Simple-Babelweb
 
Eigenentwicklung der Freifunk Franken Community und es wird aktuell auch aktiv dran weiter entwickelt.
 
Beispiel: http://fff-jupiter.fff.community/Simple-Babelweb/

Aktuelle Version vom 19. November 2022, 00:32 Uhr

Babel

Funktion

Babel wird als Layer 3 Routingprotokoll in der Freifunk Franken Backbone verwendet. So werden alle Gateways über das Protokoll direkt oder indirekt miteinander verbunden. Babel tauscht gegenseitig die Routen der Gateways aus, so das jedes Gateway weiß über welchen Weg es eine andere Hood erreichen kann. Das eigentliche Routing übernimmt der Linuxkernel. Babel ist nur für den Austausch der Informationen zuständig.

Vorsicht

ACHTUNG:

IP Adressen dürfen nur announced werden, wenn sie auch erreicht werden können. Wer das Subnetz für eine Hood announced, muss diese Hood auch erreichen können.

Installation

babeld kann aktuell meist NICHT aus der Distribution installiert werden. Die dort ausgelieferte Version ist zu alt.

babeld muss daher selbst kompilieret und installiert werden.

Empfohlen ist aktuell die Version 1.10, mindestens muss jedoch 1.9.0 installiert werden. Ein Patch wie für 1.9.0/1.9.1 ist (derzeit) nicht mehr nötig. Getestet wird aktuell 1.12.1, hier müssen submodule hinzugefügt werden (was auch immer das ist...)

Kurzanleitung fürs bauen und installieren der aktuell empfohlenen Version:

git clone https://github.com/jech/babeld
cd babeld
git checkout babeld-1.10
# nötig für nach 1.10
git submodule init
git submodule update

make clean
make
sudo make install

Dafür sind in Debian die Pakete git und build-essential nötig.

Änderungen ab Babel 1.8.0

  • Die Option 'wired true' gibt es nicht mehr, dafür gibt es jetzt Interface-Typen. Am sinnvollsten für GRE oder wireguard Tunnel ist wohl 'type tunnel'
  • Die neueste Version von BabelWeb (0.4.0) ist nicht mit Babel 1.8.0 kompatibel. Daher muss BabelWeb aus dem develop Branch installiert werden oder man nutzt Simple-Babelweb (Eigenentwicklung aus der Community in PHP geschrieben).

systemd service für babeld

Bei Debian Stretch wird babeld noch mit einem SysVinit Skript ausgeliefert. Es kann sinnvoll sein, dieses durch einen passenden systemd Service auszutauschen. Wird babeld ausschließlich aus den Quellen installiert (siehe oben), ist kein init-Skript installiert, in diesem Fall muss dieser systemd Service verwendet werden.

Die Service Datei wird unter /etc/systemd/system/babeld.service abgelegt.

[Unit]
Description=babeld Routing Daemon
After=network.target

[Service]
Type=simple
EnvironmentFile=/etc/default/babeld
ExecStart=/usr/local/bin/babeld $DAEMON_ARGS $INTERFACES
Restart=on-abort

[Install]
WantedBy=multi-user.target


Ggf. muss die Datei /etc/default/babeld manuell angelegt werden:

# Defaults for babeld initscript
# sourced by /etc/init.d/babeld

# List of interfaces on which the protocol should operate
INTERFACES=""

# Additional arguments
DAEMON_ARGS="-S /var/lib/babeld/state"

Beispielkonfiguration

Diese Beispielkonfiguration kann so übernommen werden.

/etc/babeld.conf

# For more information about this configuration file, refer to
# babeld(8)

# Überschneidung der Tabellen für Source-Specific IPv4 Routing und der fff-Tabelle verhindern
first-table-number 100 # Achtung! Ab babeld-1.10 muss diese Zeile entfernt werden, sonst startet babeld nicht mehr!

# Defaultwerte für die Schnittstellen setzen:
default type tunnel max-rtt-penalty 128

#Interface definieren auf denen Babeld läuft
#interface <GRE/WG Interfacename>

#Schnittstellenspezifische Optionen setzen:
#interface <IFNAME> type wired rxcost 4096

export-table 10
import-table 10

# redistribute rules
## Filter für lokalen Routen (siehe ip route show tab local), die im Babel announced werden.
redistribute local ip 10.50.0.0/16
redistribute local ip 10.83.0.0/16
redistribute local ip fd43:5602:29bd::/48
redistribute local deny
## Filter für Routen aus fff, die announced werden sollen.
redistribute ip 10.50.0.0/16
redistribute ip 10.83.0.0/16
redistribute ip fd43:5602:29bd::/48

local-port 33123

Jedes Interface, auf dem babeld laufen soll, bekommt einen eigenen interface <IFNAME> [optionen] Block.

Routen die man manuell in die fff Table einträgt und redistributen (announcen) möchte, müssen mit proto static eingetragen werden. Dies gilt z.B. für die Routen in das Netz einer Hood oder auch für die default Route, so man diese announcen möchte. Beispiel:

...
up ip route replace 10.x.x.x/yy dev $IFACE proto static table fff
down ip route del 10.x.x.x/yy dev $IFACE proto static table fff
...

Abschließend muss der babeld-Dienst aktiviert und gestartet werden.

systemctl enable babeld
systemctl start babeld

IP Adressen für Peering

IPv4

Es sollte für jedes Interface die selbe Adresse verwendet werden, um IP Adressen zu sparen. Die Adressen sollten in folgendem Netz liegen und reserviert werden: https://wiki.freifunk-franken.de/w/Portal:Netz#10.83.252.0.2F22_.28Master_IPs.29

Dabei ist es am sinnvollsten die Adresse als /32 an das Interface zu hängen und Babel die Routen übernehmen zu lassen. Hierbei ist es dann auch egal, aus welchem der beiden Prefixe die Adresse stammt (10.83.x.y bzw. 10.50.x.y). Außerdem ist es bei dieser Konfiguration ebenfalls nicht nötig, die Adresse des Partners als Pointopoint anzuhängen.

ACHTUNG: Es ist dann ebenfalls (erstmal) nicht möglich, den Partner direkt zu pingen, da bei dieser Konfiguration keine passende Route in der main-Tabelle existiert!

IPv6

Für IPv6 gilt in etwas das gleiche. Für das Routing ist eine Link Local Adresse nötig. Bei Ethernet und Layer2 Tunneln wird diese automatisch aus der Mac Adresse gebildet. Bei Layer3 Tunneln muss diese ggf. manuell generiert und als /64 an das Interface gehangen werden.

Damit ein Router sinnvoll auf ICMPv6 antworten kann, ist außerdem eine Adresse aus dem fc00::/7 oder eine öffentliche IPv6 nötig. Dafür kann beispielsweise eine IP aus diesem Netz verwendet werden.

Diese Adresse kann dann einfach an das Loopback Interface (oder ein anderes passendes Interface) gehängt werden. Für die Peeringinterfaces genügt die Link Local Adresse.

macvtap

Ist das Interface in einer VM, die macvtap auf dem Host verwendet, um ein physikalisches Interface zu verwenden, kann es Probleme mit Multicast geben. (gilt nicht bei GRE (das verwendet ja auch kein macvtap :P) in einer VM sondern nur wenn das physikalische Interface verwendet wird, also eth0 oder eth1.6 oder... in den meisten Standardfällen daher uninteressant).

Näheres hier

In libvirt kann die Option trustGuestRxFilters='yes' an das entsprechende Interface gepackt werden, damit Multicast funktioniert:

    <interface type='direct' trustGuestRxFilters='yes'>
      <source dev='enp1s0' mode='vepa'/>
      <model type='virtio'/>
      [..]
    </interface>

local-port

Mithilfe der Option "local-port" kann babeld einen lokalen TCP Socket öffnen, über den von babeld Statusinformationen abgefragt werden können. Dieser Socket ist dann unter ::1 (IPv6 Localhost) erreichbar.

Mithilfe von netcat kann eine TCP Verbindung aufgebaut werden. Vorsicht: netcat muss IPv6 unterstützen, um sich mit ::1 verbinden zu können. netcat-traditional kann das nicht. Daher muss ggf. netcat-openbsd installiert werden.

$ nc ::1 33123
BABEL 1.0
version babeld-1.9.1
host aquarius.sgstbr.de
my-id 50:7e:d5:d3:7b:46:59:7a
ok

Schickt man ein "dump" an den Server, antwortet der Server mit allem, was er so weiß.

$ nc ::1 33123
BABEL 1.0
version babeld-1.9.1
host aquarius.sgstbr.de
my-id 50:7e:d5:d3:7b:46:59:7a
ok
dump
add interface ens7 up true ipv6 fe80::5054:ff:fe81:f31b
add interface gre_nue2gw1 up true ipv6 fe80::a04b:9c94:2ab9:555e ipv4 10.83.252.31
[..]
  • interface beschreibt Interfaces, für die babeld konfiguriert ist
  • neighbour beschreibt Nachbarn, die babeld auf einem Interface sieht
  • xroute beschreibt Routen, die babeld selbst announced
  • route beschreibt Routen, die babeld von einem Nachbar sieht

Mehr zum local-port kann in der man-Page nachgelesen werden.

Selbstverständlich kann man auch die Ausgabe von netcat in ein anderes Programm wie "grep" pipen. Die Eingabe von "dump" (auf stdin) funktioniert wie gewohnt.

$ nc ::1 33123 | grep xroute
dump
add xroute 10.83.252.0/32-::/0 prefix 10.83.252.0/32 from ::/0 metric 0
add xroute fd43:5602:29bd:ffff::42/128-::/0 prefix fd43:5602:29bd:ffff::42/128 from ::/0 metric 0

Testen der Konfiguration

Es kann in der Routingtabelle geguckt werden ob hier bereits Routen vorhanden sind:

ip route show tab fff
ip -6 route show tab fff


Wie oben beschrieben kann mithilfe des local-port der aktuelle Status von babeld abgefragt werden. Dabei sollte vor allem geschaut werden, ob

  • alle Interfaces, auf denen babeld Routen austauschen soll gelistet sind
  • alle Nachbarn gelistet sind und deren rx/txcost und "reach" normal sind
  • alle Routen gelistet sind, die selbst announced werden sollen
  • Routen von Nachbarn sichbar sind.

Richtlinien für Babel Penalty (rxcost)

  • Tunnel zwischen Routern in Rechenzentren: 96
  • Ethernet: 96
  • Richtfunk
    • >100Mbit: 256
    • 30-100Mbit: 512
    • 10-30Mbit: 1024
    • bis 10Mbit: 4096
  • Tunnel: 4096 - 16384

Je nach Situation können Links auch schlechter hier angegeben bewertet werden. Auf eine Aufwertung sollte jedoch verzichtet werden. Pro Link sollte maximal 16384 verwendet werden, damit auch bei vielen Hops das Maximum von 65535 nicht erreicht wird.


Begründung:

Wir wollen Richtfunkverbindungen (z.B. Marterlach -> St. Markus -> Hardhöhe -> Neunhof) gegenüber VPN (z.B. Marterlach -> per VPN zu einem HetznerGW -> per VPN nach Neunhof) bevorzugen, obwohl der Weg mehr Hops hat.

Metriken anpassen

Default Route auf einen Server bevorzugen

Die Kosten für eine Route können nicht per Filter verringert werden, sonst wäre das System nicht mehr Loopfrei. Es können aber stattdessen alle anderen Routen entsprechend teurer gemacht werden.

Dies erreicht man durch einen Filter in der Babel Config.

Es wird ein Inputfilter benötigt, der auf ip 0.0.0.0/0 eq 0 greift. Das bedeutet, dass der Filter für alle Routen gilt, die innerhalb von 0.0.0.0/0 liegen (also _alle_ Routen) und die Prefixlänge 0 haben.

Dann muss das zu bevorzugende Interface ohne zusätzliche Penalty (== Kostenerhöhung) hinzugefügt werden.

Die Regeln werden analog zu iptables von oben nach unten abgearbeitet, beim ersten Match die passende Aktion ausgeführt.

in ip 0.0.0.0/0 eq 0 if IFNAME1 allow
in ip 0.0.0.0/0 eq 0 if IFNAME2 metric 384
in ip 0.0.0.0/0 eq 0 metric 2048

Weitere Details finden sich in der Babeld Man-Page: man babeld

Route die man announced abwerten

Es ist auch möglich, routen die man extern announced abzuwerten um darüber weniger wahrscheinlich ausgewählt zu werden.

out ip 10.83.x.x/22 eq 22 metric 512

Bedeutung: Routen die innerhalb 10.83.x.x/22 liegen und exakt Prefixlänge 22 haben, die an Nachbarn weitergegeben werden sollen (out), bekommen 512 Kosten zusätzlich und werden dann weitergegeben.

Filter Regeln

Public IPv6

Auch öffentliche IPv6 Adressen, die innerhalb des Freifunks verwendet werden, müssen im Babel Netz announced werden. Dazu müssen sie im Filter freigeschaltet werden. Dies kann z.b. mit folgenden Abschnitt in der /etc/babeld.conf gemacht werden:

[...]
redistribute local ip 2001:db8:aaaa::/56
..
redistribute ip 2001:db8:aaaa::/56
[...]

Es handelt sich hier nur um Filterregeln. Alles was innerhalb das hier eingetragenen Subnetzes als "proto static" in die Routingtabelle eintragen wird, wird Babel an seine Nachbarn announcen.

Nur default routen lernen

In manchen Fällen (z.b. reine HotSpot Netze ohne weiteres peering oder Netzinseln die man komplett selbst betreibt) macht es u.U. Sinn nur default routen zu lernen. Damit bleibt die Routingtabelle klein und babeld läuft hoffentlich stabiler (noch im Test, Erfahrung folgt). Beachtet das routen immer more specific ausgewählt werden, sobald über ein anderes Interface eine Freifunk-Fulltable rein kommt, wird diese immer bevorzugt behandelt.

Der Syntax der Filter sieht so aus:

babeld.conf

in ip 0.0.0.0/0 eq 0  allow
in ip ::/0 eq 0  allow
in if wg_wg0  deny
in if wg_wg1  deny

uci Syntax für OpenWrt:

config filter
	option type 'in'
	option ip '0.0.0.0/0'
	option eq '0'
	option action 'allow'

config filter
	option type 'in'
	option ip '::/0'
	option eq '0'
	option action 'allow'

config filter
	option type 'in'
	option if 'wg_wg0'
	option action 'deny'

config filter
	option type 'in'
	option if 'wg_wg1'
	option action 'deny'

Zuerst werden die default routen sowohl für IPv4 und IPv6 erlaubt, danach wird alles andere auf den Peeringinterfaces zur Außengrenze dieser Insel verboten.

Mit bestimmer IP antworten - src in der Route

Möchte man erreichen das der Router mit einer bestimmten IP antwortet kann man an der Route ein src von babeld dran hängen lassen, eine route kann dann z.b. so aussehen:

2001:db8::/64 via fe80::c11:12:15:d dev gre_test proto babel src 2001:db8:1::1 metric 1024 onlink pref medium

Sollte nun von 2001:db8::/64 ein Traceroute über diesen Router gehen, der mit IP Rules in die Tabelle zu dieser Route guckt, wird er immer mit 2001:db8:1::1 antworten.

Dazu muss ein install Filter in der babeld config verwendet werden. Um oberes zu erreichen sieht das z.b. so aus:

install ip ::/0 ge 0 pref-src 2001:db8:1::1

UCI Syntax:

config filter                    
        option type 'install' 
        option ip '::/0'   
        option ge '0'     
        option action 'pref-src 2001:db8:1::1'

über ip ::/0 ge 0 kann dies natürlich auch auf bestimme Netze eingegrenzt werden wenn dies gewünscht ist, in diesem Beispiel trifft der Filter auf alle Netze zu.

Nur bestimmte Routen lernen

Wichtig z.b. für gefilterte Peerings

in ip 192.168.0.0/24 eq 24 if wg_blub allow
in ip 192.168.3.0/24 eq 24 if wg_blub allow
in ip 2001:db8:1::/48 eq 48 if wg_blub allow
in if wg_blub deny

Logfile

Dies ist nur bis babel 1.9.2 nötig, ab babel 1.10 sollte dieses Problem gefixt sein und dieser Workaround kann ignoriert werden!

Gerade wenn ein Nachbar bird2 verwendet, wird das syslog u.U. enorm schnell sehr voll. Man kann hier z.b. das logging ganz abschalten indem man in die /etc/babeld.conf folgende Zeile einfügt:

log-file /dev/null

WebUI für Babel

Die Installation eines WebUIs ist nicht für den Betrieb eines Gateways nötig, kann aber hilfreich sein

Simple-Babelweb

Simple-Babelweb ist eine sehr einfache PHP Seite, die den Babeld local-port auswertet und die Routen als Webseite darstellen kann. Das PHP Script findet man hier: https://github.com/rohammer/Simple-Babelweb

Die Installation funktioniert analog zu jeder anderen PHP-basierten Webseite.

Simple-Babelweb ist eine Eigenentwicklung der Freifunk Franken Community. Es wird aktiv dran weiter entwickelt.

Beispiel: http://fff-gw-geo.freifunk-geo.de/Simple-Babelweb/

Es ist auch ein einfaches Looking Glass https://de.wikipedia.org/wiki/Looking_Glass_(Internet) integriert.

Babelweb 0.4.0

Babelweb wird nicht mehr gepflegt und ist relativ langsam. Wenn ein WebUI für die Anzeige von Routen gewünscht ist, sollte die PHP Version von oben verwendet werden.

Für Babel gibt es ein WebUI. Quellen: https://github.com/kerneis/babelweb

Hinweis: Laut E-Mail von Gabriel Kerneis wird babelweb nicht mehr gepflegt, stattdessen wird der Nachfolger BabelWeb2 https://github.com/Vivena/babelweb2 weiter entwickelt! (Der folgende Text bezieht sich noch auf das ursprüngliche Babelweb 0.4.0.)

Installation:

apt install nodejs-legacy npm
npm install -g babelweb


/etc/systemd/system/babelweb.service:

[Unit]
Description=babelweb

[Service]
ExecStart=/usr/local/bin/babelweb
Type=simple

[Install]
WantedBy=multi-user.target


Der Dienst wird registriert und gestartet mit

systemctl enable babelweb
systemctl start babelweb


Modifikationen (optional):

Die Dokumentation von Babelweb empfiehlt, das Programm nicht als "root" laufen zu lassen. Manche möchten die Webseiten lieber über einen anderen Port als 8080 erreichen, zum Beispiel über Port 80. Leider benötigt BabelWeb root Rechte, um auf Ports < 1024 zuzugreifen (ein Linux-Feature). Beispiel, hier für einen eingeschränkten Benutzer "normalo" und Port 7070:

[Unit]
Description=babelweb

[Service]
ExecStart=/usr/local/bin/babelweb port=7070
User=normalo
Type=simple

[Install]
WantedBy=multi-user.target

Die Webseite optisch umgestalten ist auch möglich, der Einstiegspunkt ist

vi /usr/local/lib/node_modules/babelweb/static/index.html


Nach Änderungen in der Datei "babelweb.service" muss diese neu eingelesen werden mit

systemctl daemon-reload
systemctl restart babelweb

Remote Server einbinden

Es muss ein SSH forwarding zu dem remote Gerät eingerichtet werden, gut erklärt in der Babel Doku: https://github.com/kerneis/babelweb/blob/develop/README.md unter "Monitoring remote babel instances". Danach die Datei server.js anpassen z.b.

[...]
    "routers" : "[::1]:33123,[::1]:33124,[::1]:33125",
[...]

Achtung, keine Leerzeichen vor oder nach dem Komma benutzen!

Problem mit dem neuen Node

In Debian 9 wird keine vollwertige Node Version mehr angeboten, und das Node 0.x aus Debian 8 ist voller Sicherheitslücken. Abhilfe schafft der Download einer aktuellen Version aus Git, hier Node.js 8 LTS (Support bis mindestens Dezember 2019).

apt-get install curl
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
apt-get install -y nodejs
npm install -g babelweb

Hinweis: Der Startlink ist nach dieser Installation "/usr/bin/babelweb", dies muss in /etc/systemd/system/babelweb.service gegenüber der Beschreibung im Absatz "WebUI für Babel" geändert werden.

Die letzte Babelweb Version 0.4.0 wurde bereits an die akuellen Node Versionen (>= 7) angepasst, aber eine Programmzeile vergessen. Deshalb muss eine Quellcode-Datei bearbeitet werden. Weiter entwickelt wird jetzt BabelWeb2, s.o.

vi /usr/lib/node_modules/babelweb/node_modules/policyfile/lib/server.js

Dort muss Zeile 254 geändert werden. Vorher:

Object.keys(process.EventEmitter.prototype).forEach(function proxy (key){

Nach Korrektur:

Object.keys(require('events').prototype).forEach(function proxy (key){

Quelle: https://github.com/LearnBoost/websocket.io/issues/55

Animation los werden

Ohne Animation lädt die Seite wesentlich schneller und auf schwachen Rechnern/Handys läuft die nicht gut. In

/usr/local/lib/node_modules/babelweb/static/index.html

folgende Zeilen auskommentieren:

  </head>
  <body>
      <h1>BabelWeb</h1>
<!--      
      <h2>Routers</h2>
      <div id="fig">
      <p class="legend">
      <span class="legend-title">Legend</span>
      <span class="legend-current">Current</span>
      <span class="legend-neighbour">Neighbours</span>
      <span class="legend-other">Others</span>
      </p>
      </div>
-->
    <h3>Configuration</h3>