• Verein
  • Freifunk
  • namespace
  • Hey, Alter!
Gantry 5

Freifunk Gera-Greiz

  • Mitmachen
  • Firmware
  • Wiki
  • Karte
  • Netzwerk
  1. Aktuelle Seite:  
  2. Startseite
  3. Freifunk
  4. Wiki
  5. Dokumentation
  6. Gateways

Gateway-Management

Gateway-Management

Einführung

Im Folgenden wird das Management unserer Gateways beschrieben. Diese Anleitung soll es auch Freifunkern, die sich nicht täglich mit dem Management komplexer Netzwerksysteme befassen, ermöglichen, die Hauptadministratoren der Gateways bei der Behebung von Fehlern und der Durchführung kleinerer Änderungen zu unterstützen. Parallel zur Entstehung dieses Wiki-Eintrages werden im Rahmen unserer Techniktreffen in loser Folge Workshops zu den einzelnen Themengebieten durchgeführt.

Überblick

Login

 

Gateway-Funktionen

 

Statusanzeigen

 

Neustarts

 

Grundkonfiguration

Grundkonfiguration des Linux-Systems mit externer Internet-Anbindung

Freifunk-Bridge

 

B.A.T.M.A.N.

 

dnsmasq für DNS, DHCP, RA

 

Verbindung der Gateways untereinander

 

Knoten-Anbindung

Fastd

Tunneldigger

 

Tunnel nach extern

IC-VPN

FFRL-Backbone

 

BIRD (dynamisches Routing)

 

Firewall

 

Dienste

Webserver

NTP

 

 

Details
Geschrieben von: Jörg
Kategorie: Gateways
Veröffentlicht: 23. November 2021
Zuletzt aktualisiert: 18. Dezember 2018

Gateway mit Debian

Sehr sehr kurz gehaltene - unfertige - Anleitung für einen Gateway unter Debian; Details bitte aus der Gentoo-Anleitung entnehmen.

<>

Unterschiede zwischen Gentoo und Debian (!!! WICHTIG !!!)

Folgende Befehle und Verzeichnisse die in der Gentoo-Anleitung verwendet werden sollten unter Debian nicht genutzt werden.Die Befehle und Pfade für Debian sind in dieser Anleitung angegeben.Befehle (in Klammern die gegenstücke für Debian):

emerge (apt-get)
rc-update (update-rc.d)
rc-service (service)

Verzeichnisse:

/etc/config.d/ (/etc/default/)
/etc/portage/
/etc/local.d/
/etc/layman/
/etc/rc.conf

Statt

/etc/init.d/DAEMON start

wird in Debian die Dienste mit

sudo service DAEMON start

gestartet, gestoppt oder neugestartet.Zudem sollte in dieser Anleitung in /etc/init.d/ nichts verändert werden! Die manuell installierten Dienste unter /usr/local/ werden über die verschiedenen Configs, und damit in richtiger Reihenfolge, gestartet.

Der Cron sollte unter Debian weder gestoppt noch neugestartet werden. Die Configs unter /etc/cron.d/ werden automatisch aktualisiert.

Noch einmal ganz wichtig: Wenn Verzeichnisse oder Dateien unter Debian nicht existieren bitte erst hier nachschauen ob diese unter Debian notwendig sind.


Voraussetzungen

Beispiel von GW2 unter Debian Jessie (8.2) auf einen KVM-VServer. Ich gehe hier nur im groben auf die wichtigsten Unterschiede zur Gentoo-Anleitung ein da vieles identisch ist.

su -c apt-get install sudo
su -c usermod -aG staff,adm,sudo BENUTZERNAME

sudo apt-get install build-essential

Es wird davon ausgegangen dass sudo verwendet wird und so viel wie möglich unter seinem normalen Benutzeraccount erledigt wird. Software die nicht über den Paket-Manager (apt-get) installiert wird sollte unter /usr/local/ erstellt und installiert werden.

Uner Debian gibts layman nicht, stattdessen kann man zur Dokumentation der Konfigurationsdateien etckeeper verwenden.Der abgleichen mit Github fehlt hier aus Sicherheitsgründen wird aber noch nachgereicht.

Grundkonfiguration

Hostname

echo "gw2" | sudo tee /etc/hostname

/etc/hosts wie in der Gentoo-Anleitung

Routing

/etc/iproute2/rt_tables wie in der Gentoo-Anleitung

Kernelparameter

An den Kernelparameter wird nichts verändert!/etc/sysctl.conf wie in der Gentoo-Anleitung

SysFS

entfällt (wird in der /etc/network/interfaces erledigt)

Netzwerk

Externe Anbindung

Die Grundkonfiguration (meist eth0) sollte aus der Installation schon passen.Siehe Netzwerkverbindungen

Bridge

Siehe Netzwerkverbindungen

GRETAP-Tunnel

Siehe Netzwerkverbindungen

Netzwerkverbindungen

sudo apt-get install bridge-utils

In dieser Datei sind "Externe Anbindung", "Bridge", "GRETAP-Tunnel" und B.A.T.M.A.N. zusammengefasst.Diese Lösung ist alles andere als hübsch und auf jeden Fall nicht perfekt aber sie funktioniert.

Das DAD (Duplicate Address Detection) musste ich für das ggrzBR-Interface deaktivieren da dies zu Probleme führte.

Mit dem ggrzBAT-Interface wird auch der Fastd gestartet und gestoppt.In der Config von Fastd wird das ggrzVPN-Interface an ggrzBAT gebunden.

/etc/network/interfaces

# hier darf eth0 nicht fehlen !

###############################
# Tunnel
###############################
# ggrzTUN1: gw1 <-> gw2
# ggrzTUN2: gw1 <-> gw3
# ggrzTUN3: gw2 <-> gw3

auto ggrzTUN1
iface ggrzTUN1 inet manual
        pre-up /bin/ip link add $IFACE type gretap remote 148.251.158.22 local 193.28.153.11 key 1
        pre-up /bin/ip link set address de:ad:be:ef:02:03 dev $IFACE
        post-up ip link set $IFACE up
        post-down /bin/ip link del $IFACE
auto ggrzTUN3
iface ggrzTUN3 inet manual
        pre-up /bin/ip link add $IFACE type gretap remote 5.196.74.176 local 193.28.153.11 key 3
        pre-up /bin/ip link set address de:ad:be:ef:02:05 dev $IFACE
        post-down /bin/ip link del $IFACE
        post-up /bin/ip link set $IFACE up

###############################
# Bridge
###############################
allow-hotplug ggrzDummy
auto ggrzDummy
iface ggrzDummy inet manual
        #bridge_ports ggrzBR
        pre-up /bin/ip tuntap add $IFACE mode tap user root
        post-up /bin/ip link set address de:ad:be:ef:02:00 dev $IFACE
        post-up ip link set $IFACE up
        post-down /bin/ip link del $IFACE

auto ggrzBR
iface ggrzBR inet6 static
        dad-attempts 0
        address fdb5:078b:64cc::12
        netmask 64
        bridge-stp no
        bridge-fd 0
        bridge-hello 10
        bridge-ports ggrzDummy
        #pre-up /sbin/brctl addif $IFACE ggrzDummy
        post-up /bin/ip rule add iif $IFACE table ggrz priority 1810 || true
        post-up /bin/ip route add unreachable default table ggrz || true
        post-up /bin/ip -6 rule add iif $IFACE table ggrz priority 1810 || true
        post-up /bin/ip -6 route add fe80::/64 proto static dev $IFACE table ggrz || true
        post-up /bin/ip -6 route add fdb5:078b:64cc::/64 proto static dev $IFACE table ggrz || true
        #post-up /bin/ip -6 addr add fdb5:078b:64cc::12/64 dev ggrzBR
        pre-down /bin/ip -6 route del fe80::/64 proto static dev $IFACE table ggrz || true
        pre-down /bin/ip -6 route del fdb5:078b:64cc::/64 proto static dev $IFACE table ggrz || true
        pre-down /bin/ip rule del iif $IFACE table ggrz priority 1810 || true
        pre-down /bin/ip route del unreachable default table ggrz || true
        pre-down /bin/ip -6 rule del iif $IFACE table ggrz priority 1810 || true

iface ggrzBR inet static
        address 10.181.0.12
        netmask 255.255.192.0
        broadcast 10.181.63.255

###############################
# Mesh-Interfaces
###############################
auto ggrzBAT
iface ggrzBAT inet manual
        pre-up /usr/local/sbin/batctl -m $IFACE if add ggrzTUN1
        pre-up /usr/local/sbin/batctl -m $IFACE if add ggrzTUN3
        pre-up /usr/local/sbin/batctl -m $IFACE gw server 96mbit/96mbit
        pre-up /usr/local/sbin/batctl -m $IFACE it 10000
        pre-up echo 60 > /sys/class/net/$IFACE/mesh/hop_penalty
        pre-up /sbin/brctl addif ggrzBR $IFACE
        pre-up /bin/ip link set address de:ad:be:ef:02:02 dev $IFACE
        post-up ip link set $IFACE up
        post-up start-stop-daemon -b --start --exec /usr/local/bin/fastd -- --config /etc/fastd/ggrz/fastd.conf;
        pre-down start-stop-daemon --stop --exec /usr/local/bin/fastd;

        post-down /sbin/brctl delif ggrzBR $IFACE
        post-down /usr/local/sbin/batctl -m $IFACE if del ggrzTUN1
        post-down /usr/local/sbin/batctl -m $IFACE if del ggrzTUN3

Ganz wichtig ist dass die MAC-Adressen korrekt angepasst werden!

B.A.T.M.A.N.

B.A.T.M.A.N.

sudo apt-get install linux-headers-$(uname --kernel-release) build-essential
cd /usr/local/src/

#wget http://downloads.open-mesh.org/batman/releases/batman-adv-2015.1/batman-adv-2015.1.tar.gz
wget https://downloads.open-mesh.org/batman/releases/batman-adv-2016.5/batman-adv-2016.5.tar.gz
tar -xzf batman-adv-201*
cd batman-adv-201*
make
sudo make install

sudo cp /lib/modules/$(uname --kernel-release)/kernel/net/batman-adv/batman-adv.ko /root/batman-adv.ko.old
sudo cp net/batman-adv/batman-adv.ko /lib/modules/$(uname --kernel-release)/kernel/net/batman-adv/batman-adv.ko

Jetzt sollte der Befehl /sbin/modinfo batman-advfolgendes ausgeben:

filename:       /lib/modules/3.16.0-4-amd64/updates/net/batman-adv/batman-adv.ko
version:        2015.1
description:    B.A.T.M.A.N. advanced
author:         Marek Lindner , Simon Wunderlich 
license:        GPL
srcversion:     4D64E98D15541F2EB62A9F0
depends:        libcrc32c,crc16
vermagic:       3.16.0-4-amd64 SMP mod_unload modversions

Da das Kernelmodul selbst gebaut wurde muss es bei einem neuen Kernel auch neu gebaut werden!

batctl

sudo apt-get install pkg-config libnl-3-200 libnl-3-dev libnl-genl-3-dev
#wget http://downloads.open-mesh.org/batman/releases/batman-adv-2015.1/batctl-2015.1.tar.gz
wget https://downloads.open-mesh.org/batman/releases/batman-adv-2016.5/batctl-2016.5.tar.gz
tar -xzf batctl-201*
cd batctl-201*
make
sudo make install

FastD

sudo apt-get install cmake bison pkg-config libsodium-dev libcap-dev doxygen libjson-c-dev
cd /usr/local/src

#wget http://git.universe-factory.net/libuecc/snapshot/libuecc-5.tar
#wget --no-check-certificate https://projects.universe-factory.net/attachments/download/81/fastd-17.tar.xz
wget https://projects.universe-factory.net/attachments/download/85/libuecc-7.tar.xz
wget https://projects.universe-factory.net/attachments/download/86/fastd-18.tar.xz

tar -xf fastd-*
tar -xf libuecc-*

cd libuecc-*
cmake .
make
sudo make install
ln -s /usr/local/src/libuecc-7/src/libuecc.so /lib/libuecc.so
ln -s /usr/local/src/libuecc-7/src/libuecc.so.0 /lib/libuecc.so.0
{{{

cd /usr/local/src cd fastd-* cmake . make sudo make install

sudo mkdir -p /etc/fastd/ggrz }}}

fastd-Schlüssel analog Gentoo erstellen

/etc/fastd/ggrz/fastd.conf

log to syslog level verbose;

hide ip addresses yes;
hide mac addresses yes;

interface "ggrzVPN";

method "aes128-gcm";
method "salsa2012+umac";
method "null+salsa2012+umac";

bind 193.28.153.11:10181;
bind [2a02:ff80:1003:2::2]:10181;

