Gateway Konfiguration

Allgemeine Software Pakete

Diese Anleitung ist auf Debian 9 ausgerichtet

sudo apt install build-essential git apt-transport-https bridge-utils ntp net-tools

Batman und Fastd

Batman Advanced ist das in Südholstein verwendete Routing Verfahren. Batman Advanced benötigt ein Kernel Modul und batclt.

Batman Kernel Modul und batctl

Als root user sudo su:

apt install linux-headers-amd64

apt install libnl-3-dev libnl-genl-3-dev libcap-dev pkg-config dkms

Wenn es bereits ein installiertes batman-adv module gibt (selbst installiert), dann vorher entfernen.

lsmod | grep batman
# wenn vorhanden dann
modprobe -rf batman_adv

Damit Batman bei einem Kernel Update nicht verschwindet oder durch die alte OS-Version ersetzt wird, richten wir das Modul mit dkms ein.

cd /usr/src
wget https://downloads.open-mesh.org/batman/releases/batman-adv-2018.4/batman-adv-2018.4.tar.gz
tar xfv batman-adv-2018.4.tar.gz
cd batman-adv-2018.4/
nano dkms.conf

Die dkms.conf befüllen:

PACKAGE_NAME=batman-adv
PACKAGE_VERSION=2018.4

DEST_MODULE_LOCATION=/extra
BUILT_MODULE_NAME=batman-adv
BUILT_MODULE_LOCATION=net/batman-adv

MAKE="'make' CONFIG_BATMAN_ADV_BATMAN_V=n"
CLEAN="'make' clean"

AUTOINSTALL="yes"

danach

dkms add -m batman-adv -v 2018.4
dkms build -m batman-adv -v 2018.4
dkms install -m batman-adv -v 2018.4
wget https://downloads.open-mesh.org/batman/releases/batman-adv-2018.4/batctl-2018.4.tar.gz
tar xvf batctl-2018.4.tar.gz
cd batctl-2018.4/
make
make install

fastd

fastd v18 ist in Debian 9 bereits in den Repositories enthalten. Unter Debian 8 findet man es in den jessie-backports.

sudo apt install fastd

fastd-Konfiguration

Wir brauchen für den neuen Server die Schlüssel für fastd. Diese sind in Südholstein für 12 Gateways bereits in der Firmware eingetragen und den privaten Schlüssel gibt es über das NOC-Team (noc@freifunk-suedholstein.de).

Im Folgenden wird der sichere private Schlüssel als [SERVER-SECRET-KEY] aufgeführt und müssen durch die erzeugten Schlüssel sinnvoll ersetzt werden!

Bitte als root zwei neue Verzeichnisse anlegen. Dort werden die Schlüssel für das Freifunknetz hinterlegt, damit Gateway und Router später zusammenfinden können:

mkdir /ffsh

Es ist eine Konfigurationsdatei für fastd notwendig. In der folgenden Konfiguration bitte die [EXTERNE-IPv4] durch die echte IP vom Server ersetzen. Wenn es auch eine IPv6 gibt, kann die entsprechende Zeile aktiviert werden und benötigt die echte IPv6 [EXTERNE-IPv6]. Die Konfigurationsdatei /etc/fastd/ffsh/fastd.conf soll bitte diese Zeilen enthalten:

# Bind to a fixed address and port, IPv4 and IPv6 at Port 1234
bind any:10000 interface "eth0";
# bind [EXTERNE-IPv6]:1234 interface "eth0";

# Set the user, fastd will work as
user "ffsh";

# Set the interface name
interface "ffsh-mesh";

# Set the mode, the interface will work as
mode tap;

# Set the mtu of the interface (salsa2012 with ipv6 will need 1406)
mtu 1426;

# Set the methods (aes128-gcm preferred, salsa2012+umac preferred for nodes)
method "null";
method "salsa2012+umac";

#hide ip addresses yes;
#hide mac addresses yes:

