Gateway-Server

Hier findest du die Anleitung, nach der wir unsere Gateway-Server aufsetzen. Diese Anleitung richtet sich nur an Mitarbeiter des Freifunk Ingolstadt Projekts, die nach Absprache mit dem Team einen Gateway-Server aufsetzen möchten. Trotzdem stellen wir die Anleitung aus transparenzgründen online.

Voraussetzungen

Diese Anleitung bezieht sich auf CentOS 7.1. Dementsprechend passen Befehle und Konfigurationsdateien nur für eine entsprechende Distribution. Folgende weitergehende Vorraussetzungen müssen erfüllt sein, um einen Gateway-Server aufzusetzen:

Repositories

Folgende zusätzliche Repositories werden benötigt:

Pakete

Folgende Pakete müssen installiert werden:

# yum install git dhcp radvd bind bind-utils fastd-multiproc batman-adv bird bird6 ntp alfred batctl iptables-services vnstat python34 redhat-lsb-core

Folgende Pakete dürfen nicht installiert sein, oder zumindest sollten die dazugehörigen Services deaktiviert sein:

# yum erase NetworkManager firewalld syslog-ng rsyslog

GIT Repositories

Folgende GIT-Repositories müssen nun nach /var/freifunk ausgecheckt werden:

Konfiguration

Sysctl

Sollte dein Serveranbieter unter /etc/sysctl.d bereits Sysctls hinterlegt haben, solltest du diese nun löschen. Danach legst du die Datei /etc/sysctl.d/10-freifunk.conf an:

# Source route verification
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

# Enable packet forwarding
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1

# Configure ipv6 features
net.ipv6.conf.default.autoconf=0
net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.default.accept_ra_defrtr=0
net.ipv6.conf.default.accept_ra_rtr_pref=0
net.ipv6.conf.default.accept_ra_pinfo=0
net.ipv6.conf.default.accept_redirects = 1

net.ipv6.conf.all.autoconf=0
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.all.accept_ra_defrtr=0
net.ipv6.conf.all.accept_ra_rtr_pref=0
net.ipv6.conf.all.accept_ra_pinfo=0
net.ipv6.conf.all.accept_redirects = 1

GRE Tunnel

Für die Verbindung mit Freifunk Rheinland wird GRE eingesetzt. Du musst also für jeden Endpunkt der für deinen Server angemeldet wurde, zwei entsprechende Dateien unter /etc/systemd/network/ anlegen. Sollte der Pfad nicht existieren, einfach mit mkdir -p anlegen

Beispiel: /etc/systemd/network/ffrl-tun-ber.netdev

[NetDev]
Name=ffrl-tun-ber
Kind=gre
MTUBytes=1400

[Tunnel]
Local=<IPv4 FFIN Endpoint>
Remote=<IPv4 FFRL Endpoint>
TTL=64

Beispiel: /etc/systemd/network/ffrl-tun-ber.network

[Match]
Name=ffrl-tun-ber

[Network]
Address=<IPv6 Tunnel>/<Prefix-Size>

[Address]
Address=<IPv4 FFIN Tunnel>/31
Peer=<IPv4 FFRL Tunnel>/31

Erklärung:

Loopback interface

Dem Loopback-Interface muss noch die öffentliche IP gegeben werden, die wir für dein Gateway vom FFRL erhalten haben. Dazu bearbeitest du die Datei /etc/systemd/network/lo.network

[Match]
Name=lo

[Network]
DHCP=no

[Address]
Address=127.0.0.1/8

[Address]
Address=<FFRL Gateway IP>/32

Erklärung:

BATMAN Interface

Die Konfiguration des BATMAN-Interfaces geschiet in der /etc/systemd/system/batman-adv.service:

[Unit]
Description=B.A.T.M.A.N. Advanced
Wants=network-online.target
After=network-online.target
Before=dhcpd.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/batctl if add ffin-tap-gw1
ExecStartPost=/usr/sbin/ip link set dev bat0 address 00:00:00:00:00:0<GW-Nummer + 1>
ExecStartPost=/usr/sbin/ip link set dev bat0 up
ExecStartPost=/usr/sbin/ip address add 10.10.0.<GW-Nummer + 1>/16 dev bat0
ExecStartPost=/usr/sbin/ip -6 address add 2a03:2260:116::<GW-Nummer + 1>/64 dev bat0
ExecStartPost=/usr/sbin/batctl gw server 1024mbit/1024mbit
ExecStop=/usr/sbin/ip address del 10.10.0.<GW-Nummer + 1>/16 dev bat0
ExecStop=/usr/sbin/ip -6 address del 2a03:2260:116::<GW-Nummer + 1>/64 dev bat0
ExecStopPost=/usr/bin/batctl if del ffin-tap-gw1

