Freifunk-Gateway aufsetzen/keyxchangev2 VERALTET

Aus Freifunk Franken
Wechseln zu:Navigation, Suche

Hier landen die ersten Infos was für Gateways bei KeyxchangeV2 geändert werden muss. Es sind nur Beispieldateien und müssen pro Hood unbedingt angepasst werden! Ungetestet!

Batman

Entweder batman-adv und batctl aus Debian 9 verwenden (2016.4) oder selbst kompilieren:

Zuerst git Repositories klonen:

git clone https://git.open-mesh.org/batman-adv.git
git clone https://git.open-mesh.org/batctl.git


Jeweils die aktuellste stabile Version auschecken:

git checkout v2017.3


Jeweils kompilieren und installieren:

make
sudo make install

Dafür ist mindestens build-essential, libnl-3-dev, libnl-genl-3-dev, make, pkg-config, linux-headers nötig. Bitte ergänzen, ob noch mehr notwendig ist.

Am Ende sollte 'batctl -v' sowohl für batctl, als auch für batman-adv eine Version größer 2013.4 ausgeben. (wie in diesem Beispiel 2017.3...)

# modprobe batman-adv && batctl -v
batctl 2017.3 [batman-adv: 2017.3]


ACHTUNG: Selbst kompilierte Kernelmodule funktionieren nach einem Kernelupdate nicht mehr und müssen unbedingt neu kompiliert und eingefügt werden!

Alfred Master aufsetzen

Alfred Monitoring Proxy

Wir nutzen besser den C-Alfred von kratz00 https://github.com/kratz00/alfred-json somit können wir auch sehr leicht mehrere Hoods bedienen. Folgende Pakete werden zum Compilieren benötigt: zlib1g-dev, pkgconf, libjansson-dev und deren Dependencies.

Zuerst den Alfred-Master pro Hood starten (irgendwo in Autostart):

root@vm3-gw-cd1:/usr/sbin# cat /etc/fastd/fff.fuerth/up.sh 
#!/bin/sh
/sbin/ifup $INTERFACE
batctl gw_mode server 32mbit
alfred -m -i bat0 -u /var/run/a0.sock &

den Socket pro Hood einfach um eins hochzählen, a1.sock a2.sock usw.

Danach bauen wir Alfred-json

git clone https://github.com/kratz00/alfred-json
cd alfred-json/
mkdir build
cd build/
cmake ../
make
sudo su
make install

danach noch das Script anlegen (auf eigenes Zeug anpassen! Pfade prüfen! Socket-Pfad im up.sh des fastd für die jeweilige Hood):

root@vm3-gw-cd1:/var/log# cat /usr/sbin/alfred-c 
#!/bin/bash

api_url="https://monitoring.freifunk-franken.de/api/alfred"
fetch_ids="64"

for fetch_id in $fetch_ids
do
    tmp=$(/bin/mktemp)
    echo "{\"$fetch_id\": " > $tmp
    /usr/local/bin/alfred-json -r "$fetch_id" -s /var/run/alfredbat0.sock >> $tmp
    echo "}" >> $tmp
    if [ "$zip" = "1" ]; then
        gzip $tmp
        tmp="$tmp.gz"
        HEADER='-H "Content-Encoding: gzip" --compressed'
    fi
    /usr/bin/curl -k -v -H "Content-type: application/json; charset=UTF-8" $HEADER -X POST --data-binary @$tmp $api_url
    /bin/rm "$tmp"
done

for fetch_id in $fetch_ids
do
    tmp=$(/bin/mktemp)
    echo "{\"$fetch_id\": " > $tmp
    /usr/local/bin/alfred-json -r "$fetch_id" -s /var/run/alfredbat1.sock >> $tmp
    echo "}" >> $tmp
    if [ "$zip" = "1" ]; then
        gzip $tmp
        tmp="$tmp.gz"
        HEADER='-H "Content-Encoding: gzip" --compressed'
    fi
    /usr/bin/curl -k -v -H "Content-type: application/json; charset=UTF-8" $HEADER -X POST --data-binary @$tmp $api_url
    /bin/rm "$tmp"
done

for fetch_id in $fetch_ids
do
    tmp=$(/bin/mktemp)
    echo "{\"$fetch_id\": " > $tmp
    /usr/local/bin/alfred-json -r "$fetch_id" -s /var/run/alfredbat2.sock >> $tmp
    echo "}" >> $tmp
    if [ "$zip" = "1" ]; then
        gzip $tmp
        tmp="$tmp.gz"
        HEADER='-H "Content-Encoding: gzip" --compressed'
    fi
    /usr/bin/curl -k -v -H "Content-type: application/json; charset=UTF-8" $HEADER -X POST --data-binary @$tmp $api_url
    /bin/rm "$tmp"