# Secret key generated by `fastd --generate-key`
secret "[SERVER-SECRET-KEY]";

# Log everything to syslog
log to syslog level debug;

# Include peers from our git-repos
#include peers from "peers/"; #optional eigene peers anlegen zb den eigenen toaster mit fastd oder so
include peers from "gateways/"; #git repo klonen in /etc/fastd/ffsh/ git clone  https://github.com/ffsh/gateways.git

# Configure a shell command that is run on connection attempts by unknown peers (true means, all attempts are accepted)
on verify "true";
# on verify "/etc/fastd/fastd-blacklist.sh $PEER_KEY";

# Configure a shell command that is run when fastd comes up
on up "
 ip link set dev $INTERFACE address 00:5b:27:80:0X:XX           # X für das GW Netz, zB 2:24 für 10.144.224.0/20
 ip link set dev $INTERFACE up
 ifup bat0
 sh /etc/fastd/ffsh/iptables_ffsh.sh
";

on down "
 ifdown bat0
";

Das Beste ist, wenn man nun die fastd-Konfiguration mal überprüft. Vorher muss der Server neugestartet werden, damit die vorher durchgeführten Anpassungen auch Wirkung zeigen :-)

Dann als root auf der Konsole mit folgender Zeile die fastd Einstellungen prüfen:

fastd -c /etc/fastd/ffsh/fastd.conf

Wenn das erfolgreich war, kann nun fastd gestartet werden, auch wieder als root mit:

systemctl start fastd

Wichtig: In der Konfiguration wird jeder Router reingelassen. Das mag nicht jeder, aber es vereinfacht die Integration der Router und damit auch die Verteilung. Wenn man das nicht möchte, müsste jeder Router separat mit seinem öffentlichen Schlüssel unter .../peers/ hinterlegt werden. Auskommentiert ist eine Zeile bei on verify die eine Blacklist führt. Damit kann man unliebsame Genossen aussperren. Wenn man das haben möchte, so ist eine Datei /etc/fastd/fastd-blacklist.sh zu erstellen mit folgenden Zeilen und dann auch ausführbar zu machen:

#!/bin/bash
PEER_KEY=$1
if /bin/grep -Fq $PEER_KEY /etc/fastd/fastd-blacklist.json; then
    exit 1
else
    exit 0
fi

Wie die weiteren Dateien mit der Blacklist aussehen, findet man unter diesem Link <https://github.com/ffruhr/fastdbl>

Netzwerk Konfiguration

IP Forwarding

In der Konfigurationsdatei /etc/sysctl.d/forwarding.conf bitte die folgenden Zeilen eintragen, damit das IP-Forwarding für IPv4 und IPv6 laufen:

# IPv4 Forwarding
net.ipv4.ip_forward=1

# IPv6 Forwarding
net.ipv6.conf.all.forwarding = 1

Interfaces Konfigurieren

Nun kommt das eigentlich wichtigste. Das Netzwerk muss eingerichtet werden, so das die einzelnen Schnittstelle bereitstehen und eine Art Brücke vom Freifunknetz in das Internet aufbauen.