mode tap;

include "secret.conf";
mtu 1406; # 1492 - IPv4/IPv6 Header - fastd Header...

include peers from "peers";

status socket "/var/run/fastd-gera-greiz.status";

on up "
    /bin/ip link set address de:ad:be:ef:02:01 dev $INTERFACE up
    /bin/ip link set dev ggrzBAT up
    /usr/local/sbin/batctl -m ggrzBAT if add $INTERFACE
    /sbin/start-stop-daemon -b --start --exec /usr/local/sbin/batadv-vis -- -si ggrzBAT
    /sbin/start-stop-daemon -b --start --exec /usr/local/sbin/alfred -- -i ggrzBR -b ggrzBAT
";

on down "
    /sbin/start-stop-daemon --stop --exec /usr/local/sbin/alfred
    /sbin/start-stop-daemon --stop --exec /usr/local/sbin/batadv-vis
    /bin/ip link set dev ggrzBAT down
    /usr/local/sbin/batctl -m ggrzBAT if del $INTERFACE
    /bin/ip link set dev $INTERFACE down
";

# Accept all keys
on verify "true";

# or with blacklist
#on verify "/etc/fastd/ggrz/fastd-blacklist.sh $PEER_KEY"

Die Blacklist ist noch nicht integriert aber zur Vollständigkeit hier dennoch angegeben:

/etc/fastd/ggrz/fastd-blacklist.sh

#!/bin/bash
PEER_KEY=$1

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

/etc/cron.d/update-fastd-blacklist

# Global variables
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# Update blacklist every 15 minutes.
*/15 * * * * root wget http://irgendwo.de/fastd-blacklist.json -O /etc/fastd/ggrz/fastd-blacklist.json > /dev/null

Exit-VPN

sudo apt-get install openvpn

Config und Scripte einfach in /etc/openvpn kopieren.Die VPN-Config um folgende zwei Zeilen für die Scripte erweitern:

up /etc/openvpn/openvpn.-up.sh
down /etc/openvpn/openvpn.-down.sh

Noch das Interface anpassen:

dev exitVPN

IC-VPN

sudo apt-get install tinc bird bird6

Die Konfigurationsdateien sind mit der Gentoo-Anleitung identisch.

Firewall

Layer 3

sudo apt-get install iptables-persistent

Die Regeln genauso wie in der Gentoo-Anleitung einfügen aber zum Abspeichern folgendes eingeben:

sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6

Layer 2

sudo apt-get install ebtables bridge-utils

Regeln wie in der Gentoo-Anleitung einfügen und wie folgt abspeichern:

sudo EBTABLES_ATOMIC_FILE=/root/ebtables-atomic ebtables -t nat --atomic-save
sudo EBTABLES_ATOMIC_FILE=/root/ebtables-atomic ebtables -t nat --atomic-commit

In der Datei /etc/default/ebtables folgendes ändern damit die Regeln beim Systemstart wieder hergestellt werden:

EBTABLES_LOAD_ON_START="yes"

Dienste

NTP

sudo apt-get install ntp

Da die Host-Uhr des V-Server falsch lief habe ich NTP angepasst damit die Uhr von NTP gestellt wird.Ansonsten kann die Konfiguration aus der Gentoo-Anleitung 1:1 übernommen werden.

/etc/ntp.conf

# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help

driftfile /var/lib/ntp/ntp.drift

statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

server 0.debian.pool.ntp.org iburst
server 1.debian.pool.ntp.org iburst
server 2.debian.pool.ntp.org iburst
server 3.debian.pool.ntp.org iburst



# listen at localhost and mesh only
#interface ignore wildcard
#interface listen 127.0.0.1
#interface listen ::1
#interface listen 10.181.0.12
#interface listen fdb5:78b:64cc::12

# only use local time, synced with kvm host time
#tos orphan 1

# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery

# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1

Unter KVM muss die Uhrzeit-Quelle erst angepasst werden damit NTP die Uhrzeit auch verändern kann.

/etc/rc.local

echo tsc > /sys/devices/system/clocksource/clocksource0/current_clocksource

tsc ohne NTP auf einen V-Server zu verwenden ist keine gute Idee da diese sehr schnell nach dem Mond läuft.

Diese Lösung ist nicht 100% sauber aber mir hats genügt.

Hinweis: NTP bindet sich automatisch an neue Interfaces.

dnsmasq

/etc/resolv.conf

search ffggrz
nameserver 127.0.0.1
nameserver 8.8.8.8

Die hier gezeigte dnsmasq.conf und damit auch das Update-Script ist noch nicht entgültig geklärt, daher sollte diese aus der Gentoo-Anleitung verwendet werden!

/etc/dnsmasq.conf

### Allgemeines

#ignores README.md from Github-README
#conf-dir=/etc/dnsmasq.d,.md
#or use only with with .conf extension
conf-dir=/etc/dnsmasq.d,*.conf

bogus-priv
no-resolv
no-poll
expand-hosts
domain-needed
cache-size=4096
strict-order
interface=ggrzBR
bind-interfaces

### DNS

# DNS Server
server=193.28.153.254
server=213.73.91.35
server=8.8.8.8
server=8.8.4.4

local=/ffggrz/
domain=ffggrz

### DHCP / RA

dhcp-authoritative
#log-dhcp

dhcp-range=10.181.3.1,10.181.4.254,3m
dhcp-option=option:router,10.181.0.12
dhcp-option=option:dns-server,10.181.0.12,10.181.0.11,10.181.0.13,8.8.8.8
dhcp-option=option:ntp-server,10.181.0.12
dhcp-option=option:domain-search,ffggrz
### MTU 1280
##dhcp-option-force=26,1280

dhcp-range=set:v6,::,constructor:ggrzBR,slaac,ra-only,3m
dhcp-option=tag:v6,option6:dns-server,[fdb5:78b:64cc::12],[fdb5:78b:64cc::11],[fdb5:78b:64cc::13],[2001:4860:4860::8888]
dhcp-option=tag:v6,option6:ntp-server,[fdb5:78b:64cc::12],[fdb5:78b:64cc::11],[fdb5:78b:64cc::13]
dhcp-option=tag:v6,option6:domain-search,ffggrz

#enable-ra
#ra-param=ggrzBAT,low,0,0
#ra-param=ggrzBR,high,60,1200

/etc/cron.d/update-dnsmasq-hostfile

# Global variables
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# Update hostsfile every 15 minutes.
*/15 * * * * root /usr/local/bin/update-dnsmasq-hostsfile > /dev/null

/usr/local/bin/update-dnsmasq-hostsfile

#!/bin/bash

# dnsmasq configuration directory
#HOSTSFILE_DIR=/etc/dnsmasq_hostsfile.d/
#CONF_DIR=/etc/dnsmasq_hostsfile.d/
CONF_DIR=/etc/dnsmasq.d/

function getCurrentVersion() {
# Get hash from latest revision
git log --format=format:%H -1
}

cd $CONF_DIR

# 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)

echo "old: $GIT_REVISION"
echo "new: $GIT_NEW_REVISION"

if [ $GIT_REVISION != $GIT_NEW_REVISION ]
then
  # Reload updated configuration
  echo "Reload dnsmasq configuration."
  cat $CONF_DIR/ffggrz-static.conf | sed -r 's/^dhcp-host=([A-Fa-f0-9:]*),([^,]*),([0-9]*)\\.([0-9]*)\\.([0-9]*)\\.([0-9]*).*/ptr-record=\\6.\\5.\\4.\\3.in-addr.arpa,\\2/' | grep  '^ptr-record' > $CONF_DIR/ptr_records_from_static

  service dnsmasq force-reload
fi

Im Github sollte es zwei Konfigurationsdateien geben, eine für die DNS-Auflösung (A, MX, NS, AAA, CNAME, TXT, ...) und eine für statische DHCP IP-Vergabe.

Beispiel:

ffggrz-dns.conf

# Config fuer zusaetlich Domains

#test (Marcus)
address=/bla.ffggrz/10.181.0.101

#test (Eric)
address=/1.eric.ffggrz/10.181.0.120

ffggrz-static.conf

#Config fuer feste IPs und gleich passende Domain(IN-A)

#test (Marcus)
dhcp-host=68:9c:5e:9f:83:15,test_stadtmitte.ffggrz,10.181.0.102

#test (Eric)
dhcp-host=4C:34:88:29:54:A5,eric-1.ffggrz,10.181.0.120

Da dnsmasq die README.md aus dem Github einlesen würde muss im dnsmasq entweder alle *.md ausgeschlossen oder nur *.conf geladen werden.

Hinweis: dnsmasq bindet sich automatisch an neue Interfaces.

Hinweis: Verzeichnis /etc/dnsmasq.d muss nicht erstellt werden!

ALFRED

cd /usr/local/src/

wget http://downloads.open-mesh.org/batman/releases/batman-adv-2015.1/alfred-2015.1.tar.gz
tar -xzf alfred-2015.1.tar.gz
cd alfred-2015.1/

make CONFIG_ALFRED_GPSD=n
sudo make CONFIG_ALFRED_GPSD=n install

Hinweis: Alfred wird von FastD gestartet!

vnstat/vnstati

sudo apt-get install vnstat vnstati
sudo vnstat -u -i ggrzBR
sudo vnstat -u -i ggrzBAT
sudo vnstat -u -i exitVPN
sudo vnstat -u -i ggrzTUN1
sudo vnstat -u -i ggrzTUN3
sudo vnstat -u -i icVPN
sudo chown vnstat:vnstat /var/lib/vnstat/*
sudo service vnstat restart

/etc/cron.d/update-vnstat-webstats.sh

# Global variables
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

*/5 * * * * root /usr/local/bin/update-vnstat-webstats.sh

/usr/local/bin/update-vnstat-webstats.sh

#!/bin/sh

#IFACES=$(ls /var/lib/vnstat/)
IFACES="ggrzBAT exitVPN icVPN"

TARGET=/var/www/html/vnstat/

for iface in $IFACES; do
    /usr/bin/vnstati -i ${iface} -h -o ${TARGET}${iface}_hourly.png
    /usr/bin/vnstati -i ${iface} -d -o ${TARGET}${iface}_daily.png
    /usr/bin/vnstati -i ${iface} -m -o ${TARGET}${iface}_monthly.png
    /usr/bin/vnstati -i ${iface} -t -o ${TARGET}${iface}_top10.png
    /usr/bin/vnstati -i ${iface} -s -o ${TARGET}${iface}_summary.png
done

cat > ${TARGET}index.html <



  
  
  



EOT


for iface in $IFACES; do
    sed s/IFACE/${iface}/g >> ${TARGET}index.html <
    traffic summary
traffic per month
traffic per hour
traffic top10
traffic per day
EOT done echo "" >> ${TARGET}index.html

Frontend

Gibts nur einmal pro Freifunk-Community, daher hier komplett weggelassen.

Optional: munin

sudo apt-get install munin

Integration in Webserver muss selbst erledigt werden.Falls es schon einen munin-server gibt sollte hier der munin-node installiert werden.

Backup und Wartung

Backup

sudo tar -czf - /etc > ~/gw2_backup_$(date +"%Y%m%d_%H%M%S").tar.gz

Das Backup sollte sicher aufbewahrt werden da darin auch Private-Keys und Passwörter stehen!

Wartung

kT

Überprüfung der Einstellungen

brctl show

bridge name     bridge id               STP enabled     interfaces
ggrzBR          8000.deadbeef0200       no              ggrzBAT
                                                        ggrzDummy