done

for fetch_id in $fetch_ids
do
    tmp=$(/bin/mktemp)
    echo "{\"$fetch_id\": " > $tmp
    /usr/local/bin/alfred-json -r "$fetch_id" -s /var/run/alfredbat3.sock >> $tmp
    echo "}" >> $tmp
    if [ "$zip" = "1" ]; then
        gzip $tmp
        tmp="$tmp.gz"
        HEADER='-H "Content-Encoding: gzip" --compressed'
    fi
    /usr/bin/curl -k -v -H "Content-type: application/json; charset=UTF-8" $HEADER -X POST --data-binary @$tmp $api_url
    /bin/rm "$tmp"
done


ausführbar machen:

chmod +x /usr/sbin/alfred-c

Einen Cronjob drüber:

*/5 * * * * sleep 70; /usr/sbin/alfred-c

Der sleep-Befehl ist wichtig. Das Argument von sleep sollte irgendwo zwischen 65 und 80 Sekunden liegen. Zwei Alfred Master in der selben Hood dürfen NIE zu gleichen Zeit Daten schicken. Details zu den Zeitslot direkt im Anschluss.

fertig :)

Wahl des korrekten Delays (sleep)

Das Zusammenspiel zwischen nodewatcher, Alfred und Monitoring ist komplex. Entsprechend gibt es mehr und weniger sinnvolle Zeiten, wann der Alfred Master seine Daten an das Monitoring sendet. Die folgende Tabelle soll bei der Wahl eines geeigneten Delays behilflich sein.

Anstatt eines fixen Delays ist auch eine Variante mit random möglich. Die Grenzen sollten dabei die angegebenen Bereiche nicht verlassen!

WICHTIG: Sind mehrere Alfred Master in einer Hood sollten diese ihre Daten nie gleichzeitig schicken! (Empfohlener Abstand min. 5 sec.)


Wartezeit nach Erreichen von */5 Kommentar
0 - 50 sec. Reservierter Zeitslot (nodewatcher)
  • In dieser Zeit generiert der nodewatcher die Daten und verschickt diese per Alfred.
  • Findet die Anfrage in diesem Zeitraum statt, werden die Daten von 5 Minuten zuvor verwendet.
50 - 85 sec. Empfohlener Zeitslot
  • Optimal zwischen 65 und 80 sec.
85 - 120 sec. Reservierter Zeitslot (Netmon-VM)
  • Bei einer anderen Anfrage sollten keine Fehler auftreten, aber die Last wird unnötig erhöht
120 - 175 sec. Möglicher Zeitslot
  • Die Daten werden noch rechtzeitig für die Statistiken geliefert
  • Die Routerdaten selbst sind weniger aktuell im Vergleich zum empfohlenen Slot
175 - 185 sec. Reservierter Zeitslot (Erstellung der Statistiken)
  • Findet hier eine Anfrage statt kann es gelegentlich zu Fehlern kommen
185 - 300 sec. Freier Zeitslot
  • Die Daten werden NACH Erstellung der Statistiken geliefert und müssen entsprechend lange warten
  • Optimal ist dieser Zeitslot für den zweiten Alfred Master einer Hood, sodass der Abstand zwischen den Anfragen etwa gleich ist (=> effektives Update alle 2.5 Minuten)
  • Ein Setzen auf nahe 300 Sekunden sollte vermieden werden

Tipps:

Handelt es sich um mehr als eine Minute Delay, kann die Cron Syntax ausgenutzt werden:

1-59/5 * * * * Befehl

Das löst dann 00:01, 00:06, 00:11 usw. aus, also im beginnend bei 1 bis 59 in 5-er Schritten

2-59/5 * * * * Befehl

Das löst dann 00:02, 00:07, 00:12 usw. aus, also im beginnend bei 2 bis 59 in 5-er Schritten

In Kombination mit sleep gibt es also für 130 Sekunden folgende Lösungen:

*/5 * * * * sleep 130; Befehl

oder besser:

2-59/5 * * * * sleep 10; Befehl

Zwei Minuten plus 10 Sekunden sind 130 Sekunden, aber man vermeidet den langen Sleep.

GWinfo Skript aufsetzen

Wir erhalten im Monitoring von den Routern auch Gateway-Daten, allerdings nur die MAC-Adresse des VPN Interfaces. Um dies mit den Gateway-Namen und ggf. weiteren Informationen zu unterfüttern, kann folgendes Skript verwendet und z.B. per Cron alle 5 Minuten ausgeführt werden (hier ist kein sleep o.ä. notwendig).