[Install]
WantedBy=multi-user.target

Erklärung:

DHCP-Server

Die Konfiguration des DHCP-Servers findet in der Datei /etc/dhcp/dhcpd.conf statt:

default-lease-time 120;
max-lease-time 600;

authoritative;

log-facility local6;

subnet 10.10.0.0 netmask 255.255.0.0 {
    range 10.10.<Start>.1 10.10.<Ende>.254;

    option routers 10.10.0.<GW-Nummer + 1>;
    option domain-name-servers 10.10.0.<GW-Nummer + 1>;
    option interface-mtu 1280;
}

Erklärung:

RADVD

Die Konfiguration von RADVD findet in der Konfigurationsdatei /etc/radvd.conf statt:

interface bat0
{
    AdvSendAdvert on;
    IgnoreIfMissing on;

    AdvManagedFlag off;
    AdvOtherConfigFlag off;
    AdvLinkMTU 1280;

    prefix 2a03:2260:116::/64
    {
        AdvOnLink on;
        AdvAutonomous on;
        AdvRouterAddr on;
    };

    RDNSS 2a03:2260:116::<GW-Nummer + 1>
    {
    };
};

Erklärung:

BIND

Die BIND config liegt unter /etc/named.conf:

options {
    listen-on port 53 { 127.0.0.1; 10.10.0.<GW-Nummer + 1>; };
    listen-on-v6 port 53 { ::1; 2a03:2260:116::<GW-Nummer + 1>; };
    interface-interval 1;
    directory   "/var/named";
    dump-file   "/var/named/data/cache_dump.db";
    statistics-file "/var/named/data/named_stats.txt";
    memstatistics-file "/var/named/data/named_mem_stats.txt";
    allow-query     { localnets; localhost; };

    recursion yes;
    allow-recursion { localnets; localhost; };

    dnssec-enable yes;
    dnssec-validation yes;

    /* Path to ISC DLV key */
    bindkeys-file "/etc/named.iscdlv.key";

    managed-keys-directory "/var/named/dynamic";

    pid-file "/run/named/named.pid";
    session-keyfile "/run/named/session.key";
};

logging {
    channel null { null; };
    category default { null; };
};

zone "." IN {
    type hint;
    file "named.ca";
};