Als erstes kommt die Netzwerkbrücke (Schnittstelle zwischen dem „Mesh“ Netzwerk und dem Internet-Ausgang per VPN:

Hinweis: diese Konfiguration ist allgemeingültig für unser Netz. Daher ist das jeweilige Gateway in den IP-Adressen mit [GW Nr] geschrieben. Diese Nummer muss natürlich durchgängig gleich sein, da sonst nichts funktionieren wird!

Bitte die /etc/network/interfaces mit Folgenden Zeilen befüllen. Das eth0 sollte so belassen werden, wie es bereits eingerichtet war, damit die Netzwerkhardware auch weiterhin im Internet erreichbar ist:

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface (here it's a local network)
allow-hotplug eth0
iface eth0 inet static
    address 192.168.1.100
    netmask 255.255.255.224
    network 192.168.1.0
    gateway 192.168.1.1
    dns-nameservers 10.144.0.1 85.214.20.141 213.73.91.35

# Netwerkbruecke fuer Freifunk
# - Hier laeuft der Traffic von den einzelnen Routern und dem externen VPN zusammen
# - Unter der hier konfigurierten IP ist der Server selber im Freifunk Netz erreichbar
# - bridge_ports none sorgt dafuer, dass die Bruecke auch ohne Interface erstellt wird

auto br-ffsh
iface br-ffsh inet static
    address 10.144.[GW Netz].1
    netmask 255.255.0.0
    bridge_ports none

iface br-ffsh inet6 static
    address fddf:0bf7:80::[GW Netz]:1
    netmask 64


    post-up /sbin/ip rule add iif br-ffsh table 42
    pre-down /sbin/ip rule del iif br-ffsh table 42

# Batman Interface
# - Erstellt das virtuelle Inteface fuer das Batman-Modul und bindet dieses an die Netzwerkbruecke
# - Die unten angelegte Routing-Tabelle wird spaeter fuer das Routing innerhalb von Freifunk (Router/VPN) verwendet
#
# Nachdem das Interface gestartet ist, wird eine IP-Regel angelegt, die besagt, dass alle Pakete, die über das bat0-Interface eingehen,
# und mit 0x1 markiert sind, über die Routing-Tabelle 42 geleitet werden.
# Dies ist wichtig, damit die Pakete aus dem Mesh wirklich über das VPN raus gehen.
#

allow-hotplug bat0
iface bat0 inet6 manual
    pre-up batctl if add ffsh-mesh
    post-up ip link set address 00:5b:27:81:0[GW Netz] dev bat0   # ACHTUNG BEI GW NETZ DEN DOPPELPUNKT NICHT VERGESSEN (80=0:80 128=1:28)
    post-up ip link set dev bat0 up
    post-up brctl addif br-ffsh bat0
    post-up batctl it 10000
    post-up batctl gw server 100mbit/100mbit

    post-up ip rule add from all fwmark 0x1 table 42

    pre-down brctl delif br-ffsh bat0 || true
    down ip link set dev bat0 down

Die /etc/hosts mit Folgenden Zeilen befüllen:

127.0.0.1                  localhost
[externe IP]               [GW Name].freifunk-suedholstein.de   [GW Name]
10.144.[GW Netz].1         ffsh
fddf:0bf7:80::[GW Netz]:1  ffsh

IP Tables

Lege die Konfigurationsdatei /etc/iptables.up.rules an mit Folgendem:

Damit werden alle Pakete, die über die Bridge rein kommen, mit dem 0x1-Flag markiert, und damit über Routing-Tabelle 42 geschickt. Es gibt noch 2 Regeln für DNS, dass auch DNS-Pakete (Port 53 TCP/UDP) über die Tabelle 42 geschickt werden.

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

Nun müssen die IP-Tables geladen werden. Bitte erstellt die Datei /etc/network/if-pre-up.d/iptables mit folgenden Zeilen:

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.up.rules

Bitte nun noch eine Datei /etc/fastd/ffsh/iptables\_ffsh.sh erstellen, die alle Routing iptables Vorgaben enthält:

#!/bin/sh
/sbin/ip route add default via [EXTERNE-IPv4] table 42
/sbin/ip route add 10.144.0.0/16 dev br-ffsh src 10.144.[GW Netz].1 table 42
/sbin/ip route add 0/1 dev tun0 table 42
/sbin/ip route add 128/1 dev tun0 table 42
/sbin/ip route del default via [EXTERNE-IPv4] table 42
/sbin/iptables -t nat -D POSTROUTING -s 0/0 -d 0/0 -j MASQUERADE > /dev/null 2>&1
/sbin/iptables -t nat -I POSTROUTING -s 0/0 -d 0/0 -j MASQUERADE
/sbin/iptables -t nat -D POSTROUTING -s 0/0 -d 0/0 -o tun0 -j MASQUERADE > /dev/null 2>&1
/sbin/iptables -t mangle -D PREROUTING -s 10.144.[GW Netz].0/20 -j MARK --set-mark 0x1 > /dev/null 2>&1
/sbin/iptables -t mangle -I PREROUTING -s 10.144.[GW Netz].0/20 -j MARK --set-mark 0x1
/sbin/iptables -t mangle -D OUTPUT -s 10.144.[GW Netz].0/20 -j MARK --set-mark 0x1 > /dev/null 2>&1
/sbin/iptables -t mangle -I OUTPUT -s 10.144.[GW Netz].0/20 -j MARK --set-mark 0x1

Jetzt müssen die für Linux ausführbar werden. Dazu dies als root auf der Konsole eingeben:

chmod +x /etc/network/if-pre-up.d/iptables
chmod +x /etc/fastd/ffsh/iptables_ffsh.sh

iptables-restore < /etc/iptables.up.rules

VPN (Mullvad)

Achtung: Kopiere bitte nicht die Konfigurationsdateien von einem Gateway auf andere Gateways!

Für das VPN werden diese Dateien benötigt, die alle nach /etc/openvpn/ müssen:

ca.crt
crl.pem
mullvad.crt
mullvad.key
mullvad_linux.conf

Die Datei mullvad\_linux.conf muss noch um folgende Zeilen am Ende ergänzt werden:

#custom
route-noexec
up /etc/openvpn/mullvad_up.sh
up /etc/fastd/ffsh/iptables_ffsh.sh

Mullvad hat an seinen Konfigurationen seit mehreren Sicherheitslücken bei OpenVPN und Snowden/NSA geändert. Es kann sein, dass ein Fehler zur Cipher-Liste angezeigt wird. Dann muss in der mullvad\_linux.conf die Zeile zur TLS-Verschlüsselung beginnend tls-cipher auskommentiert werden. Wenn kein IPv6 am Server ins Internet möglich ist, kann auch tun-ipv6 auskommentiert werden.

Die Datei /etc/openvpn/mullvad\_up.sh gibt es noch nicht.Also bitte die Datei mit folgenden Zeilen anlegen:

#!/bin/sh
ip route replace 0.0.0.0/1 via $5 table 42
ip route replace 128.0.0.0/1 via $5 table 42

service dnsmaq restart
exit 0

Diese Datei muss nun auch als root ausführbar gemacht werden:

chmod +x /etc/openvpn/mullvad\_up.sh

Damit Linux auch diese VPN-Schnittstelle kennt, muss tun in der Datei /etc/modules bekannt gemacht werden. OpenVPN benötigt ein tun-Interface. Trage einfach in eine eigene neue Zeile dies ein

tun

Bitte nun als root über die Konsole tun aktivieren und den VPN starten mit:

modprobe tun
service openvpn start

VPN-Connect regelmäßig überprüfen

Es ist sinnvoll regelmäßig zu prüfen, ob die VPN Verbindung noch aktiv ist. Dazu wird ein Script auf dem Server abgelegt, dass dann über den CRON immer neu den VPN-Connect prüft.

/ffsh/check-vpn.sh

#!/bin/bash

# Test gateway is connected to VPN
test=$(ping -q -I tun0 8.8.8.8 -c 4 -i 1 -W 5 | grep 100 )

if [ "$test" != "" ]
    then
    echo "VPN nicht da - Neustart!"
    service openvpn restart      # Fehler - VPN nicht da - Neustart
else
    echo "alles gut"
fi

Dann noch das Script ausführbar machen:

chmod ug+x /ffsh/check-vpn.sh

Danach in die Datei /etc/crontab das Skript alle 10 Minute auszuführen und damit regelmäßig der VPN-Status geprüft wird.

# Check VPN via openvpn is running, if not service restart
*/10 * * * * root /ffsh/check-vpn.sh > /dev/null

Die Änderungen übernehmen durch einen Neustart des Cron-Dämonen:

service cron restart

DHCP

apt install radvd isc-dhcp-server

DHCP radvd IPv6

Es wird für IPv6 die Konfigurationsdatei /etc/radvd.conf mit folgenden Zeilen benötigt:

interface br-ffsh {
    AdvSendAdvert on;
    IgnoreIfMissing on;
    AdvManagedFlag off;
    AdvOtherConfigFlag on;
    MaxRtrAdvInterval 200;
    AdvLinkMTU 1280;
    prefix fddf:0bf7:80::/64 {
        AdvOnLink on;
        AdvAutonomous on;
        AdvRouterAddr on;
    };

    RDNSS fddf:0bf7:80::[GW Netz]:1 {
    };
};

Jetzt kann radvd als root auf der Konsole gestartet werden:

service radvd restart

DHCP isc-dhcp-server IPv4 und IPv6

Die Konfigurationsdatei /etc/dhcp/dhcpd.conf wird für IPv4 mit folgenden Zeilen benötigt:

ddns-update-style none;
option domain-name ".ffsh";

# möglichst kurze Leasetime
default-lease-time 120;
max-lease-time 600;

log-facility local7;

subnet 10.144.0.0 netmask 255.255.0.0 {
    authoritative;
    range 10.144.[GW Netz].2 10.144.[GW Netz + 15].254;

    option routers 10.144.[GW Netz].1;

    option domain-name-servers 10.144.[GW Netz].1; # für die eigenen DNS-Einträge
    # option domain-name-servers 85.214.20.141; # weitere anonyme DNS
    # option domain-name-servers 213.73.91.35;
}

include "/etc/dhcp/static.conf";

Bitte eine leere Datei /etc/dhcp/static.conf erzeugen.

useradd -m -s /bin/bash dhcpstatic

cd /home/dhcpstatic

su dhcpstatic

git clone https://github.com/ffsh/dhcp-static.git

chmod +x dhcp-static/updateStatics.sh

exit

/home/dhcpstatic/dhcp-static/updateStatics.sh

*/5 * * * * root /home/dhcpstatic/dhcp-static/updateStatics.sh > /dev/null 2>&1

Auf dem DHCP-Server muss noch das Bridge-Interface für IPv4 festgelegt werden. Bitte die Datei /etc/default/isc-dhcp-server mit folgender Option ergänzen:

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="br-ffsh"

Am Besten wird der DHCP-Server vor dem Start und Betrieb noch mal geprüft. Bitte vorher den Server rebooten und dann auf der Konsole als root folgende Zeile ausführen:

dhcpd -f -d

War das erfolgreich, so kann der DHCP-Server als root gestartet werden:

systemctl restart isc-dhcp-server

DNS-Server (BIND)

apt install bind9

Für das interne Freifunknetz ist nun noch der DNS-Server bind9 mit den Konfigurationsdateien wie folgt zu konfigurieren:

Erstmal diese Datei /etc/bind/named.conf.options

options {
    directory "/var/cache/bind";
    // If there is a firewall between you and nameservers you want
    // to talk to, you may need to fix the firewall to allow multiple
    // ports to talk.  See http://www.kb.cert.org/vuls/id/800113
    // If your ISP provided one or more IP addresses for stable
    // nameservers, you probably want to use them as forwarders.
    // Uncomment the following block, and insert the addresses replacing
    // the all-0's placeholder.
    forwarders {
        8.8.8.8;
        8.8.4.4;
    };
    //========================================================================
    // If BIND logs error messages about the root key being expired,
    // you will need to update your keys.  See https://www.isc.org/bind-keys
    //========================================================================
    // dnssec-enable yes;
    // dnssec-validation yes;
    dnssec-validation no;
    // dnssec-lookaside auto;
    // recursion yes;
    // allow-recursion { localnets; localhost; };
    auth-nxdomain no;    # conform to RFC1035
    listen-on-v6 { any; };
};

Dann in der Datei /etc/bind/named.conf.local folgendes am Ende ergänzen:

// Do any local configuration here
// Consider adding the 1918 zones here, if they are not used in your organization

include "/etc/bind/zones.rfc1918";

zone "stormarn.freifunk.net" {
       type master;
       file "/etc/bind/db.net.freifunk.stormarn";
  };

zone "freifunk-stormarn.de" {
       type master;
       file "/etc/bind/db.de.freifunk-stormarn";
  };

zone "lauenburg.freifunk.net" {
       type master;
       file "/etc/bind/db.net.freifunk.lauenburg";
  };

zone "freifunk-lauenburg.de" {
       type master;
       file "/etc/bind/db.de.freifunk-lauenburg";
  };

zone "freifunk-suedholstein.de" {
        type master;
        file "/etc/bind/db.de.freifunk-suedholstein";
};

zone "ffshev.de" {
     type master;
     file "/etc/bind/db.de.ffshev";
};

Die zugehörigen Zone Dateien werden in einem Repository verwaltet.

Diese sollen automatisch aktualisiert werden.

Als erstes legen wir einen neuen Benutzer an.

useradd -m -s /bin/bash dnsbind

Dann wechseln wir zu diesem Nutzer.

su - dnsbind
cd /home/dnsbind/

Und Klonen das Repository

git clone https://github.com/ffsh/bind.git

Danach verlassen wir den Nutzer.

exit

Und legen einige Cron jobs an.

*/15 * * * * root /home/dnsbind/bind/updatestofrei.sh > /dev/null 2>&1
*/15 * * * * root /home/dnsbind/bind/updatelauen.sh > /dev/null 2>&1
*/15 * * * * root /home/dnsbind/bind/updateffsh.sh > /dev/null 2>&1

Zum Schluss starten wir bind neu.

systemctl restart bind9

Mesh Announce

Um als Gateway, Server oder alles was kein Freifunk Router ist auf der Karte zu erscheinen kann mesh-announce installiert werden.

Dafür müssen folgende Dinge vorhanden sein:

lsb_release, ethtool, python3 (>= 3.3)
sudo apt install ethtool python3

Mesh Announce kann auch im alfred Stil Daten broadcasten das wollen wir aber nicht.

sudo git clone https://github.com/ffnord/mesh-announce /opt/mesh-announce
sudo cp /opt/mesh-announce/respondd.service /etc/systemd/system/respondd.service
nano /etc/systemd/system/respondd.service

Den Systemd Service passen wir jetzt an unser Netzwerk und Gateway an. Erstmal das Konzept. Wir starten respondd.py mit einigen argumenten:

respondd.py -d /opt/mesh-announce/providers -i <your-clientbridge-if> -i <your-mesh-vpn-if> -b <your-batman-if> -m <mesh ipv4 address>
your-clientbridge-if - br-ffsh
your-mesh-vpn-if     - ffsh-mesh
your-batman-if       - bat0
mesh ipv4 address    - GW-IPV4

Im folgenden Beispiel ist Hopfenbach das Gateway dort sind die Interfaces so wie in der Anleitung benannt und die IP ist 10.144.128.1.

[Unit]
Description=Respondd
After=network.target

[Service]
ExecStart=/opt/mesh-announce/respondd.py -d /opt/mesh-announce/providers -i br-ffsh -i ffsh-mesh -b bat0 -m 10.144.128.1
Restart=always
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

[Install]
WantedBy=multi-user.target

Dann mit hostname prüfen ob der erwünschte Gateway-Name eingetragen ist ggf. ändern oder:

nano providers/nodeinfo/hostname.py

import providers
import socket
class Source(providers.DataSource):
    def call(self):
        return "GW_Barnitz"

Dann den Service aktivieren

systemctl daemon-reload
systemctl start respondd
# autostart on boot
systemctl enable respondd

Das System sollte in kürze auf der Karte auftauchen.