#!/bin/sh
#
# Gateway data script for FFF Monitoring
# Copyright Adrian Schmutzler, 2018.
# License GPLv3
#
# v1.2.1 - 2018-01-12
# - Added "grep fff" to support L2TP
#
# v1.2 - 2018-01-12
# - Added batctl command and vpnif
#
# v1.1 - 2018-01-12
# - Initial Version
#

# Config
api_url="http://monitoring.freifunk-franken.de/api/gwinfo"
batctlpath=/usr/local/sbin/batctl # Adjust to YOUR path!
hostname="MyHost" # Namen nicht zu lang machen, kein hostname.fff.irgendwas
admin1="Admin"
admin2=
admin3=
statslink="" # Provide link to stats page (MRTG or similar)

# Code
tmp=$(/bin/mktemp)
echo "{\"hostname\":\"$hostname\",\"stats_page\":\"$statslink\",\"netifs\":[" > $tmp

comma=""
for netif in $(ls /sys/class/net); do
	if [ "$netif" = "lo" ] ; then
		continue
	fi
	mac="$(cat "/sys/class/net/$netif/address")"
	batctl="$("$batctlpath" -m "$netif" if | grep "fff" | sed -n 's/:.*//p')"
	echo "$comma{\"mac\":\"$mac\",\"netif\":\"$netif\",\"vpnif\":\"$batctl\"}" >> $tmp
	comma=","
done

echo "],\"admins\":[" >> $tmp

comma=""
[ -n "$admin1" ] && echo "\"$admin1\"" >> $tmp && comma=","
[ -n "$admin2" ] && echo "$comma\"$admin2\"" >> $tmp && comma=","
[ -n "$admin3" ] && echo "$comma\"$admin3\"" >> $tmp

echo "]}" >> $tmp


/usr/bin/curl -k -v -H "Content-type: application/json; charset=UTF-8" -X POST --data-binary @$tmp $api_url
/bin/rm "$tmp"

Sowohl die Verwendung des Skriptes als auch welche Daten zur Verfügung gestellt werden bleibt dem Nutzer überlassen.

Soll z.B. keine stats_page angezeigt werden, einfach statslink="" einstellen.

network

Für keyxchangev2 werden neue Subnetze benötigt. Jede Hood aus dem KeyxchangeV2 ist ein eigenes Subnetz aus dem 10.83/16 und muss dort auch auf der Netz Seite registriert werden. Dazu werden absofort auch IPv6 Netze verwendet, diese müssen auch hier registriert werden: https://wiki.freifunk-franken.de/w/Portal:Netz/IPv6

/etc/network/interfaces

device: bat0
iface bat0 inet manual
post-up ifconfig $IFACE up
    ##Einschalten post-up:
    # IP des Gateways am B.A.T.M.A.N interface:
    post-up ip addr add 10.83.X.1/22 dev $IFACE
    post-up ip -6 addr add fe80::1/64 dev $IFACE nodad
    post-up ip -6 addr add fe80::BLA:BLA:BLA/64 dev $IFACE #wird für radvd benötigt!!
    post-up ip -6 addr add fd43:5602:29bd:X::1/64  dev $IFACE
    # Regeln, wann die fff Routing-Tabelle benutzt werden soll: 
    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.0.0.0/8 table fff
    post-up ip rule add to 10.0.0.0/8  table fff
    # Route in die Fuerther Hood:       
    post-up ip route replace 10.83.X.0/22 dev $IFACE proto static table fff
    post-up ip -6 route replace fd43:5602:29bd:X::/64 dev $IFACE proto static table fff # PREFIX ANPASSEN!
    # Start des DHCP Servers:
    post-up invoke-rc.d isc-dhcp-server restart

    ##Ausschalten post-down:
    # Loeschen von oben definieren Routen, Regeln und Interface: 
    post-down ip route del 10.83.X.0/22 dev $IFACE table fff
    post-down ip rule del from 10.0.0.0/8 table fff
    post-down ip rule del to 10.0.0.0/8 table fff
    post-down ip rule del iif $IFACE table fff
    post-down ifconfig $IFACE down

# VPN Verbindung in die Fuerther Hood
iface ffffuerthVPN inet manual
    post-up batctl -m bat0 if add $IFACE
    post-up ifconfig $IFACE up
    post-up ifup bat0
    post-down ifdown bat0
    post-down ifconfig $IFACE down

fastd