batctl -m ggrzBAT gwl

      Gateway      (#/255)           Nexthop [outgoingIF]: advertised uplink bandwidth ... [B.A.T.M.A.N. adv 2015.1, MainIF/MAC: ggrzTUN1/de:ad:be:ef:02:03 (ggrzBAT)]
   de:ad:be:ef:01:01 (255) de:ad:be:ef:01:03 [  ggrzTUN1]: 96.0/96.0 MBit
   de:ad:be:ef:03:04 (255) de:ad:be:ef:03:05 [  ggrzTUN3]: 96.0/96.0 MBit

batctl -m ggrzBAT if

ggrzTUN3: active
ggrzTUN1: active
ggrzVPN: active

ifconfig

eth0      Link encap:Ethernet  HWaddr 52:54:00:28:14:c8
          inet addr:193.28.153.11  Bcast:193.28.153.255  Mask:255.255.255.0
          inet6 addr: 2a02:ff80:1003:2::2/64 Scope:Global
          inet6 addr: fe80::5054:ff:fe28:14c8/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:80296635 errors:0 dropped:8033 overruns:0 frame:0
          TX packets:52538871 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:16191904959 (15.0 GiB)  TX bytes:15949713964 (14.8 GiB)

exitVPN   Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.114.0.115  P-t-P:10.114.0.115  Mask:255.255.0.0
          inet6 addr: fd39:cdef:9618:72::1071/112 Scope:Global
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:6024602 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3890046 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:7356020110 (6.8 GiB)  TX bytes:417733636 (398.3 MiB)

ggrzBAT   Link encap:Ethernet  HWaddr de:ad:be:ef:02:02
          inet6 addr: fe80::dcad:beff:feef:202/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8622637 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9438523 errors:0 dropped:31656 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:857382035 (817.6 MiB)  TX bytes:7883348224 (7.3 GiB)

ggrzBR    Link encap:Ethernet  HWaddr de:ad:be:ef:02:00
          inet addr:10.181.0.12  Bcast:10.181.63.255  Mask:255.255.192.0
          inet6 addr: fdb5:78b:64cc::12/64 Scope:Global
          inet6 addr: fe80::dcad:beff:feef:200/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8626127 errors:0 dropped:65 overruns:0 frame:0
          TX packets:9470171 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:736741551 (702.6 MiB)  TX bytes:7884891558 (7.3 GiB)

ggrzDummy Link encap:Ethernet  HWaddr de:ad:be:ef:02:00
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ggrzTUN1  Link encap:Ethernet  HWaddr de:ad:be:ef:02:03
          inet6 addr: fe80::dcad:beff:feef:203/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1458  Metric:1
          RX packets:12414385 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10328976 errors:7 dropped:0 overruns:0 carrier:7
          collisions:0 txqueuelen:1000
          RX bytes:1787847851 (1.6 GiB)  TX bytes:1392594024 (1.2 GiB)

ggrzTUN3  Link encap:Ethernet  HWaddr de:ad:be:ef:02:05
          inet6 addr: fe80::dcad:beff:feef:205/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1458  Metric:1
          RX packets:6878445 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7016310 errors:7 dropped:0 overruns:0 carrier:7
          collisions:0 txqueuelen:1000
          RX bytes:709346982 (676.4 MiB)  TX bytes:779500947 (743.3 MiB)

ggrzVPN   Link encap:Ethernet  HWaddr de:ad:be:ef:02:01
          inet6 addr: fe80::dcad:beff:feef:201/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1406  Metric:1
          RX packets:18217951 errors:0 dropped:0 overruns:0 frame:0
          TX packets:19160527 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:2004329047 (1.8 GiB)  TX bytes:9241262907 (8.6 GiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:88636 errors:0 dropped:0 overruns:0 frame:0
          TX packets:88636 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:11916430 (11.3 MiB)  TX bytes:11916430 (11.3 MiB)

ip addr show

1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:28:14:c8 brd ff:ff:ff:ff:ff:ff
    inet 193.28.153.11/24 brd 193.28.153.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 2a02:ff80:1003:2::2/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe28:14c8/64 scope link
       valid_lft forever preferred_lft forever
3: gre0@NONE:  mtu 1476 qdisc noop state DOWN group default
    link/gre 0.0.0.0 brd 0.0.0.0
4: gretap0@NONE:  mtu 1462 qdisc noop state DOWN group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
5: ggrzTUN1@NONE:  mtu 1458 qdisc pfifo_fast master ggrzBAT state UNKNOWN group default qlen 1000
    link/ether de:ad:be:ef:02:03 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dcad:beff:feef:203/64 scope link
       valid_lft forever preferred_lft forever
6: ggrzTUN3@NONE:  mtu 1458 qdisc pfifo_fast master ggrzBAT state UNKNOWN group default qlen 1000
    link/ether de:ad:be:ef:02:05 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dcad:beff:feef:205/64 scope link
       valid_lft forever preferred_lft forever
7: ggrzDummy:  mtu 1500 qdisc pfifo_fast master ggrzBR state DOWN group default qlen 500
    link/ether de:ad:be:ef:02:00 brd ff:ff:ff:ff:ff:ff
8: ggrzBR:  mtu 1500 qdisc noqueue state UP group default
    link/ether de:ad:be:ef:02:00 brd ff:ff:ff:ff:ff:ff
    inet 10.181.0.12/18 brd 10.181.63.255 scope global ggrzBR
       valid_lft forever preferred_lft forever
    inet6 fdb5:78b:64cc::12/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::dcad:beff:feef:200/64 scope link
       valid_lft forever preferred_lft forever
9: ggrzBAT:  mtu 1500 qdisc noqueue master ggrzBR state UNKNOWN group default
    link/ether de:ad:be:ef:02:02 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dcad:beff:feef:202/64 scope link
       valid_lft forever preferred_lft forever
10: ggrzVPN:  mtu 1406 qdisc pfifo_fast master ggrzBAT state UNKNOWN group default qlen 500
    link/ether de:ad:be:ef:02:01 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::dcad:beff:feef:201/64 scope link
       valid_lft forever preferred_lft forever
13: exitVPN:  mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 100
    link/none
    inet 10.114.0.115/16 brd 10.114.255.255 scope global exitVPN
       valid_lft forever preferred_lft forever
    inet6 fd39:cdef:9618:72::1071/112 scope global
       valid_lft forever preferred_lft forever

ip route show

default via 193.28.153.1 dev eth0
10.114.0.0/16 dev exitVPN  proto kernel  scope link  src 10.114.0.115
10.181.0.0/18 dev ggrzBR  proto kernel  scope link  src 10.181.0.12
193.28.153.0/24 dev eth0  proto kernel  scope link  src 193.28.153.11

ip rule show

0:      from all lookup local
1810:   from all iif ggrzBR lookup ggrz
9181:   from 10.114.0.115 lookup ggrz
32766:  from all lookup main
32767:  from all lookup default

ip route show table ggrz

0.0.0.0/1 via 10.114.0.1 dev exitVPN
unreachable default
128.0.0.0/1 via 10.114.0.1 dev exitVPN

Nicht wundern, die Routing-Regeln werden nicht wie in iptables von oben nach unten abgearbeitet sondern in der Reihenfolge der Netzmaske!


Verschiedenes

Verbesserungen der Anleitung

  • Ausdruck- und Rechtschreibkontrolle xD
  • Kann Alfred über vor fastd gestartet werden? Dadurch könnte Alfred schon beim Systemstart gestartet werden
  • Aufteilung der /etc/network/interfaces zur besseren übersicht
  • Haben die up/down-Scripte des exitVPN einen richtigen Platz unter Debian? (wie unter Gentoo)
  • Anleitung ausbauen um die Abhängigkeit zur Gentoo-Anleitung zu lösen.

Überlegungen zum Betrieb

reine Überlegungen zum Gateway-Betrieb ohne Anspruch auf Richtigkeit

Überlegungen zu IPv6-Only Netzwerken mit Windows/Linux

In der Aktuellen Konfiguration und Version (dnsmasq 2.72) ist ausschließlich das A-Flag im RA (Router-Advertisement-Packet) gesetzt.Daher wird nur im RA (RDNSS Feature) die "DNS Search List" und "Recursive DNS Server" verschickt, dies würde ausreichen damit ein IPv6-Only Netzwerk funktionieren kann.Um aber NTP, SIP, Routen oder ähnliches noch zu setzen wird DHCPv6 benötigt (O-Flag).Da Windows RDNSS nicht unterstützt ist im Moment DHCPv6 für ein funktionierendes Netzwerk notwendig.Erst mit den M-Flag wird über DHCPv6, unabhängig von der Auto-Konfiguration, eine IPv6 vom DHCPv6 vergeben.

In meinen Tests konnten meine Freifunk-Knoten (Gluon 2015.1.2/2015.2), mein Android-Handy (Android 4.2.1), den Raspberry Pi und Banana Pi mit gesetzten A- und O-Flag alles korrekt einstellen.Leider war ich unter Windows 8.1 nicht erfolgreich, erst als das M-Flag gesetzt wurde und der dnsmasq per DHCPv6 - zusätzlich zur autokonfigurierten - eine IPv6 vergeben hat konnte Windows auch alle anderen Daten korrekt einstellen.

Im Parallelbetrieb mit IPv4 reicht die Auto-Konfiguration ohne DHCPv6 da DNS über IPv4 (mit AAAA-Records) aufgelöst wird.

RA = Router-Advertisement-Packet

M-Flag = Managed Address Configuration Flag: statefull, get IP from DHCPv6

O-Flag = Other Configuration Flag: get other data from DHCPv6

A-Flag = Autonomous address-Configuration Flag: stateless

https://weirdfellow.wordpress.com/2014/09/05/dhcpv6-and-ra-with-dnsmasq/

Überlegungen zu Fastd Gateway Auto-Balancing

kT

Überlegungen zur vergabe fester IPs mit dnsmasq für interne Dienste

Vorteile:

  • Zentrale Verwaltung
  • geringere Hürden für Anfänfger da nichts eingstellt werden mussNachteile:
  • kein DHCP-Server -> keine IP
  • manche Geräte unterstützen kein DHCPParallelbetrieb?

Ungelöste Probleme

  • da batman-adv nur die Verbindung und Verbindungsqualität (TQ) zum nächsten Node kennt entstehen folgende Phänomene:
    • Pakete werden über Gateways geschickt obwohl eine Funkverbindung möglich gewesen wäre
    • unterschiedliche Bandbreiten werden gleich behandelt
    • Bei starker Auslastung mit verschiedenen Routen entsteht ein "schwallartiger" Datenstrom da erst die Route gewechselt wird wenn Pakete (TQ) verloren gehen
    • http://trier.freifunk.net/2015/10/21/layer-2-anycast-routing-mit-batman/
  • Verteiltes DNS
    • https://github.com/mwarning/KadNode
  • Verteiltes DHCP
    • https://forum.freifunk.net/t/experimenteller-server-fuer-verteiltes-dhcp/5426?page=3
  • Montoring / Fallback / Watchdog
    • munin
    • monit
    • fertige Python-Scripte aus anderen FF-Communitys
Details
Geschrieben von: Matthias Drobny
Kategorie: Gateways
Veröffentlicht: 23. November 2021
Zuletzt aktualisiert: 15. Februar 2017

Gateway mit Gentoo

Die Installation des Gateways ist noch nicht abgeschlossen, deswegen ist dieser Wiki-Eintrag noch nicht fertiggestellt. Änderungen sind möglich, ebenso können noch Fehler enthalten sein.


<>

Voraussetzungen

Im Folgenden wird das Aufsetzen eines Gateways (gw1) beschrieben. Beispielhaft verwenden wir Gentoo, dabei wird von Grundinstallation laut Gentoo Handbuch ausgegangen. Empfohlen wird die Nutzung eines Hardened Profiles.

Die einzelnen Konfigurationsdateien werden zentral in einem Git-Repository und können dort eingesehen werden.Dort befindet sich auch ein Gentoo-Portage-Overlay für Freifunk-spezifische Ebuilds. Diese wird wie folgt eingebunden:

emerge -av layman

Nach der Layman-Installation wird angezeigt, wie dies in der Portage-Konfiguration (/etc/portage/make.conf) integriert wird. Danach wird das Overlay eingebunden:

# cd /etc/layman/overlays
# wget https://raw.githubusercontent.com/ffggrz/ff-overlay/master/ff-overlay.xml
# layman -L
# layman -a ff-overlay

Grundkonfiguration

Hostname

Der Hostname wird in /etc/conf.d/hostname gesetzt:

# Set to the hostname of this machine
hostname="gw1"

/etc/hosts sollte etwa so aussehen:

# IPv4 and IPv6 localhost aliases

#
127.0.0.1                       localhost
::1                             localhost ip6-localhost ip6-loopback
ff02::1                         ip6-allnodes
ff02::2                         ip6-allrouters

# own external addresses
148.251.158.22                  gw1.freifunk-gera-greiz.de gw1
2a01:4f8:210:5132:201::22       gw1.freifunk-gera-greiz.de gw1

# Freifunk external
78.46.192.49                    gw2.freifunk-gera-greiz.de gw2
2a01:4f8:c17:229::12            gw2.freifunk-gera-greiz.de gw2

 # Freifunk internal

10.181.0.1                      nextnode.ffggrz
fdb5:078b:64cc::1               nextnode.ffggrz

10.181.0.11                     gw1.ffggrz 1.ntp.services.ffggrz 1.updates.services.ffggrz
fdb5:78b:64cc::11               gw1.ffggrz 1.ntp.services.ffggrz 1.updates.services.ffggrz

10.181.0.12                     gw2.ffggrz 2.ntp.services.ffggrz 2.updates.services.ffggrz
fdb5:78b:64cc::12               gw2.ffggrz 2.ntp.services.ffggrz 2.updates.services.ffggrz

10.181.0.101                    raspbx.ffggrz
fdb5:78b:64cc::101              raspbx.ffggrz

Hier werden also, jeweils für IPv4 und IPv6, die Namen für die localhost-Adressen, die externen Adressen im Internet und die Freifunk-internen Adressen definiert. Am Ende folgen noch Einträge für alle Host, welche der später per DNSmasq arbeitende DNS-Server auflösen soll.

Routing

/etc/iproute2/rt_tables:

#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
# local community tables
181     ggrz
#
# icvpn table
42      icvpn
#
# ffrl table (Exit per FFRL)
83      ffrl

Hier wurden separate Routing-Tabellen für das lokale Mesh-Netzwerk (181, ggrz), das Intercity-VPN (42, icvpn) und den Exit per Freifunk Rheinland e.V. (83, ffrl) definiert. Nur so kann später erreicht werden, daß dieses Gateway als Default Gateway für alle Clients fungiert und deren Traffic nicht über das "normale" Internet routet, sondern über ein Exit-VPN per Tunnel ins Ausland oder zu einem der Freifunk-Vereine mit Provider-Status.

Kernelparameter

Unter Gentoo bauen wir den Kernel selbst. Neben der Grundkonfiguration, um die verwendete Hardware bzw. den Virtualisierungs-Host oder Grundfunktionen wie Netzwerk mit IPv6 zu unterstützen, brauchen wir folgende Optionen:

[*] Networking support --->
   Networking options --->
      <*> TCP/IP networking
      [*] IP: multicasting
      [*] IP: advanced router
      [*] IP: policy routing
      <*> The IPv6 protocol --->
             [*] IPv6: multiple routing tables
      <*> 802.1d Ethernet Bridging

    Device Drivers  --->
      [*] Network device support  --->
             [*]   Network core driver support
             <*>     Universal TUN/TAP device driver support

Sicherlich fehlen hier noch viele andere erforderliche Parameter. Ein Beispiel einer funktionierenden (aber sicher auch nicht optimalen) Konfiguration findet sich hier: linux-3.18.9-hardened.config. Die aktuelle Konfiguration ist im Git-Repository zu finden.

Folgende Einstellungen in /etc/sysctl.conf sind erforderlich:

# Freifunk specific settings
net.ipv4.ip_forward = 1

net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2

net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0

net.ipv6.conf.all.forwarding = 1

net.ipv6.conf.all.autoconf = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.eth0.autoconf = 0

net.ipv6.conf.all.accept_ra = 0
net.ipv6.conf.default.accept_ra = 0
net.ipv6.conf.eth0.accept_ra = 0

Damit wird das Routing (Forwarding) für IPv4 und IPv6 aktiviert, Bridge-Traffic wird nicht von der Firewall (iptables) verarbeitet, die IPv6-Autoconfiguration wird deaktiviert und Router Advertisements werden nicht ausgewertet.

Netzwerk

Externe Anbindung

Das Gateway in diesem Beispiel läuft als Virtuelle maschine auf einem Root-Server bei Hetzner unter KVM. Der Root-Server verfügt über ein zusätzliches Subnetz mit 8 IPv4-Adressen sowie ein IPv6-Subnetz. Um die wertvollen IPv4-Adressen alle nutzen zu können und diese nicht als Netzwerk- und Broadcast-Adresse "zu verbraten", wird eine etwas spezielle Netzwerk-Konfiguration verwendet:

modules="iproute2"

# Natives IPv6-Netz (/64)
v6net="2a01:4f8:210:5132"

config_eth0="148.251.158.22 peer 148.251.152.51
             ${v6net}:201::22/128"
routes_eth0="default via 148.251.152.51
             default via fe80::1"

dns_domain="freifunk-gera-greiz.de"
dns_servers="213.133.100.100 213.133.99.99 213.133.98.98"

Auf gw3 (Rootserver Kimsuf1 KS-2 SSD) sieht das so aus:

modules="iproute2"

###############################
# Externe Anbindung
###############################
config_eth0="5.196.74.176/24
             2001:41d0:e:8b0::1/64"
routes_eth0="default via 5.196.74.254
             2001:41d0:e:8ff:ff:ff:ff:ff
             default via 2001:41d0:e:8ff:ff:ff:ff:ff"

dns_domain="freifunk-gera-greiz.de"
dns_servers="213.186.33.99
             2001:41d0:3:163::1"

Bridge

Eine Bridge brauchen wir im Gateway nicht unbedingt. Sie erleichtert aber das Leben, da sie praktisch ohne Abhängigkeiten immer aktiv bleibt. Die Bridge erhält die Freifunk-internen IP-Adressen des Gateways, auch diese sind damit immer verfügbar. Daran können wir dann unsere internen Dienste (DNS, DHCP, NTP...) binden. Würden wir auf die Bridge verzichten, müßte das B.A.T.M.A.N.-Interface die IP-Adressen erhalten. Müßte dieses z.B. neu gestartet werden, müßten wir auch alle Dienste neu starten.Die Bridge wird in /etc/conf.d/net wie folgt konfiguriert:

###############################
# Bridge
###############################
# Dummy-Interface "ggrzDummy" für die Bridge "ggrzBR". Dieses Interface bekommt
# die niedrigste Mac-Adresse aller Interfaces an der Bridge, welche dann auch
# von der Bridge übernommen wird.

tuntap_ggrzDummy="tap"
config_ggrzDummy="null"
rc_net_ggrzBR_need="net.ggrzDummy"

bridge_ggrzBR="ggrzDummy"
config_ggrzBR="10.181.0.11 netmask 255.255.192.0 brd 10.181.63.255
               fdb5:078b:64cc::11/64"
brctl_ggrzBR="setfd 0
sethello 10
stp off"

routes_ggrzBR="10.181.0.0/18 proto kernel src 10.181.0.11 table ggrz
               fe80::/64 proto kernel table ggrz
               fdb5:078b:64cc::/64 proto kernel table ggrz
               10.181.0.0/18 proto kernel src 10.181.0.11 table icvpn
               fe80::/64 proto kernel table icvpn
               fdb5:078b:64cc::/64 proto kernel table icvpn"
rules_ggrzBR="iif ggrzBR table ggrz priority 1810"
rules6_ggrzBR="iif ggrzBR table ggrz priority 1810"

###############################
# Up-/Down-Scripts
###############################
postup() {
    if  $IFACE == ggrzDummy  ; then
        /bin/ip link set address de:ad:be:ef:01:00 dev $IFACE
    elif  $IFACE == ggrzBR  ; then
        /bin/ip route add unreachable default table ggrz
    fi
    return 0
}

predown() {
    if  $IFACE == ggrzBR  ; then
        /bin/ip route del unreachable default table ggrz
    fi
    return 0
}

Zuerst wird also ein Dummy-Interface angelegt, welches als erstes an die Bridge gebunden wird. Von diesem Interface übernimmt die Bridge die Mac-Adresse, welche im postup-Script gesetzt wird. In den Rules zur Bridge wird festgelegt, daß alle über die Bridge eingehenden Pakete über die Tabelle ggrz geroutet werden.

Da die zusätzlichen Routing-Tables nicht automatisch Device-Rpouten erhalten, werden diese in der Konfiguration hinzugefügt (routes_ggrzBR).

Die Interfaces werden nach Anlegen der erforderlichen Symlinks gestartet und in den Runlevel default aufgenommen:

# cd /etc/init.d
# ln -s net.lo net.ggrzDummy
# ln -s net.lo net.ggrzBR
# rc-service net.ggrzDummy start
# rc-service net.ggrzBR start
# rc-update add net.ggrzDummy default
# rc-update add net.ggrzBR default

GRETAP-Tunnel

Zwischen den Gateways werden GRETAP-Tunnel angelegt, worüber diese auf Layer2-Ebene verbunden werden. Die Tunnel werden in /etc/conf.d/net wie folgt konfiguriert:

###############################
# Tunnel
###############################
# ggrzTUN1: gw1 <-> gw2
# ggrzTUN2: gw1 <-> gw3
# ggrzTUN3: gw2 <-> gw3
config_ggrzTUN2="null"
config_ggrzTUN3="null"

###############################
# Up-/Down-Scripts
###############################
preup() {
    if [...]
    elif $IFACE == ggrzTUN1 ; then
        /bin/ip link add $IFACE type gretap remote 193.28.153.11 local 148.251.158.22 key 1
        /bin/ip link set address de:ad:be:ef:01:03 dev $IFACE
    elif $IFACE == ggrzTUN2 ; then
        /bin/ip link add $IFACE type gretap remote 5.196.74.176 local 148.251.158.22 key 2
        /bin/ip link set address de:ad:be:ef:01:04 dev $IFACE
    fi
    return 0
}

postdown() {
    if [...]
    elif $IFACE == ggrzTUN1 ; then
        /bin/ip link del $IFACE type gretap remote 193.28.153.11 local 148.251.158.22 key 1
    elif $IFACE == ggrzTUN2 ; then
        /bin/ip link del $IFACE type gretap remote 5.196.74.176 local 148.251.158.22 key 2
    fi
    return 0
}

Auch für diese Tunnel-Interfaces werden wieder Symlinks angelegt, sie werden gestartet und in den Default-Runlevel aufgenommen:

# cd /etc/init.d
# ln -s net.lo net.ggrzTUN1
# ln -s net.lo net.ggrzTUN2
# rc-service net.TUN1 start
# rc-service net.TUN2 start
# rc-update add net.TUN1 default
# rc-update add net.TUN2 default

B.A.T.M.A.N.

Als Kernel-Modul nutzen wir nicht das direkt im Kernel integrierte, da wir dort nicht dessen Version beeinflussen können. Zur Steuerung benötigen wir dann noch batctl:

# echo "net-misc/batman-adv-2015.1" >> /etc/portage/package.keywords/Freifunk
# echo "net-misc/batctl-2015.1" >> /etc/portage/package.keywords/Freifunk
# echo "net-misc/batman-adv bla dat debug mcast nc" >> /etc/portage/package.use/Freifunk
# emerge -av batman-adv batctl

Die Konfiguration in /etc/conf.d/net:

###############################
# Mesh-Interfaces
###############################
config_ggrzBAT="null"
rc_net_ggrzBAT_need="net.ggrzBR net.ggrzTUN1 net.ggrzTUN2"

###############################
# Up-/Down-Scripts
###############################
preup() {
    if  $IFACE == ggrzBAT  ; then
        /sbin/modprobe batman-adv
        /usr/sbin/batctl -m $IFACE if add ggrzTUN1
        /usr/sbin/batctl -m $IFACE if add ggrzTUN2
        /usr/sbin/batctl -m $IFACE gw server 96mbit/96mbit
        /usr/sbin/batctl -m $IFACE it 10000
        /bin/ip link set address de:ad:be:ef:01:02 dev $IFACE
        echo 60 > /sys/class/net/$IFACE/mesh/hop_penalty
        /sbin/brctl addif ggrzBR $IFACE
    fi
    return 0
}

postdown() {
    if  $IFACE == ggrzBAT  ; then
        /sbin/brctl delif ggrzBR $IFACE
        /usr/sbin/batctl -m $IFACE if del ggrzTUN1
        /usr/sbin/batctl -m $IFACE if del ggrzTUN2
    fi
    return 0
}

Das Mesh-Interface wird also nach Bridge- und GRETAP-Tunnels gestartet. Nach dem Start des Mesh-Interfaces werden die Tunnel ans Mesh-Interface gekoppelt und dieses in der Gateway-Mode versetzt. Anschließend wird das Mesh-Interface an die Bridge gehängt.

Der Start erfolgt wie gewohnt:

# cd /etc/init.d
# ln -s net.lo net.ggrzBAT
# rc-service net.BAT start
# rc-update add net.BAT default

FastD

Der "Fast and secure tunneling Daemon" erstellt die Tunnel zwischen den Routern der Nodes und dem Gateway. Dafür gibt es keine fertigen Ebilds im Portage-Tree, aber sie sind bereits im Bugtracker gelandet: dev-libs/libuecc und net-misc/fastd. An diesen beiden Bugeinträgen hängen funktionierende Ebuilds, welche wir angepaßt und in unser Portage-Overlay integriert haben. Anschließend erfolgt die Installation mittels:

# echo "dev-libs/libuecc" >> /etc/portage/package.keywords/Freifunk
# echo "net-misc/fastd" >> /etc/portage/package.keywords/Freifunk
# echo "sys-devel/bison" >> /etc/portage/package.keywords/Freifunk
# emerge -av fastd

Die Konfiguration für unsere Community Gera-Greiz wird in folgender Datei vorgenommen:

/etc/fastd/ggrz/fastd.conf

log to syslog level verbose;

hide ip addresses yes;
hide mac addresses yes;

interface "ggrzVPN";

method "aes128-gcm";
method "salsa2012+umac";
method "null+salsa2012+umac";

# Bind auf externe v4 (genattet) and v6 Adressen
bind 172.31.1.100:10181;
bind [2a01:4f8:c17:229::12]:10181;

mode tap;

include "secret.conf";
mtu 1406; # 1492 - IPv4/IPv6 Header - fastd Header...

include peers from "peers";

status socket "/var/run/fastd-gera-greiz.status";

on up "
    /bin/ip link set address de:ad:be:ef:03:01 dev $INTERFACE up
    /usr/sbin/batctl -m ggrzBAT if add $INTERFACE
";

on down "
    /usr/sbin/batctl -m ggrzBAT if del $INTERFACE
    /bin/ip link set dev $INTERFACE down
"; 

on verify "
    /etc/fastd/ggrz/fastd-blacklist.sh $PEER_KEY
";

Das "on verify" Script wird bei der Verbindungsaufnahme unbekannter Clients aufgerufen. Es hat folgenden Inhalt:

/etc/fastd/ggrz/fastd-blacklist.sh

#!/bin/bash

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

Ist der Schlüssel des Clients in /etc/fastd/ggrz/fastd-blacklist.json aufgeführt, wird die Verbindung durch Rückgabe einer "1" abgewiesen, ansonsten werden Verbindungen unbekannter Knoten generell erlaubt (Rückgabe von "0").

Als nächstes werden die Keys erzeugt (die angezeigten Keys sind nur Beispiele):

# fastd --generate-key
2015-04-02 14:58:03 +0200 --- Info: Reading 32 bytes from /dev/random...
Secret: 8897599cc0298ee31cff6e83315f68207b0c95cf03678da4b4b8b5661c9d1568
Public: 5818e1e0c322c2f414ec13b4ab536ac0696d571eebb0327ba2ce8beb5d159244

Der geheime Schlüssel wird wie folgt in secret.conf eingetragen, als Kommentar ist hier auch der zugehörige public Key hinterlegt:

/etc/fastd/ggrz/secret.conf

secret "8897599cc0298ee31cff6e83315f68207b0c95cf03678da4b4b8b5661c9d1568";
# 
# (public: a8fe6ec0e7d7a1bb125a02c06b8caa8b06405752667e346e85d81ee48f358109)

Der öffentliche Schlüssel muß dann noch in die site.conf zum Erstellen der Gluon-Firmware eingetragen werden, damit sich die Knoten-Router mit dem Gateway verbinden können.

Die öffentlichen Schlüssel der Knoten werden im Git-Repository "peers-ffggrz"eingetragen. Obwohl wir derzeit auch alle Verbindungen von unbekannten Knoten zulassen, geben wir die Knoten trotzdem unserem Gateway bekannt. So könnten wir ohne großen Aufwand bei Bedarf nur noch Verbindungen bekannter Knoten akzeptieren. Deswegen laden wir nun dieses Repository auf das Gateway:

# cd /etc/fastd/ggrz
# git clone https://github.com/ffggrz/peers-ffggrz.git peers

Mit dem folgenden Script wird dafür gesorgt, daß die Peers aktuell bleiben:

/etc/fastd/update-fastd-peers

# fastd configuration directory
FASTD_CFG=/etc/fastd

# FF Communities
COMMUNITIES="ggrz"

function getCurrentVersion() {
# Get hash from latest revision
git log --format=format:%H -1
}

cd $FASTD_CFG/$COMMUNITIES/peers

# 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
  # Reload updated configuration
  echo "Reload fastd configuration."
  kill -HUP $(pidof fastd.$COMMUNITIES)
fi

Das Script muß ausführbar sein:

# chmod 750 /etc/fastd/update-fastd-peers

Nun muß dieses Script noch regelmäßig per Cron aufgerufen werden:

/etc/cron.d/update-fastd-peers

# Global variables
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# Update fastd peers every 15 minutes.
*/15 * * * * root /etc/fastd/update-fastd-peers > /dev/null

Zuletzt legen wir noch einen Symlink des Startscriptes für die FastD-Instanz der Community an, starten diese und nehmen sie in den Default-Runlevel auf:

# cd /etc/init.d
# ln -s fastd /etc/init.d/fastd.ggrz
# rc-service fastd.ggrz start
# rc-update add fastd.ggrz default

Exit-VPN

Zur Vermeidung der Störerhaftungs-Problematik erfolgt der Internet-Zugang ausschließlich per VPN über einen Server im Ausland oder den Server eines Vereines mit Provider-Status. In den meisten Fällen wird dabei ein Tunnel mit OpenVPN aufgebaut. Das installieren wir deswegen:

# echo "net-misc/openvpn iproute2 passwordsave" >> /etc/portage/package.use/Freifunk
# emerge -av openvpn

In /etc/conf.d/openvpn muß die Zeile PEER_DNS="yes" ersetzt werden durch PEER_DNS="no".

Oft erhält man vom VPN-Anbieter eine fertige Konfiguration, diese wird nach /etc/openvpn/.conf kopiert.

Für Mullvad sieht die Konfiguration z.B. so aus:

/etc/openvpn/mullvad.conf

client
remote se.mullvad.net 1300
##remote nl.mullvad.net 1300
cipher AES-256-CBC
dev exitVPN
dev-type tun
proto udp
tun-ipv6

resolv-retry infinite
route-noexec
persist-key
persist-tun
nobind ping 5
ping-restart 60
ping-timer-rem
explicit-exit-notify 2
script-security 2
remote-cert-tls server
route-delay 5
##tun-mtu 1500
##fragment 1300
##mssfix 1300
verb 4
comp-lzo

ca /etc/openvpn/mullvad/ca.crt
cert /etc/openvpn/mullvad/mullvad.crt
key /etc/openvpn/mullvad/mullvad.key

crl-verify /etc/openvpn/mullvad/crl.pem
# Limit range of possible TLS cipher-suites
tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-SEED-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SH

Das CA-Zertifikat von Mullvad, das eigene Zertifikat und der zugehörige private key sowie die CRL gehören also nach /etc/openvpn/mullvad.

Weiterhin benötigen wir Up- und Down-Scripte, in denen Routen und Regeln gesetzt werden:

/etc/openvpn/openvpn.mullvad-up.sh

#!/bin/sh
# ip rules for maintenance
ip rule add from $ifconfig_local table ggrz priority 9181

# ipv4 default route into appropriate rt_table
ip route replace 0.0.0.0/1 via $route_vpn_gateway dev $dev table ggrz
ip route replace 128.0.0.0/1 via $route_vpn_gateway dev $dev table ggrz

# ipv6 default route into appropriate rt_table
ip -6 route replace 2000::/3 dev $dev table ggrz

exit 0

/etc/openvpn/openvpn.mullvad-down.sh

#!/bin/sh
# ip rules for maintenance
ip rule del from $ifconfig_local table ggrz priority 9181

Zuletzt wird wieder ein Symlink für den Initscript erstellt, dieser gestartet und in den Default-Runlevel aufgenommen:

# nano -w /etc/openvpn/.conf
# cd /etc/init.d
# ln -s openvpn /etc/init.d/openvpn.
# rc-service openvpn. start
# rc-update add openvpn. default

IC-VPN

Installation

# echo "net-misc/bird" >> /etc/portage/package.keywords/Freifunk
# echo "net-misc/tinc" >> /etc/portage/package.keywords/Freifunk
# emerge -av bird tinc

tinc

Wesentliche Community-übergreifende Konfigurationen liegen in einem Git-Repository, welches wir klonen:

# mkdir /etc/tinc/icVPN
# git clone https://github.com/freifunk/icvpn /etc/tinc/icVPN/

Zur Absicherung des Tunnels wird ein Schlüsselpaar erzeugt:

# tincd -n icvpn -K

Bei den Vorgaben für den Speicherort wird der Verzeichnisname icvpn durch icVPN ersetzt. Also /etc/tinc/icVPN/rsa_key.priv und /etc/tinc/icVPN/rsa_key.pub.

Anschließend erstellen wir den Kopf der Konfiguration von tinc:

/etc/tinc/icVPN/tinc.conf.header:

Name = gera_greiz1
PrivateKeyFile = /etc/tinc/icVPN/rsa_key.priv
Mode = Switch
PingTimeout = 30
Port = 10781
Hostnames = yes
Interface = icVPN

Diesen Header kopieren wir in die eigentliche tinc-Konfiguration:

# cp /etc/tinc/icVPN/tinc.conf.header /etc/tinc/icVPN/tinc.conf

Nun benötigen wir Scripts zur Netzwerk-Konfiguration, welches tinc nach dem Verbindungsauf- und -abbau ausführt:

/etc/tinc/icVPN/tinc-up:

#!/bin/sh
# Interface aktivieren und IP-Adressen setzen
/bin/ip link set dev $INTERFACE up
/bin/ip addr add dev $INTERFACE 10.207.0.181/16 broadcast 10.207.255.255 scope link
/bin/ip -6 addr add dev $INTERFACE fec0::a:cf:0:b5/96 preferred_lft 0

# Device-Routen in den anderen Routing-Tabellen
/bin/ip -4 route add 10.207.0.0/16 proto kernel dev $INTERFACE src 10.207.0.181 table ggrz
/bin/ip -6 route add fec0::a:cf:0:0/96 proto kernel dev $INTERFACE table ggrz
/bin/ip -6 route add fe80::/64 proto kernel dev $INTERFACE table ggrz
/bin/ip -4 route add 10.207.0.0/16 proto kernel dev $INTERFACE src 10.207.0.181 table icvpn
/bin/ip -6 route add fec0::a:cf:0:0/96 proto kernel dev $INTERFACE table icvpn
/bin/ip -6 route add fe80::/64 proto kernel dev $INTERFACE table icvpn

### Default-Route zu vpn03 Berlin
##ip route replace 0.0.0.0/1 via 10.207.0.6 dev $INTERFACE table ggrz
##ip route replace 128.0.0.0/1 via 10.207.0.6 dev $INTERFACE table ggrz

# ip rules
/bin/ip rule add priority 31000 iif $INTERFACE table icvpn
/bin/ip rule add priority 31001 iif $INTERFACE unreachable
/bin/ip -6 rule add priority 31000 iif $INTERFACE table icvpn
/bin/ip -6 rule add priority 31001 iif $INTERFACE unreachable

/etc/tinc/icVPN/tinc-down:

#!/bin/sh
/bin/ip addr del dev $INTERFACE 10.207.0.181/16 broadcast 10.207.255.255
/bin/ip -6 addr del dev $INTERFACE fec0::a:cf:0:b5/96

# ip rules
/bin/ip rule del priority 31000 iif $INTERFACE table icvpn
/bin/ip rule del priority 31001 iif $INTERFACE unreachable
/bin/ip -6 rule del priority 31000 iif $INTERFACE table icvpn
/bin/ip -6 rule del priority 31001 iif $INTERFACE unreachable

# shutdown interface
/bin/ip link set dev $INTERFACE down

Beide Scripts müssen ausführbar sein:

# chmod 755 /etc/tinc/icVPN/tinc-*

Nun wird noch ein Script benötigt, welches die Konfiguration um die aktuellen Peer-Einträge ergänzt:

/etc/tinc/icVPN/update-tincd-icvpn:

#!/bin/bash
# Simple script for update of tinc IC-VPN hosts from git
# upstream and automated creation of tincd configuration.

# Tinc IC-VPN configuration directory
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 metanodes
  while read HOST; do
    # search correspondending host with address
    grep -iq '^Address' -- hosts/"$HOST" || continue
    # Add ConnectTo line for current host
    echo "ConnectTo = $HOST" >> $TINC_CONF
  done < metanodes

  # Reload updated configuration
  echo "Reload tincd configuration."
  kill -HUP $(pidof tincd)
fi

Auch dieses Script muß ausführbar sein:

# chmod 750 /etc/tinc/icVPN/update-tincd-icvpn

Um dann stündlich abgearbeitet zu werden, legen wir für cron folgende Datei an:

/etc/cron.d/update-tincd-icvpn

# Global variables
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# Update tincd IC-VPN peers every hour.
42 * * * * root /etc/tinc/icVPN/update-tincd-icvpn > /dev/null

Wichtig sind die richtigen Berechtigungen und ein Neustart von Cron:

# chmod 644 /etc/cron.d/update-tincd-icvpn
# /etc/init.d/vixie-cron restart

Nun müssen wir unser Gateway im Git hinterlegen und damit den anderen Gateways bekanntgeben. Dazu wird ein Push-Request auf https://github.com/freifunk/icvpn mit folgender Datei im Verzeichnis hosts erstellt:

gera_greiz1:

Address = gw1.freifunk-gera-greiz.de
Port = 10781

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEArLhMleQyfCgADO1vPEHK1hTJ8ZW/NljeiFsZcvTHCRKnnfF0AP1S
XfcviGlQCV3sfhXLdKABe0QZiLeHwbJY2R/n0PJxG/UxfscAKH+vRCa6qA4PqVI7
CLShMe+E/S66UPvYzYYwBpfLBFYlaMzSz+IhvhiRwoCWgk/0+YfPJt85mFSUHNxN
XGiBLJBSRGnGi9BFSw+GbrN86lmknV/fnL4uypFw94TJYF0Q7TexgP7aRtFSOciH
2tDCbzzJh7lmw4XE1Wtz7QWUP/R34zqlOELXlmoilbkTO71y4qlCeTHmaWDOG9/f
VScV3K/v1mrofNlK35GJzfcOp9ueijIbZwIDAQAB
-----END RSA PUBLIC KEY-----

Der public Key ist der Inhalt von /etc/tinc/icVPN/rsa_key.pub.

Zum Abschluß wird tinc gestartet:

# cd /etc/init.d
# ln -s tincd /etc/init.d/tincd.icVPN
# rc-service tincd.icVPN start
# rc-config add tincd.icVPN default

Nun können wir noch kontrollieren, ob alles wie gewünscht funktioniert. Das Interface:

# ifconfig icVPN
icVPN: flags=4163  mtu 1500
        inet 10.207.0.181  netmask 255.255.0.0  broadcast 10.207.255.255
        inet6 fe80::3001:89ff:fe38:e613  prefixlen 64  scopeid 0x20
        inet6 fec0::a:cf:0:b5  prefixlen 96  scopeid 0x40
        ether 32:01:89:38:e6:13  txqueuelen 500  (Ethernet)
        RX packets 49766  bytes 2922522 (2.7 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 749  bytes 50702 (49.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Erreichbarbeit anderer Peers, z.B. berlin2:

# ping -c2 10.207.0.6
PING 10.207.0.6 (10.207.0.6) 56(84) bytes of data.
64 bytes from 10.207.0.6: icmp_seq=1 ttl=64 time=1.53 ms
64 bytes from 10.207.0.6: icmp_seq=2 ttl=64 time=1.17 ms

--- 10.207.0.130 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.171/1.354/1.537/0.183 ms

# ping6 -c2 fec0::a:cf:0:6
PING fec0::a:cf:0:6(fec0::a:cf:0:6) 56 data bytes
64 bytes from fec0::a:cf:0:6: icmp_seq=1 ttl=64 time=1.10 ms
64 bytes from fec0::a:cf:0:6: icmp_seq=2 ttl=64 time=2.20 ms

--- fec0::a:cf:0:82 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 1.108/1.656/2.204/0.548 ms

bird

# mkdir /etc/bird
# mkdir /etc/bird/bird.d
# mkdir /etc/bird/bird6.d
# touch /etc/bird/bird.conf
# touch /etc/bird/bird6.conf
# ln -s bird/bird.conf /etc/bird.conf
# ln -s bird/bird6.conf /etc/bird6.conf

Nun erstellen bzw. editieren wir folgende Konfigurations-Dateien:

/etc/bird/local.conf:

# lokale Parameter (verschieden für jedes Gateway unserer Community)

router id 10.207.0.181;                 # Router-Id (entspricht üblicherweise v4-IP-Adresse)
define addr_ic = 10.207.0.181;          # eigene Gateway-Adresse im IC-VPN (Tinc-Tunnel)
define addr_br = 10.181.0.11;           # eigene Mesh-Bridge-IP
define addr_neighbor1 = 10.181.0.12;    # interner Peer 1
define addr_neighbor2 = 10.181.0.13;    # interner Peer 2

/etc/bird/bird.conf:

timeformat protocol iso long;

# lokale Konfigurationsdaten einbinden
include "/etc/bird/local.conf";

# AS
define ggrz_as = 65181; # AS Gera-Greiz

# Bird Routingtabellen
table ggrz;                                     # internes Mesh
table icvpn;                                    # ICVPN

# ROA
roa table roa_icvpn {
    include "/etc/bird/bird.d/icvpn-roa";
}

#####################
### F U N C T I O N S
#####################
#
#   alle Freifunk-Netze
function is_freifunk() {
    return net ~ [
        10.0.0.0/8+
    ];
}

#   alle DN42-Netze
function is_dn42() {
    return net ~ [
        172.20.0.0/16+,
        172.22.0.0/15+
    ];
}

#   alle Chaos-VPN-Netze
function is_chaosvpn() {
    return net ~ [
        172.31.0.0/16+
    ];
}

#   Mesh-Netze Gera-Greiz
function is_ggrz_self_net() {
    return net ~ [
        10.181.0.0/16+
    ];
}

#####################
### F I L T E R S
#####################
#
#   Import-Filter für alle ICVPN-Peers
filter ebgp_icvpn_import_filter {
    if is_ggrz_self_net() then reject;          # eigene Netze zurückweisen
    if is_freifunk() then accept;               # interne Freifunk-Netze erlauben
    if is_dn42() then accept;                   # DN42-Netze erlauben
    if is_chaosvpn() then accept;               # CaosVPN-Netze erlauben
#    if roa_check(roa_icvpn) = ROA_VALID then { # Test Route Origin Authorization für Freifunk-Netze
#        accept;
#    } else {
#        print "ROA check failed for ", net, " ASN ", bgp_path.last;
#    }
    reject;                                     # alles andere ablehnen
}

#####################
### P R O T O C O L S
#####################
#
#   Interfaces abfragen
protocol device {
    scan time 30;
};

#   Device-Routen in Bird-Table icvpn aufnehmen
protocol direct ggrz_subnets {
    interface 10.181.0.0/16;
    table icvpn;
};

#   Bird-Tabelle ICVPN nach GGRZ kopieren
protocol pipe icvpn2ggrz {
    import none;                                # nichts von ggrz nach icvpn importieren
    export all;                                 # alles von icvpn nach ggrz exportieren
    table icvpn;                                # Quelle: icvpn
    peer table ggrz;                            # Ziel: ggrz
};

#   Kernel-Routing-Table fürs Mesh-Netz Gera-Greiz
protocol kernel kernel_ggrz {
    scan time 30;
    import none;                                # nichts von Kernel in Bird importieren
    export filter {
        if is_ggrz_self_net() then              # eigene Netze nicht zum Kernel exportieren
            reject;
        krt_prefsrc = addr_br;
        accept;                                 # alles andere Bird-ggrz-Tabelle kommt in Kernel
    };
    table ggrz;                                 # Bird-Tabelle icvpn
    kernel table 181;                           # Kernel-Tabelle icvpn (s. etc/iproute2/rt_tables)
};

#   Kernel-Routing-Table fürs IC-VPN
protocol kernel kernel_icvpn {
    scan time 30;
    import none;                                # nichts von Kernel in Bird importieren
    export filter {
        if is_ggrz_self_net() then              # eigene Netze nicht zum Kernel exportieren
            reject;
        krt_prefsrc = addr_ic;
        accept;                                 # alles andere vom IC-VPN kommt in Kernel
    };
    table icvpn;                                # Bird-Tabelle icvpn
    kernel table 42;                            # Kernel-Tabelle icvpn (s. etc/iproute2/rt_tables)
};

#####################
### T E M P L A T E S
#####################
#
#   Template für iBGP (interne Peers)
template bgp ibgp {
    local addr_br as ggrz_as;           # als eigene IP die der Mesh-Bridge verwenden
    table icvpn;                        # Bird-Tabelle icvpn (korrekt???)
    import keep filtered on;            # gefilterte Routen nicht löschen,
                                        # sondern verstecken und nicht propagieren
                                        # können dadurch mit "show route filtered" angesehen werden
    import all;  # EXPERIMENT !!!!!
    export where source = RTS_BGP;      # alles, was über BGP hereingekommen ist, exportieren
    direct;                             # Nachbar ist direkt verbunden
    gateway direct;                     # Next Hop wird nicht durch Lookup der Routing Table ermittelt,
                                        # sondern der bgp_next_hop genommen (falls direkt erreichbar,
                                        # sonst die Adresse des Neighbor
};

#   Template für eBGP (Peers im IC-VPN)
template bgp peers {
    local addr_ic as ggrz_as;           # als eigene IP die des Tinc-Tunnels verwenden
    table icvpn;                        # Bird-Tabelle icvpn
    import keep filtered on;            # gefilterte Routen nicht löschen,
                                        # sondern verstecken und nicht propagieren
                                        # können dadurch mit "show route filtered" angesehen werden
    import filter ebgp_icvpn_import_filter;
    export filter {
        if is_ggrz_self_net() then {    # interne Netze Gera-Greiz
            accept;                     # exportieren
        }
        if source = RTS_BGP then {      # wenn über BGP gelernt und
            if is_freifunk() || is_dn42() || is_chaosvpn() then {
                                        # wenn es sich um ein Freifunk-, DN42- oder Chaos-Netz handelt
                accept;                 # exportieren
            }
        }
        reject;                         # alle anderen Routen nicht exportieren
    };
    direct;                             # Nachbar ist direkt verbunden
};

#####################
### P E E R I N G S
#####################
#
#   iBGP (interne Peers)
##protocol bgp neighbor1 from ibgp {
##    neighbor addr_neighbor1 as ggrz_as;
##};
##protocol bgp neighbor2 from ibgp {
##    neighbor addr_neighbor2 as ggrz_as;
##};

# eBGP IC-VPN Peers
# erzeugt mit /etc/cron.d/update-icvpn-meta
# ruft auf: /etc/icvpn/update-icvpn-meta
# Parameter BIRD_TEMPLATE muß dem Templatenamen (peers) entsprechen
include "/etc/bird/bird.d/icvpn";

/etc/bird/local6.conf

# lokale Parameter (verschieden für jedes Gateway unserer Community)

router id 10.207.0.183;                         # Router-Id (entspricht üblicherweise v4-IP-Adresse)
define addr_ic = fec0::a:cf:0:b5;               # eigene Gateway-Adresse im IC-VPN (Tinc-Tunnel)
define addr_br = fdb5:78b:64cc::11;             # eigene Mesh-Bridge-IP
define addr_neighbor1 = fdb5:78b:64cc::12;      # interner Peer 1
define addr_neighbor2 = fdb5:78b:64cc::13;      # interner Peer 2

/etc/bird/bird6.conf

timeformat protocol iso long;

# lokale Konfigurationsdaten einbinden
include "/etc/bird/local6.conf";

# AS
define ggrz_as = 65181; # AS Gera-Greiz

# Bird Routingtabellen
table ggrz;                                     # internes Mesh
table icvpn;                                    # ICVPN

# ROA
roa table roa_icvpn {
    include "/etc/bird/bird6.d/icvpn-roa";
}

#####################
### F U N C T I O N S
#####################
#
#   ULA Adressen
function is_ula() {
    return net ~ [
        fc00::/7{48,64}
    ];
}

# Mesh-Netze Gera-Greiz
function is_ggrz_self_net() {
    return net ~ [
        fdb5:078b:64cc::/48+
    ];
}

#####################
### F I L T E R S
#####################
#
#   Import-Filter für alle ICVPN-Peers
filter ebgp_icvpn_import_filter {
    if is_ggrz_self_net() then reject;          # eigene Netze zurückweisen
    if is_ula() then accept;                    # Netze mit ULA-Adressen erlauben
#    if roa_check(roa_icvpn) = ROA_VALID then { # Test Route Origin Authorization für Freifunk-Netze
#        accept;
#    } else {
#        print "ROA check failed for ", net, " ASN ", bgp_path.last;
#    }
    reject;                                     # alles andere ablehnen
}

#####################
### P R O T O C O L S
#####################
#
#   Interfaces abfragen
protocol device {
    scan time 30;
};

#   Device-Routen in Bird-Table icvpn aufnehmen
protocol direct ggrz_subnets {
    interface fdb5:078b:64cc::/48;
    table icvpn;
};

#   Bird-Tabelle ICVPN nach GGRZ kopieren
protocol pipe icvpn2ggrz {
    import none;                                # nichts von ggrz nach icvpn importieren
    export all;                                 # alles von icvpn nach ggrz exportieren
    table icvpn;                                # Quelle: icvpn
    peer table ggrz;                            # Ziel: ggrz
};

#   Kernel-Routing-Table fürs Mesh-Netz Gera-Greiz
protocol kernel kernel_ggrz {
    scan time 30;
    import none;                                # nichts von Kernel in Bird importieren
    export filter {
        if is_ggrz_self_net() then              # eigene Netze nicht zum Kernel exportieren
            reject;
        krt_prefsrc = addr_br;
        accept;                                 # alles andere Bird-ggrz-Tabelle kommt in Kernel
    };
    table ggrz;                                 # Bird-Tabelle icvpn
    kernel table 181;                           # Kernel-Tabelle icvpn (s. etc/iproute2/rt_tables)
};

#   Kernel-Routing-Table fürs IC-VPN
protocol kernel kernel_icvpn {
    scan time 30;
    import none;                                # nichts von Kernel in Bird importieren
    export filter {
        if is_ggrz_self_net() then              # eigene Netze nicht zum Kernel exportieren
            reject;
        krt_prefsrc = addr_ic;
        accept;                                 # alles andere vom IC-VPN kommt in Kernel
    };
    table icvpn;                                # Bird-Tabelle icvpn
    kernel table 42;                            # Kernel-Tabelle icvpn (s. etc/iproute2/rt_tables)
};

#####################
### T E M P L A T E S
#####################
#
#   Template für iBGP (interne Peers)
template bgp ibgp {
    local addr_br as ggrz_as;           # als eigene IP die der Mesh-Bridge verwenden
    table icvpn;                        # Bird-Tabelle icvpn (korrekt???)
    import keep filtered on;            # gefilterte Routen nicht löschen,
                                        # sondern verstecken und nicht propagieren
                                        # können dadurch mit "show route filtered" angesehen werden
    import all;  # EXPERIMENT !!!!!
    export where source = RTS_BGP;      # alles, was über BGP hereingekommen ist, exportieren
    direct;                             # Nachbar ist direkt verbunden
    gateway direct;                     # Next Hop wird nicht durch Lookup der Routing Table ermittelt,
                                        # sondern der bgp_next_hop genommen (falls direkt erreichbar,
                                        # sonst die Adresse des Neighbor
};

#   Template für eBGP (Peers im IC-VPN)
template bgp peers {
    local addr_ic as ggrz_as;           # als eigene IP die des Tinc-Tunnels verwenden
    table icvpn;                        # Bird-Tabelle icvpn
    import keep filtered on;            # gefilterte Routen nicht löschen,
                                        # sondern verstecken und nicht propagieren
                                        # können dadurch mit "show route filtered" angesehen werden
    import filter ebgp_icvpn_import_filter;
    export filter {
        if is_ggrz_self_net() then {    # interne Netze Gera-Greiz
            accept;                     # exportieren
        }
        if source = RTS_BGP then {      # wenn über BGP gelernt und
            if is_ula() then {          # wenn es sich um Netze mit ULA-Adressen handelt
                accept;                 # exportieren
            }
        }
        reject;                         # alle anderen Routen nicht exportieren
    };
    direct;                             # Nachbar ist direkt verbunden
};

#####################
### P E E R I N G S
#####################
#
#   iBGP (interne Peers)
##protocol bgp neighbor1 from ibgp {
##    neighbor addr_neighbor1 as ggrz_as;
##};
##protocol bgp neighbor2 from ibgp {
##    neighbor addr_neighbor2 as ggrz_as;
##};

# eBGP IC-VPN Peers
# erzeugt mit /etc/cron.d/update-icvpn-meta
# ruft auf: /etc/icvpn/update-icvpn-meta
# Parameter BIRD_TEMPLATE muß dem Templatenamen (peers) entsprechen
include "/etc/bird/bird6.d/icvpn";

Der Austauch der Konfirurationsparameter der einzelnen Communities geschieht wieder per Git. Es gibt ein Repository mit den Daten (icvpn-meta) und eines mit Scripts zur Erzeugung der Konfigurationen (icvpn-scripts). Für die Scripts wird python-yaml benötigt. Das installieren wir, anschließend clonen wir die beiden Repositories:

# emerge -av pyyaml
# mkdir /etc/icvpn
# cd /etc/icvpn
# git clone https://github.com/freifunk/icvpn-meta.git meta
# git clone https://github.com/freifunk/icvpn-scripts.git scripts

Unsere eigene Community müssen wir auch bekanntgeben. Dazu wird ein Push-Request auf https://github.com/freifunk/icvpn-meta mit folgender Datei erstellt:

gera-greiz:

tech-c:
  - Diese E-Mail-Adresse ist vor Spambots geschützt! Zur Anzeige muss JavaScript eingeschaltet sein.
asn: 65181
networks:
  ipv4:
    - 10.181.0.0/16
  ipv6:
    - fdb5:078b:64cc::/48
bgp:
  gera_greiz1:
    ipv4: 10.207.0.181
    ipv6: fec0::a:cf:0:b5
domains:
  - ffggrz
  - 181.10.in-addr.arpa
  - c.c.4.6.b.8.7.0.5.b.d.f.ip6.arpa
nameservers:
  - 10.181.0.11
  - fdb5:78b:64cc::11

Jetzt benötigen wir ein Script, welches das lokale Git-Repository aktualisiert und daraus die Konfigurationen für bird und dnsmasq erzeugt:

/etc/icvpn/update-icvpn-meta:

****!/bin/bash
# Simple script for update of IC-VPN meta information from git upstream
# and automated creation of derived bird and dnsmasq configuration.
# Note that scripts are not automatically updated for security reasons.

# Local icvpn-meta and icvpn-script clones
ICVPN_META=/etc/icvpn/meta
ICVPN_SCRIPTS=/etc/icvpn/scripts

# Name of own community (as used in icvpn-meta repository)
OWN_COMMUNITY=gera-greiz

# Bird peer configuration (IPv4 and IPv6)
BIRD_CONF=/etc/bird/bird.d/icvpn
BIRD6_CONF=/etc/bird/bird6.d/icvpn

# Bird roa configuration (IPv4 and IPv6)
BIRD_ROA=/etc/bird/bird.d/icvpn-roa
BIRD6_ROA=/etc/bird/bird6.d/icvpn-roa
BIRD_ROA_LEN=24
BIRD6_ROA_LEN=64

# Bird templates used for peers (IPv4 and IPv6)
BIRD_TEMPLATE=peers
BIRD6_TEMPLATE=peers

# Dnsmasq configuration
DNSMASQ_CONF=/etc/dnsmasq.d/icvpn

function getCurrentVersion() {
  # Get hash from latest revision
  git log --format=format:%H -1
}

cd $ICVPN_META

# 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)

# Check whether content of icvpn-meta has changed
if [ $GIT_REVISION != $GIT_NEW_REVISION ]
then
  cd $ICVPN_SCRIPTS
  # Create bird configuration
  ./mkbgp -4 -f bird -s $ICVPN_META -d $BIRD_TEMPLATE -x $OWN_COMMUNITY > $BIRD_CONF
  ./mkbgp -6 -f bird -s $ICVPN_META -d $BIRD6_TEMPLATE -x $OWN_COMMUNITY > $BIRD6_CONF
  ./mkroa -4 -f bird -s $ICVPN_META -m $BIRD_ROA_LEN -x $OWN_COMMUNITY > $BIRD_ROA
  ./mkroa -6 -f bird -s $ICVPN_META -m $BIRD6_ROA_LEN -x $OWN_COMMUNITY > $BIRD6_ROA
  # Restrict access
  ##chown bird.bird $BIRD_CONF $BIRD6_CONF $BIRD_ROA $BIRD6_ROA
  chmod 640 $BIRD_CONF $BIRD6_CONF $BIRD_ROA $BIRD6_ROA

  # Create dnsmasq configuration
  ./mkdns -f dnsmasq -s $ICVPN_META -x OWN_COMMUNITY > $DNSMASQ_CONF

  # Version has changed we need to update
  echo "Reload bird configuration."
  kill -HUP $(pidof bird)
  kill -HUP $(pidof bird6)
  echo "Reload dnsmasq configuration."
  /sbin/rc-service dnsmasq restart
fi

Die Programme zum Erstellen der Bird- und Dnsmasq-Konfiguration benötigen ein Python 2.x, kein 3.x. Ansonsten bleiben beim Aufruf per Cron (warum auch immer?) die erzeugten Konfigurationen leer. Deswegen wird Python 2.7 als System-Python eingestellt (mittels "eselect python set x").

Das Script sollte ausführbar sein:

# chmod 750 /etc/icvpn/update-icvpn-meta

Um dann stündlich abgearbeitet zu werden, legen wir für cron folgende Datei an:

/etc/cron.d/update-icvpn-meta

# Global variables
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# Update tincd IC-VPN peers every hour.
37 * * * * root /etc/icvpn/update-icvpn-meta > /dev/null

Die Cron-Datei muß die richtigen Rechte bekommen und Cron neu gestartet werden:

# chmod 644 /etc/cron.d/update-icvpn-meta
# /etc/init.d/vixie-cron restart

ZumSchluß wird bird gestartet und in den Default-Runlevel aufgenommen:

# /etc/init.d/bird start
# /etc/init.d/bird6 start
# rc-update add bird default
# rc-update add bird6 default

Zur Kontrolle werden die Routing-Tabellen angezeigt, diese müssen jede Menge Einträge enthalten:

# ip route show table icvpn
[...]
# ip route show table ggrz
[...]
# ip -6 route show table icvpn
[...]
# ip -6 route show table ggrz
[...]

Ein paar weitere Tests:

Eine Schwierigkeit ist die Ermittlung eines möglichen Ping-Ziels im ICVPN. Am wahrsccheinlichsten ist es, daß man einen der DNS-Server anderer Communities erreichen kann. Diese kann man wie folgt auflisten:

# cat /etc/dnsmasq.d/icvpn

In den folgenden Beispielen nutzen wir die 10.56.0.7.

Diese sollte man dann von einem Client aus unserem Freifunk-Netz anpingen können. Für einen Test direkt vom Gateway muß man mit einer "ip rule" noch dafür sorgen, daß wie für die Clients die Routing-Table "ggrz" verwendet wird:

# ip rule add to 10.56.0.7 table ggrz priority 32000
# ping 10.56.0.7
# ip rule del to 10.56.0.7 table ggrz priority 32000

Das korrekte Routing kann auch schneller wir folgt getestet werden:

# ip route get to 10.56.0.7 from 10.181.0.22 iif ggrzBAT
10.56.0.7 from 10.181.0.22 via 10.207.0.56 dev icVPN
    cache  iif ggrzBAT

Backbone Rheinland

Gre-Tunnel

Der Freifunk Rheinland e.V. ermöglicht uns den Exit ins Internet. Dazu werden GRE-Tunnel zu den dortigen Gateways erstellt. Die Konfiguration in /etc/conf.d/net:

###############################
# Tunnel
###############################

# ffrl-a-ak-ber: Backbone Rheinland (A), Berlin
# ffrl-a-ix-dus: Backbone Rheinland (A), Düsseldorf
# ffrl-b-ak-ber: Backbone Rheinland (B), Berlin
# ffrl-b-ix-dus: Backbone Rheinland (B), Düsseldorf
#
iptunnel_ffrl_a_ak_ber="mode gre local 148.251.158.22 remote 185.66.195.0 ttl 64"
config_ffrl_a_ak_ber="100.64.3.167 peer 100.64.3.166
                      185.66.194.27/32
                      2a03:2260:0:1dd::2/64"
mtu_ffrl_a_ak_ber="1400"
#
iptunnel_ffrl_a_ix_dus="mode gre local 148.251.158.22 remote 185.66.193.0 ttl 64"
config_ffrl_a_ix_dus="100.64.3.169 peer 100.64.3.168
                      185.66.194.27/32
                      2a03:2260:0:1de::2/64"
mtu_ffrl_a_ix_dus="1400"
#
iptunnel_ffrl_b_ak_ber="mode gre local 148.251.158.22 remote 185.66.195.1 ttl 64"
config_ffrl_b_ak_ber="100.64.3.171 peer 100.64.3.170
                      185.66.194.27/32
                      2a03:2260:0:1df::2/64"
mtu_ffrl_b_ak_ber="1400"
#
iptunnel_ffrl_b_ix_dus="mode gre local 148.251.158.22 remote 185.66.193.1 ttl 64"
config_ffrl_b_ix_dus="100.64.3.173 peer 100.64.3.172
                      185.66.194.27/32
                      2a03:2260:0:1e0::2/64"
mtu_ffrl_b_ix_dus="1400"

Danach werden die Symlinks der Init-Scripts der einzelnen Interfaces erstellt, die Tunnel gestartet und in den Default-Runlevel aufgenommen:

# cd /etc/init.d
# ln -s net.lo net.ffrl-a-ak-ber
# ln -s net.lo net.ffrl-a-ix-dus
# ln -s net.lo net.ffrl-b-ak-ber
# ln -s net.lo net.ffrl-b-ix-dus
# rc-service net.ffrl-a-ak-ber start
# rc-service net.ffrl-a-ix-dus start
# rc-service net.ffrl-b-ak-ber start
# rc-service net.ffrl-b-ix-dus start
# rc-update add net.ffrl-a-ak-ber default
# rc-update add net.ffrl-a-ix-dus default
# rc-update add net.ffrl-b-ak-ber default
# rc-update add net.ffrl-b-ix-dus default

Firewall

Layer 3

Primär dient die Firewall an dieser Stelle dazu, die Pakete aus der Freifunk-Mesh Richtung Exit-VPN zu natten und zu markieren, um sie an die spezielle Routing-Tabelle (181, ggrz) zu übergeben. Dazu legen wir die folgenden Regeln an:

IPv4:

# iptables -t filter -A INPUT -i eth0 -p tcp --dport 179 -j REJECT
# iptables -t filter -A INPUT -i exitVPN -p tcp --dport 179 -j REJECT
# iptables -t filter -A INPUT -i ggrzBR -p tcp --dport 179 -j REJECT

# iptables -A FORWARD -i ggrzBR -o eth0 -p tcp --dport 587 -m connlimit --connlimit-above 5 -j REJECT

# iptables -t mangle -A PREROUTING -i ggrzBR -j MARK --set-xmark 0x1/0xffffffff
# iptables -t mangle -A PREROUTING -i ggrzBR -p tcp --dport 587 -j MARK --set-mark 0x0/0xffffffff

# iptables -t nat -A POSTROUTING -o exitVPN -j MASQUERADE
# iptables -t nat -A POSTROUTING -o eth0 -p tcp --dport 587 -j MASQUERADE

# iptables -t nat -N ffrl-nat
# iptables -t nat -A ffrl-nat -s 100.64.3.166/31 -o ffrl+ -j RETURN
# iptables -t nat -A ffrl-nat -s 100.64.3.168/31 -o ffrl+ -j RETURN
# iptables -t nat -A ffrl-nat -s 100.64.3.170/31 -o ffrl+ -j RETURN
# iptables -t nat -A ffrl-nat -s 100.64.3.172/31 -o ffrl+ -j RETURN
# iptables -t nat -A ffrl-nat -s 10.181.0.0/16 -o ffrl+ -j SNAT --to-source 185.66.194.27
# iptables -t nat -A POSTROUTING -s 10.181.0.0/16 -o ffrl+ -j ffrl-nat

# iptables -A FORWARD -i ggrzBR -o ffrl+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# iptables -A FORWARD -i ffrl+ -o ggrzBR -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# iptables -t raw -A PREROUTING -d 5.196.74.176/32 -i ggrzBR -p udp -m multiport --dports 10181,20181 -m comment --comment "drop VPN from mesh" -j DROP
# iptables -t raw -A PREROUTING -d 193.28.153.11/32 -i ggrzBR -p udp -m multiport --dports 10181,20181 -m comment --comment "drop VPN from mesh" -j DROP
# iptables -t raw -A PREROUTING -d 136.243.179.182/32 -i ggrzBR -p udp -m multiport --dports 10181,20181 -m comment --comment "drop VPN from mesh" -j DROP

IPv6:

# ip6tables -t filter -A INPUT -i eth0 -p tcp --dport 179 -j REJECT
# ip6tables -t filter -A INPUT -i exitVPN -p tcp --dport 179 -j REJECT
# ip6tables -t filter -A INPUT -i ggrzBR -p tcp --dport 179 -j REJECT

# ip6tables -t nat -A POSTROUTING -o exitVPN -j MASQUERADE

# ip6tables -A FORWARD -i ggrzBR -o ffrl+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# ip6tables -A FORWARD -i ffrl+ -o ggrzBR -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# ip6tables -t raw -A PREROUTING -d 2a01:4f8:172:19ea:201::182/128 -i ggrzBR -p udp -m multiport --dports 10181,20181 -m comment --comment "drop VPN from mesh" -j DROP
# ip6tables -t raw -A PREROUTING -d 2a02:ff80:1003:2::2/128 -i ggrzBR -p udp -m multiport --dports 10181,20181 -m comment --comment "drop VPN from mesh" -j DROP
# ip6tables -t raw -A PREROUTING -d 2001:41d0:e:8b0::1/128 -i ggrzBR -p udp -m multiport --dports 10181,20181 -m comment --comment "drop VPN from mesh" -j DROP

Die Zeilen mit --dport 587 bewirken, daß der SMTP-Submission-Port nicht über das VPN geroutet wird. Das ist erforderlich, da die meisten VPN-Anbieter zur Spam-Verhinderung die Ports 25, 465 und 587 sperren.

Im Verzeichnis /etc/conf.d wird in den Dateien iptables und ip6tables die Zeile SAVE_ON_STOP="yes" geändert in SAVE_ON_STOP="no". Anschließend werden die angelegten Regeln gespeichert und iptables in den Runlevel default aufgenommen:

# rc-service iptables save
# rc-service iptables start
# rc-update add iptables default
# rc-service ip6tables save
# rc-service ip6tables start
# rc-update add ip6tables default

Layer 2

B.A.T.M.A.N. verfügt über die sinnvolle Funktionatität, im Server-Mode DHCP-Broadcasts von Clients nicht weiterzuleiten. Diese werden damit nur vom lokalen DHCP-Server beantwortet, welcher den Clients sich selbst als Default Gateway und DNS-Server nennt. Für IPv6 fehlt in B.A.T.M.A.N. eine analoge Funktionalität für die Router Advertisements. Damit sehen die Clients alle Gateways einer Mesh-Wolke als mögliches Default Gateway und nicht das nächste (wo der FastD-Tunnel des Knotens endet. Um das zu verhindern, wird "ebtables" genutzt:

# emerge -av ebtables

Analog zu iptables wird in /etc/conf.d/ebtables die Zeile SAVE_ON_STOP="yes" geändert in SAVE_ON_STOP="no". Anschließend wird die Konfiguration erzeugt, gespeicher und in den Default Runlevel aufgenommen:

# ebtables -A FORWARD -p IPv6 -i ggrzBAT --ip6-proto ipv6-icmp --ip6-icmp-type router-advertisement -j DROP
# rc-service ebtables save
# rc-service ebtables start
# rc-update add ebtables default

Dienste

NTP

Bei Verschlüsselung, fürs Logging u.a. ist eine genaue Zeit wichtig. Dafür wird NTP installiert:

# emerge -av ntp

Die Konfiguration wird dann wie folgt angepaßt:

/etc/ntp.conf:

# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help

driftfile /var/lib/ntp/ntp.drift

# listen at localhost and mesh only
interface ignore wildcard
interface listen 127.0.0.1
interface listen ::1
interface listen 10.181.0.11
interface listen fdb5:78b:64cc::11

# only use local time, synced with kvm host time
tos orphan 1

# By default, exchange time with everybody, but don't allow configuration.
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery

# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1

Ohne die Angabe von "server", stattdessen mit "tos orphan 1" werden keine externen Zeitserver abgefragt, sondern nur die Systemzeit an andere NTP-Clients verteilt. Das ist sinnvoll, da dieses Gateway in einer virtuellen Maschine auf einem KVM-Host läuft. Dieser Host gibt seine per NTP aktuell gehaltene Zeit an die VMs weiter.

Damit der NTP-Daemon erst startet, wenn das Mesh-Interface vorhanden ist (daran soll er sich ja binden), wird folg. ergänzt:

/etc/conf.d/ntpd:

# soll sich an die Mesh-Interfaces binden,
# die sollten also da sein
rc_need="net.ggrzBAT"

Abschließend wird der Daemon gestartet:

# /etc/init.d/ntpd start
# rc-update add ntpd default

Dnsmasq

Als Server für DNS und DHCP verwenden wir Dnsmasq:

# echo "net-dns/dnsmasq auth-dns dhcp-tools" >> /etc/portage/package.use/Freifunk
# emerge -av dnsmasq

Die Konfiguration sollte dann so aussehen

/etc/dnsmasq.conf:

### Allgemeines
conf-dir=/etc/dnsmasq.d
bogus-priv
no-resolv
no-poll
expand-hosts
domain-needed
cache-size=4096
strict-order
interface=ggrzBAT
bind-interfaces

### DNS

# Hetzner DNS Server (später evtl. andere nehmen)
server=213.133.100.100
server=213.133.99.99
server=213.133.98.98

local=/ffggrz/
domain=ffggrz

### DHCP / RA

dhcp-authoritative
#log-dhcp

dhcp-range=10.181.1.1,10.181.2.254,3m
dhcp-option=option:router,10.181.0.11
dhcp-option=option:dns-server,10.181.0.11,8.8.8.8
dhcp-option=option:ntp-server,10.181.0.11
dhcp-option=option:domain-search,ffggrz
### MTU 1280
##dhcp-option-force=26,1280

dhcp-range=set:ggrzv6,::,constructor:ggrzBAT,slaac,ra-only,3m
dhcp-option=tag:ffsv6,option6:dns-server,[fdb5:78b:64cc::11]
dhcp-option=tag:ffsv6,option6:ntp-server,[fdb5:78b:64cc::11]
dhcp-option=tag:ffsv6,option6:domain-search,ffggrz

enable-ra
##ra-param=ggrzBAT,low,0,0
ra-param=ggrzBAT,high,60,1200

Falls das Verzeichnis /etc/dnsmasq.d noch nicht existiert, wird dieses jetzt angelegt:

# mkdir /etc/dnsmasq.d

Auch Dnsmasq soll erst starten, wenn das Mesh-Interface vorhanden ist:

/etc/conf.d/dnsmasq:

# soll sich an die Mesh-Interfaces binden,
# die sollten also da sein
rc_need="net.ggrzBAT"

Nun wird Dnsmasq noch gestartet und in den Default Runlevel aufgenommen:

# /etc/init.d/dnsmasq start
# rc-update add dnsmasq default

Karte, Listen

Backend

Zur Darstellung aktiver Nodes und Gateway in einer Karte bzw. Liste erfolgt die Sammlung und Aufbereitung der nötigen Daten mittels A.L.F.R.E.D.:

# emerge -av alfred

A.L.F.R.E.D. wird das zu nutzende Interface mitgeteilt, außerdem soll der Start erst nach dem Mesh-Interface erfolgen:

/etc/conf.d/alfred:

# B.A.T.M.A.N. interface
ALFRED_IFCBAT="ggrzBAT"

# soll sich an die Mesh-Interfaces binden,
# die sollten also da sein
rc_need="net.ggrzBAT"

Nun wird A.L.F.R.E.D. noch gestartet und in den Default Runlevel aufgenommen:

# /etc/init.d/alfred start
# rc-update add alfred default

Das Auslesen der Daten und die Übergabe an den Mapviewer erfolgt über das ffmap-Backend:

# emerge -av ffmap-backend

Dieses wird dann mittels Cron-Job minütlich abgearbeitet (s. /etc/cron.d/ffmap-backend). Die erzeugten Daten landen in /var/www/localhost/htdocs/data und werden dort vom Webserver (Nginx) für das Frontend zur Verfügung gestellt.

Frontend

Als Frontend verwenden wir den Meshviewer. Dieser wird nicht auf dem Gateway, sondern auf den Server für das Webportal installiert. Die folgenden Schritte werden also dort durchgeführt.

# cd /root
# git clone https://github.com/tcatm/meshviewer.git
# cd meshviewer
# npm install
# npm install bower grunt-cli
# node_modules/.bin/bower --allow-root install
# node_modules/.bin/grunt

Anschließend erfolgt die Konfiguration. Dazu wird die Beispieldatei  config.json.example nach build/config.json kopiert und angepaßt.

Details
Geschrieben von: Jörg
Kategorie: Gateways
Veröffentlicht: 23. November 2021
Zuletzt aktualisiert: 26. November 2018
RSS

Freifunk Community Feeds

  • ffradio107: Total übersteuert
    29. März 2023
  • Freifunk-Treffen am 13. März 2023 – vor Ort und virtuell
    12. März 2023
  • Firmware Update 2022.1.3.0
    10. März 2023
  • Transparenter Proxy trifft VPN trifft SSH
    09. März 2023
  • Netzmodernisierung
    09. März 2023
  • WireGuard auf OpenWrt
    09. März 2023
  • Mitgliederversammlung 2023
    08. März 2023
  • Neue Beta 0.16.4 bringt Bugfixes
    07. März 2023
  • Neue Firmware
    02. März 2023
  • Einladung zur Mitgliederversammlung des Freifunk Mainz e.V. am Donnerstag, 23.03.2023 (19 Uhr)
    01. März 2023

Veranstaltungen / Ereignisse

Mi März 29 @18:00 - 22:00
namespace geöffnet
Mi Apr. 05 @18:00 - 22:00
namespace geöffnet
  • Willkommen
  • Impressum
  • Kontakt
© 2023 Bürgernetz Gera-Greiz e.V.