zone "ffin" {
        type master;
        file "/var/freifunk/ffin-gateway/dns/db.ffin";
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

Erklärung:

FASTD

Die FASTD-Konfiguration gliedert sich in 2 Teile einen Teil, der für alle FASTD-Instanzen gleich ist, und ein Teil, der sich in jeder Instanz unterscheidet. Mehrere Instanzen von FASTD können wir deshalb starten, weil wir ein gepatchtes FASTD nutzen, das die Socket-Option SO_REUSEADDR sowie SO_REUSEPORT nutzt.

Folgende Ordnerstruktur muss als erstes angelegt werden:

# mkdir -p /etc/fastd/mesh/peers

Außerdem muss für jede FASTD-Instanz ein Ordner erzeugt werden (Beispiel für 8 Instanzen). Als Faustregel gilt: Je Kern des GWs eine Instanz von fastd:

# mkdir /etc/fastd/mesh/{01..08}

Danach legst du die Golabe Konfigurationsdatei /etc/fastd/mesh/fastd-master.conf an:

# Bind to a fixed address and port :31416 interface "eth0";
bind <IPv4-Adresse>:31416 interface "eth0";
bind [<IPv6-Adresse>]:31416 interface "eth0";

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

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

# Set the methods
method "salsa2012+umac";

# Secret key generated by `fastd --generate-key`
secret "<secret hier einfügen>";

# Set peers directory
include peers from "peers/";

# Allow any connection but blacklist
on verify "/bin/bash /var/freifunk/ffin-gateway/blacklist.sh";

on up "
    ip link set dev $INTERFACE up
    batctl if add $INTERFACE
    ifup bat0
    batctl gw server 1024MBit/1024MBit
    batctl bl 1
";

Erklärung:

Dann muss für jede Instanz eine Konfiguration unter /etc/fastd/mesh/<Instanz>/fastd.conf. Für faule: find /etc/fastd/mesh -mindepth 1 ! -name peers -type d -exec touch {}/fastd.conf \; -exec echo Created empty fastd config in {} \;

include "../fastd-master.conf";

# Set the interface name
interface "mesh-ffin-<Instanz>";

# Status Socket
status socket "/run/fastd/mesh-ffin-<Instanz>.sock";

Erklärung:

Als letztes muss für FASTD noch ein Systemd-Service unter /etc/systemd/system/fastd\@.service erstellt werden:

[Unit]
Description=Fast and Secure Tunnelling Daemon (connection %I)
After=network.target

[Service]
Type=notify
RuntimeDirectory=fastd
RuntimeDirectoryMode=0777
ExecStart=/usr/bin/fastd --syslog-level info --syslog-ident fastd@%I -c /etc/fastd/%I/fastd.conf
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target 

BATMAN-ADV Kernelmodul

Das Kernelmodul wurde bereits im Abschnitt "Pakete" installiert, deshalb muss es nur noch (automatisch) geladen werden:

# modprobe batman-adv

Dann in die Datei /etc/moules-load.d/freifunk.conf folgendes schreiben:

batman-adv

BIRD

Die Konfiguration von BIRD findet in der Datei /etc/bird.conf statt:

log syslog { remote, warning, error, auth, fatal, bug };
#debug protocols all;
router id 10.10.0.<GW-Nummer + 1>;

protocol direct {
        interface "*";
};

filter not_local {
        if net ~ <IP des Servers>/32 then reject;
        else accept;
};

protocol kernel {
        device routes;
        import all;
        export filter not_local;
        kernel table 42;
};

protocol device {
        scan time 8;
};

function is_default() {
        return (net ~ [0.0.0.0/0]);
};

filter hostroute {
        if net ~ <FFRL Gateway IPv4>/32 then accept;
        reject;
};

template bgp uplink {
        local as 65252;
        import where is_default();
        export filter hostroute;
        next hop self;
        multihop 64;
        default bgp_local_pref 200;
};

protocol bgp ffrl_ber from uplink {
        source address <IPv4 FFIN Tunnel>;
        neighbor <IPv4 FFRL Tunnel> as 201701;
};

Erklärung:

Natürlich muss entsprechend für jeden FFRL-Endpunkt eine weitere protocol-Sektion in die Datei geschrieben werden.

BIRD6

Die Konfiguration von BIRD6 findet in der Datei /etc/bird6.conf statt:

log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
debug protocols all;
router id 10.10.0.<GW-Nummer>;

protocol direct {
    interface "*";
}

filter not_local {
    if net ~ <IPv6 des Servers>/64 then reject;
    else accept;
};


protocol kernel {
    device routes;
    import all;
    export filter not_local;
    kernel table 42; # ip table to use
}

protocol device {
    scan time 10;
}

function is_default() {
    return (net ~ [::/0]);
}

filter hostroute {
    if net ~ <FFRL Gateway IPv6>/48 then accept;
    reject;
}

template bgp uplink {
    local as 65252;
    import where is_default();
    export filter hostroute;
    gateway recursive;
}

protocol bgp ffrl_ber from uplink {
    source address <IPv6 FFIN Tunnel>;
    neighbor <IPv6 FFRL Tunnel> as 201701;
}

Erklärung:

IP-Tables

Als erstes müssen die IP-Tables Services konfiguriert werden. Dies geschiet unter `/etc/sysconfig/iptables-config´:

IPTABLES_SAVE_ON_STOP="yes"
IPTABLES_SAVE_ON_RESTART="yes"

Nun können folgende Regeln unter /etc/sysconfig/iptables angelegt werden:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
# Regeln zum markieren eingehender Pakete
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o tun-+ -j TCPMSS --set-mss 1280
-A PREROUTING -i bat0 -j MARK --set-xmark 0x1/0xffffffff
-A OUTPUT -o eth0 -p udp --dport 53 -j MARK --set-xmark 0x1/0xffffffff
-A OUTPUT -o eth0 -p tcp --dport 53 -j MARK --set-xmark 0x1/0xffffffff
COMMIT
# Route an VPN per nat.
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o tun-+ -j SNAT --to-source <FFRL Gateway IP>
COMMIT

Erklärung:

Nun müssen die Regeln noch aktiviert werden:

# iptables-restore < /etc/sysconfig/iptables

IP-Rules

Für einige IP-Regeln brauchen wir ein SystemD Service-File unter /etc/systemd/system/ip-rules.service:

[Unit]
Description=Freifunk related ip rules

[Service]
Type=oneshot
ExecStart=/usr/sbin/ip rule add from <FFRL Gateway IP>/30 lookup 42
ExecStart=/usr/sbin/ip rule add from 10.10.0.0/16 lookup 42
ExecStart=/usr/sbin/ip -6 rule add from 2a03:2260:116::/48 lookup 42

[Install]
WantedBy=multi-user.target

Erklärung:

NTP

Wir brauchen einen NTP-Server im Netz, damit sich auch Knoten ohne eigene Internetverbindung synchronisieren können. Dazu bearbeitest du die /etc/ntp.conf:

driftfile /var/lib/ntp/drift
restrict default nomodify notrap nopeer noquery
restrict 127.0.0.1 
restrict ::1

restrict 10.10.0.0 mask 255.255.0.0 nomodify notrap
restrict 2a03:2260:116:: mask ffff:ffff:ffff:: nomodify notrap

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

includefile /etc/ntp/crypto/pw
keys /etc/ntp/keys
disable monitor

alfred

Damit dein Server auch hübsch in der Map erscheint, benötigst du ALFRED. Dazu muss ein Systemd Service-File unter ´/etc/systemd/system/alfred.service´ angelegt werden:

[Unit]
Description=ALFRED Fact Distribution Daemon
Requires=fastd@mesh-01.service
After=fastd@mesh-01.service

[Service]
Type=simple
ExecStart=/usr/sbin/alfred -i bat0

[Install]
WantedBy=multi-user.target

batadv-vis

Weitergehend muss auch für batadv-vis ein Systemd Service-File unter /etc/systemd/system/batadv-vis.service angelegt werden:

[Unit]
Description=Batman-adv VIS
Requires=alfred.service
After=alfred.service

[Service]
Type=simple
ExecStart=/usr/sbin/batadv-vis -s

[Install]
WantedBy=multi-user.target

ffnord-alfred-announce

Das ffnord-alfred-announce Script sammelt alle benötigten Daten des Gateway-Servers zusammen und übergibt sie an alfred. Um dies zu installieren muss per git das Repository https://github.com/ffnord/ffnord-alfred-announce.git nach /opt geklont werden.

Da CentOS beim Installieren von python34 keinen Symbolischen Link auf python3 anlegt, musst du dies nun nachholen, da das Script sonst nicht lauffähig ist:

ln -s /usr/bin/python3.4 /usr/local/bin/python3

Als letztes legst du folgende crontab-Zeile an:

* * * * * PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin /opt/ffnord-alfred-announce/announce.sh

Lokale Nameserver konfigurieren

Da du einen bind installiert hast, macht es sinn, auch lokale Adressauflösungen über diesen laufen zu lassen. Dazu bearbeitest du die Datei /etc/resolv.conf:

nameserver 127.0.0.1

Logging abschalten

da wir kein Logging möchten, solltest du, wenn alles getestet ist und läuft, das Logging findet über journald statt, das in der /etc/systemd/journald.conf konfiguriert wird:

Storage=volatile
MaxRetentionSec=1m
MaxFileSec=1m
ForwardToSyslog=no 
MaxLevelStore=error

Dienste starten

Wenn alles konfiguriert ist können die Dienste gestartet werden:

systemctl restart systemd-journald
systemctl start ip-rules
systemctl enable ip-rules
systemctl start bird
systemctl enable bird
systemctl start bird6
systemctl enable bird6
systemctl enable ntpd
systemctl start ntpd
systemctl enable fastd@mesh-01
systemctl start fastd@mesh-01
systemctl enable fastd@mesh-02
systemctl start fastd@mesh-02
systemctl enable fastd@mesh-03
systemctl start fastd@mesh-03
systemctl enable fastd@mesh-04
systemctl start fastd@mesh-04
systemctl enable fastd@mesh-05
systemctl start fastd@mesh-05
systemctl enable fastd@mesh-06
systemctl start fastd@mesh-06
systemctl enable fastd@mesh-07
systemctl start fastd@mesh-07
systemctl enable fastd@mesh-08
systemctl start fastd@mesh-08
systemctl start named
systemctl enable named
systemctl start dhcpd
systemctl enable dhcpd
systemctl start radvd
systemctl enable radvd
systemctl enable alfred
systemctl start alfred
systemctl enable batadv-vis
systemctl start batadv-vis
systemctl start vnstat
systemctl enable vnstat