Fastd wird komplett anders als früher konfiguriert: https://wiki.freifunk-franken.de/w/Freifunk-Gateway_aufsetzen#FastD_Start-_und_Verwaltungsscript das *.sh Script darf KEINESFALLS(!!) mehr angelegt/ausgeführt werden, auch der Cronjob ist nicht mehr nötig. Falls die IP noch im alten KeyXchange eingetragen ist, sollte sie hieraus unbedingt entfernt werden (KeyXchange Admin fragen) Bitte nur noch folgende Anleitung folgen:

root@vm3-gw-cd1:/etc/fastd/fff.fuerth# cat down.sh 
#!/bin/sh
/sbin/ifdown $INTERFACE
root@vm3-gw-cd1:/etc/fastd/fff.fuerth# cat fff.fuerth.conf 
# Log warnings and errors to stderr
log level error;
# Log everything to a log file
log to syslog as "ffffuerth" level info;
# Set the interface name
interface "ffffuerthVPN";
# Support xsalsa20 and aes128 encryption methods, prefer xsalsa20
#method "xsalsa20-poly1305";
#method "aes128-gcm";
method "null";
# Bind to a fixed port, IPv4 only
bind any:10004;
# fastd need a key but we don't use them
secret "c00a286249ef5dc5506945f8a3b413c0928850214661aab866715203b4f2e86a";
# Set the interface MTU for TAP mode with xsalsa20/aes128 over IPv4 with a base MTU of 1492 (PPPoE)
# (see MTU selection documentation)
mtu 1426;
on up "/etc/fastd/fff.fuerth/up.sh";
on post-down "/etc/fastd/fff.fuerth/down.sh";
secure handshakes no;
on verify "/etc/fastd/fff.fuerth/verify.sh";

root@vm3-gw-cd1:/etc/fastd/fff.fuerth# cat up.sh 
#!/bin/sh
/sbin/ifup $INTERFACE

root@vm3-gw-cd1:/etc/fastd/fff.fuerth# cat verify.sh 
#!/bin/sh
return 0

root@vm3-gw-cd1:/etc/fastd/fff.fuerth# 
root@vm3-gw-cd1:/home/christiand# cat /etc/systemd/system/fastd.service 
[Unit]
Description=fastd

[Service]
ExecStart=/usr/bin/fastd -c /etc/fastd/fff.fuerth/fff.fuerth.conf
Type=simple

[Install]
WantedBy=multi-user.target

danach:

systemctl enable fastd
systemctl start fastd

Der Server muss dann händisch in den keyxchangev2 eingetragen werden. Dazu sind folgende Infos nötig:

  • IP Adresse (aktuell v4)
  • Port von fastd
  • Public Key von fastd (die Router müssen den Pub-Key vom Gateway kennen sonst funktioniert es nicht, das Gateway muss KEINE Keys vom Router kennen)
  • Servername
  • Hood

Gateways untereinander verbinden

Die Gateways müssen sich im fastd auch noch untereinander verbinden, hier fehlt noch $config

am besten wird es sein, sich die json vom keyxchange zu holen und alle Gateways (auser sich selbst) in das peers Verzeichnis eintragen, dann sollte fastd sich darum kümmern. Dies regelmäßig per Cronjob tun.

babel

siehe hier

GRE TUnnel

Die GRE Tunnel brauchen auch eine ipv6 aus dem Transfernetz.

...
post-up ip -6 addr add fd43:5602:29bd:ffff::X dev XXXXX
...

ip -6 rule show sollte noch folgende Einträge bekommen:

  • from all to fc00::/7 lookup fff
  • from fc00::/7 lookup fff

radvd

radvd muss mindestens 2.16 installiert sein, prüfen mit

radvd -v

wird benötigt für AdvRASrcAddress

In Debian bis 9 ist nur 2.15 integriert.

install radvd from buster:

add /etc/apt/preferences.d/limit-buster

Package: *
Pin: release n=buster
Pin-Priority: 150

add /etc/apt/sources.list.d/buster.list

deb http://ftp.de.debian.org/debian/ buster main
  • apt-get update
  • apt-get -t buster install radvd

in der config bitte das prefix anpassen!

root@vm3-gw-cd1:/etc/fastd/fff.fuerth# cat /etc/radvd.conf 
interface bat0 { 
        AdvSendAdvert on;
        MinRtrAdvInterval 60; 
        MaxRtrAdvInterval 300;
	AdvDefaultLifetime 0;
        AdvRASrcAddress {
                fe80::b41e:49ff:XXXX:XXXX;
        };
        prefix fd43:5602:29bd:X::/64 { 
                AdvOnLink on; 
                AdvAutonomous on; 
        };
        route fc00::/7 {
        };
};

ACHTUNG: Die fe80:: die bei AdvRASrcAddress eingetragen ist muss fest an das batX Interface gebunden werden, bitte eigene fe80 generieren, sie muss pro Hood Unique sein:

    post-up ip -6 addr add fe80::b41e:49ff:XXXX:XXXX dev $IFACE

AdvRASrcAddress ist nötig damit die route spezifisch zu einem Gateway gesetzt wird (Client sucht sich Gateway aus) und nicht per fe80::1 anycast wird (Standardmäßig nutzt radvd die kleinste fe80 Adresse und das ist bei uns immer fe80::1 und diese hängt per nodad am batX). Wie sich das am Ende ausbalanciert muss mit vielen Routern und Clients getestet werden, gerade wenn eine IPv6 default Route gesetzt wird da PublicV6 verteilt wird.

/etc/init.d/radvd restart

ntp Server

Es werden routbare v6 Adressen aus den ULA Bereich verwendet. Jede Hood kann, muss aber nicht einen eigenen ntp Server bereit stellen. Aktuell sind folgende NTP Server in betrieb und können verwendet werden:

  • fd43:5602:29bd:ffff::1

http

hier wird noch ein http Server benötigt den man so konfigurieren kann, das es pro eingehendes Interface mit gleicher IP (jedes batX bekommt eine fe80::1/64 mit nodad damit auch mehrere GWs in einer Hood die IP haben können!) eine andere Hoodfile zurück gibt. Die aktuelle Hoodfile kann vom keyxchangev2 bezogen werden und muss regelmäßig (Cronjob, alle 5 Minuten) auf den Gateways aktualisiert werden

Cronjob:

*/5 * * * * wget "http://keyserver.freifunk-franken.de/v2/index.php?lat=49.4814&long=10.966" -O /var/www/html/keyxchangev2data

Koordinaten auf die Hood anpassen: http://keyserver.freifunk-franken.de/v2/hoods.php

Mittlerweile ist die Firmware angepasst und der Webserver muss auf Port 2342 lauschen! Zeile 103: https://github.com/FreifunkFranken/firmware/blob/master/src/packages/fff/fff-hoods/files/usr/sbin/configurehood

Für mehrere Hoods: Im Prinzip braucht man einen Webserver, welcher aus der jeweiligen Hood heraus unter fe80::1 erreichbar ist, damit das File keyxchangev2data abgerufen werden kann. Am einfachsten ist das zu realisieren, indem man den Webserver auf mehreren Ports lauschen lässt und aus und Pakete vom jeweiligen batX Port 2342 auf den jeweiligen Port redirected. Die gewählten Ports zwischen 2001-2003 sind beliebig gewählt, your mileage may vary.

Beispiel Apache:

/etc/apache2/ports.conf
Listen 2001
Listen 2002
Listen 2003
.
.

/etc/apache2/sites-available/bat.conf:
<VirtualHost *:2001>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/bat1
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:2002>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/bat2
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<VirtualHost *:2003>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/bat3
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
.
.

und dann noch das Redirect einbauen in /etc/fastd/fff.HOODNAME1/up.sh:
ip6tables -t nat -A PREROUTING -i bat1 -p tcp -d fe80::1 --dport 2342 -j REDIRECT --to-port 2001
Und in den up.sh der anderen Hoods:
ip6tables -t nat -A PREROUTING -i bat2 -p tcp -d fe80::1 --dport 2342 -j REDIRECT --to-port 2002
ip6tables -t nat -A PREROUTING -i bat3 -p tcp -d fe80::1 --dport 2342 -j REDIRECT --to-port 2003

mkdir /var/www/html/bat1
mkdir /var/www/html/bat2
mkdir /var/www/html/bat3
..

a2ensite bat

Cronjob:
*/5 * * * * wget "http://keyserver.freifunk-franken.de/v2/?lat=99.0023&long=77.8507" -O /var/www/html/bat1/keyxchangev2data
WICHTIG: KOORDINATEN DER HOOD ANPASSEN!
Analog müssen für die anderen bat-Verzeichnisse Cronjobs angelegt werden.


Fastd und Apache neustarten. Es sollte noch in jedem Verzeichnis, in dem ein keyxchangev2data liegt, ein File "gateway" liegen mit dem Servernamen z.b. "fff-hof-gw3" (ohne Anführungszeichen). So kann man beim Debuggen gleich sehen, welcher Server hier lauscht.