Zum Inhalt springen

Flensburg:Gateway-Liste

Aus wiki.freifunk.net

Hier den unformatierten Text eingeben== Gateways ==

Hostname IPv4 (WAN) IPv6 (WAN) IPv4 (LAN) IPv6 (LAN) MAC (mesh vpn) DHCP-Range(GW/DNS) Links Kommentar Verantwortliche(r)
snowden.mesh.freifunk-flensburg.de 10.129.1.1 fddf:bf7:10:1:1::1 9E:99:81:75:B5:61 10.129.5.1 - .20.254 Keine Services
gw02.mesh.freifunk-flensburg.de 10.129.1.2 fddf:bf7:10:1:1::2 9E:99:81:75:B5:62 10.129.21.1 - .40.254 Keine Services
nerdisch.ent 152.228.240.18 2001:41d0:305:2100::1:8745 10.129.1.3 fddf:bf7:10:1:1::3 00:00:ff:f1:01:03 10.129.41.1 - .60.254 Stats OVH FR Debian 13 Nymphadora


Vorbereitung

Systemanforderungen

CPU: Mindestens 2 Kerne mit guter Single-Thread-Leistung
RAM: Mindestens 512 MB
Speicher: Mindestens 10 GB
Datenverkehr: Mindestens 5 TB monatlich (gerne auch unlimitiert)
Virtualisierung: Kernel-Anpassungen müssen möglich sein (kein OpenVZ)
Netzwerk: Mindestens 100 Mbit/s empfohlen
VPN: VPN-Anbieter zur Weiterleitung und verschleirung des Netzwerkverkehrs empfohlen

Beispiel Hoster

Anbieter Bandbreite) Traffic) Standort) IPv4) IPv6) Kosten) Bemerkung)
OVH VPS 500 Mbit/s öffentliche Bandbreite) flat Frankreich JA JA Ab ca: 4,53 € netplan
webtropia VPS 1GBit (200 Mbit/s garantierte Peak-Bandbreite) 40 TB Traffic bei VPS Düsseldorf JA JA Ab ca: 5,99 € netplan
Hetzner VPS 1GBit 20 TB inkl. · Extra-TB: ca: 1,19 € Gunzenhausen, Bayern kostet extra JA Ab ca: 7,13 € netplan ?

Eine detaillierte Liste findest du hier: pinneberg oder pinneberg (Wayback Machine)

sicherheitsvorkehrungen

SSH key einrichten

ssh key erstellen

ssh-keygen -t ed25519

ssh key auf den Server übertragen

ssh-copy-id benutzer@ip_adresse

mit den server verbinden

ssh benutzer@IP-Adresse

User erstellen (falls notwendig)

adduser user

ssh absichern

nano /etc/ssh/sshd_config
# ==========================================
# SSH-Härtung für das Freifunk-Gateway
# ==========================================

# ------------------------------------------
# Netzwerk und Zugriffskontrolle
# ------------------------------------------

# SSH-Port ändern zum Beispiel 3022
Port 3022

# IPv4 und IPv6 erlauben
AddressFamily any

# Direkten Root-Login verbieten
PermitRootLogin no

# Nur diesen Benutzer für SSH zulassen
# WICHTIG: Benutzernamen ersetzen!
AllowUsers dein_username

# Maximal 3 Authentifizierungsversuche
MaxAuthTries 3

# Login-Zeitfenster auf 30 Sekunden begrenzen
LoginGraceTime 30

# Maximal 2 Sitzungen pro SSH-Verbindung
MaxSessions 2

# Unauthentifizierte Verbindungen begrenzen
MaxStartups 3:30:10

# ------------------------------------------
# Authentifizierung
# ------------------------------------------

# Public-Key-Authentifizierung aktivieren
PubkeyAuthentication yes

# Passwort-Authentifizierung deaktivieren
PasswordAuthentication no

# Interaktive Authentifizierung deaktivieren
KbdInteractiveAuthentication no

# Ausschließlich Public-Key-Authentifizierung verlangen
AuthenticationMethods publickey

# Anmeldung mit leeren Passwörtern verbieten
PermitEmptyPasswords no

# ------------------------------------------
# SSH-Schlüssel
# ------------------------------------------

# Nur die reguläre Schlüsseldatei verwenden
AuthorizedKeysFile .ssh/authorized_keys

# ------------------------------------------
# Weiterleitungen und Tunnel
# ------------------------------------------

# SSH-Agent-Weiterleitung deaktivieren
AllowAgentForwarding no

# TCP-Port-Weiterleitungen deaktivieren
AllowTcpForwarding no

# X11-Weiterleitung deaktivieren
X11Forwarding no

# SSH-TUN/TAP-Tunnel deaktivieren
PermitTunnel no

# Benutzerdefinierte Umgebungsvariablen verbieten
PermitUserEnvironment no

# ------------------------------------------
# Sicherheitsprüfung und Protokollierung
# ------------------------------------------

# Rechte und Eigentümer der SSH-Dateien prüfen
StrictModes yes

# Authentifizierungsereignisse detaillierter protokollieren
LogLevel VERBOSE

Server aktualisieren

apt update && apt upgrade

Fail2ban

apt install fail2ban python3-systemd
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
nano /etc/fail2ban/jail.local

[…] (Fail2Ban Multiplikator)


[DEFAULT]

#
# MISCELLANEOUS OPTIONS
#

# "bantime.increment" allows to use database for searching of previously banned ip's to increase a 
# default ban time using special formula, default it is banTime * 1, 2, 4, 8, 16, 32...
DIESER WERT MUSS TRUE SEIN
#bantime.increment = true

# "bantime.rndtime" is the max number of seconds using for mixing with random time 
# to prevent "clever" botnets calculate exact time IP can be unbanned again:
DIESER WERT auf 10m setzen
bantime.rndtime = 10m

# "bantime.maxtime" is the max number of seconds using the ban time can reach (doesn't grow further)
DIESER WERT AUF 7d setzen
bantime.maxtime = 7d

# "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier,
# default value of factor is 1 and with default value of formula, the ban time 
# grows by 1, 2, 4, 8, 16 ...
DIESER WERT auf 1 setzen
bantime.factor = 1

# "bantime.formula" used by default to calculate next value of ban time, default value below,
# the same ban time growing will be reached by multipliers 1, 2, 4, 8, 16, 32...
#bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
#
# more aggressive example of formula has the same values only for factor "2.0 / 2.885385" :
#bantime.formula = ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)

# "bantime.multipliers" used to calculate next value of ban time instead of formula, corresponding
# previously ban count and given "bantime.factor" (for multipliers default is 1);
# following example grows ban time by 1, 2, 4, 8, 16 ... and if last ban count greater as multipliers count, 
# always used last multiplier (64 in example), for factor '1' and original ban time 600 - 10.6 hours
#bantime.multipliers = 1 2 4 8 16 32 64
# following example can be used for small initial ban time (bantime=60) - it grows more aggressive at begin,
# for bantime=60 the multipliers are minutes and equal: 1 min, 5 min, 30 min, 1 hour, 5 hour, 12 hour, 1 day, 2 day
#bantime.multipliers = 1 5 30 60 300 720 1440 2880

# "bantime.overalljails" (if true) specifies the search of IP in the database will be executed 
# cross over all jails, if false (default), only current jail of the ban IP will be searched
DIESER WERT MUSS TRUE SEIN
bantime.overalljails = true

[…] IP-Sperren und Schutzparameter

# "ignoreself" specifies whether the local resp. own IP addresses should be ignored
# (default is true). Fail2ban will not ban a host which matches such addresses.
#ignoreself = true

# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
# will not ban a host which matches an address in this list. Several addresses
# can be defined using space (and/or comma) separator.
ignoreip = 127.0.0.1/8 ::1


# External command that will take an tagged arguments to ignore, e.g. <ip>,
# and return true if the IP is to be ignored. False otherwise.
#
# ignorecommand = /path/to/command <ip>
ignorecommand =

# "bantime" is the number of seconds that a host is banned.
# 3600 = 1 Stunde
bantime  = 3600

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 600

# "maxretry" is the number of failures before a host get banned.
maxretry = 3

# Wenn es sich hierbei ein systemd System handelt muss dies umgestellt werden.
backend = systemd

[…] (SSH-Login absichern:')

#
# SSH servers
# 

[sshd]

enabled	= true
# Hier muss derselbe Port eingetragen werden, der in der SSH-Konfiguration steht.
port    = 3022
filter	= sshd
#logpath	= /var/log/auth.log
maxretry = 4
findtime = 1d
bantime = 20160
ignoreip = 127.0.0.1/8

Fail2ban SSH Filter für Public Key

nano /etc/fail2ban/filter.d/sshd.conf

Unter dem Punkt „cmnfailre“ muss folgendes hinzugefügt werden:

^%(__prefix_line)sConnection closed by authenticating user <F-USER>.+</F-USER> <HOST> port \d+ \[preauth\]$

[…] (SSH-Filtermodus auf „aggressive“ setzen)

# Parameter "mode": normal (default), ddos, extra or aggressive (combines all)
# Usage example (for jail.local):
#   [sshd]
#   mode = extra
#   # or another jail (rewrite filter parameters of jail):
#   [sshd-aggressive]
#   filter = sshd[mode=aggressive]
#  DIESER MUSS VON ,,normal" auf aggressive gestellt werden.
mode = normal

Fail2ban muss neu gestartet werden

systemctl restart fail2ban.service

Grundlegende Einstellungen

Packete installieren

Wir haben uns an die Beschreibungen und Tipps von anderen gehalten und es ist empfohlen, die folgenden Pakete zu installieren:

  ^ Paket              ^ Beschreibung
| sudo               | Ausführung von Befehlen mit Root-Rechten |
| bridge-utils       | Verwaltung von Netzwerkbrücken           |
| batctl             | B.A.T.M.A.N. Verwaltungstools            |
| wireguard          | VPN für Verbindung zur Anonymisierung    |
| haveged            | Entropie                                 |
| fastd              | VPN für Verbindung zu den Knoten         |
| radvd              | IPv6 Router Advertisements               |
| isc-dhcp-server    | DHCP Server                              |
| bind9              | DNS Server                               |
| git                | Versionsverwaltungssystem                |
| alfred             | A.L.F.R.E.D. Datenübertragung            |
| alfred-json        | A.L.F.R.E.D. Datenausgabe                |
| batman-adv-dkms    | Batman-Kernelmodul in Version 2016.01 V5 |
| ntpsec             | Zeitsynchronisation                      |
| curl               | Linux Tool                               |
| screen             | Terminal-Multiplexer                     |
| htop               | Prozessmonitor                           |
| iftop              | Traffic live pro Verbindung              |
| mtr-tiny           | traceroute + ping kombiniert             |
| mc                 | Midnight Commander                       |
| bash-completion    | Tab-Vervollständigung                    |
| nano               | Editor                                   |
| ca-certificates    | CA-Zertifikate                           |
| unbound            | rekursiver DNS-Resolver                  |
| iptables-persistent| iptables-Regeln persistent speichern     |
| apt-transport-https| HTTPS für apt                            |

Die Installation erfolgt über die folgende Befehlszeile als root:

apt-get install screen htop iftop traceroute mtr-tiny mc bash-completion nano ca-certificates haveged ntpsec unbound isc-dhcp-server radvd iptables-persistent apt-transport-https bind9 sudo git apt-transport-https vnstat fastd

Zeit und Sprache anpassen

Zeit auf Berlin setzen.

timedatectl set-timezone Europe/Berlin

ntpsec zum Autostart hinzufügen:

sudo systemctl enable --now ntpsec

ntpsec starten

sudo systemctl start ntp

Aktuellen Statusdienst abfragen

systemctl status ntpsec

Zeit Server abfragen:

ntpq -p

Aktuelle Server Zeit abfragen:

timedatectl

Falls man die Systemsprache auf deutsch stellen möchte: Locale-Paket installieren

apt-get install -y locales

de_DE.UTF-8 freischalten

sed -i 's/^# *de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen

Locale erzeugen

locale-gen

Deutsch als System-Standard setzen

update-locale LANG=de_DE.UTF-8 LC_ALL=de_DE.UTF-8

Batman-adv 2016.1

batman-adv 2016.1 mit BATMAN_V muss gebaut werden. Unter neueren Distributionen wie Debian 13 oder Ubuntu ist der Kernel zu neu und muss dafür gepatcht werden. Das Repo findest du hier: [(GitHub)].

#!/bin/bash
# Build and install batman-adv + batctl via DKMS.
# Module and batctl only — does not apply kernel patches.
#
# Set VER below, or pass -v / VERSION on the CLI.
# For Kernel 6.12 + 2016.1, see README.md in this directory (extract → patch → --keep-src).
set -euo pipefail

# --- set version here (CLI can override) ---
VER=2016.1

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

REMOVE_OLD=1
SKIP_APT=0
KEEP_SRC=0
NEED_REBOOT=0

usage() {
  cat <<EOF
Usage: sudo bash $0 [OPTION]... [VERSION]

  VERSION            e.g. 2016.1, 2024.4 (default: VER=${VER})
  -v, --version VER  same as VERSION

  --keep-old         do not remove existing module/DKMS first
  --keep-src         reuse existing source under /usr/local/src/batman-\${VER}
  --skip-apt         skip apt install

Release URL:
  https://downloads.open-mesh.org/batman/releases/batman-adv-\${VER}/
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    -v|--version)
      [[ $# -ge 2 ]] || { echo "[!] $1 needs an argument"; exit 1; }
      VER="$2"
      shift 2
      ;;
    --remove-old) REMOVE_OLD=1; shift ;;
    --keep-old) REMOVE_OLD=0; shift ;;
    --keep-src) KEEP_SRC=1; shift ;;
    --skip-apt) SKIP_APT=1; shift ;;
    -h|--help) usage; exit 0 ;;
    -*)
      echo "Unknown: $1"
      usage
      exit 1
      ;;
    *)
      if [[ "$1" =~ ^[0-9]+\.[0-9]+([.-][0-9A-Za-z]+)*$ ]]; then
        VER="$1"
        shift
      else
        echo "Unknown: $1"
        usage
        exit 1
      fi
      ;;
  esac
done

[[ $(id -u) -eq 0 ]] || { echo "[!] run as root: sudo bash $0"; exit 1; }

log() { echo "[*] $*"; }
die() { echo "[!] $*" >&2; exit 1; }

BASE_URL="https://downloads.open-mesh.org/batman/releases/batman-adv-${VER}"
SRC_ROOT="${SRC_ROOT:-/usr/local/src/batman-${VER}}"
BAT_SRC="$SRC_ROOT/batman-adv-${VER}"
BATCTL_SRC="$SRC_ROOT/batctl-${VER}"
DKMS_SRC="/usr/src/batman-adv-${VER}"

run_limited() {
  local secs="$1"; shift
  ("$@" >/dev/null 2>&1) &
  local pid=$! i=0
  while kill -0 "$pid" 2>/dev/null; do
    if (( i >= secs )); then
      kill -KILL "$pid" 2>/dev/null || true
      disown "$pid" 2>/dev/null || true
      return 124
    fi
    sleep 1
    i=$((i + 1))
  done
  wait "$pid" 2>/dev/null || true
  return 0
}

find_ko() {
  local ko
  ko="$(modinfo -n batman-adv 2>/dev/null || true)"
  if [[ -n "$ko" && -f "$ko" ]]; then
    echo "$ko"
    return 0
  fi
  for cand in \
    "/lib/modules/${KVER}/updates/dkms/batman-adv.ko"{,.xz} \
    "/lib/modules/${KVER}/updates/net/batman-adv/batman-adv.ko"{,.xz}
  do
    [[ -f "$cand" ]] && { echo "$cand"; return 0; }
  done
  return 1
}

remove_batman() {
  log "Removing existing batman-adv…"
  local batctl_bin=""
  command -v batctl >/dev/null 2>&1 && batctl_bin="$(command -v batctl)"
  [[ -x /usr/local/sbin/batctl ]] && batctl_bin=/usr/local/sbin/batctl
  if [[ -n "$batctl_bin" ]]; then
    for hif in mesh-vpn tap0; do
      run_limited 3 "$batctl_bin" -m bat0 if del "$hif" || true
    done
  fi
  run_limited 2 ip link set bat0 nomaster || true
  run_limited 2 ip link del bat0 || true

  if lsmod | grep -q '^batman_adv'; then
    echo 'blacklist batman_adv' > /etc/modprobe.d/blacklist-batman-adv.conf
    NEED_REBOOT=1
    log "batman_adv is loaded — reboot required after install"
  else
    rm -f /etc/modprobe.d/blacklist-batman-adv.conf
  fi

  run_limited 30 dkms remove "batman-adv/${VER}" --all || true
  rm -rf "/usr/src/batman-adv-${VER}" /var/lib/dkms/batman-adv 2>/dev/null || true
  rm -f "/lib/modules/${KVER}/updates/dkms/batman-adv.ko"* \
        "/lib/modules/${KVER}/updates/net/batman-adv/batman-adv.ko"* \
        "/lib/modules/${KVER}/extra/batman-adv.ko"* 2>/dev/null || true
  rm -f /usr/local/bin/batctl /usr/local/sbin/batctl
  [[ -f /etc/modprobe.d/batman-adv.conf ]] \
    && mv -f /etc/modprobe.d/batman-adv.conf /etc/modprobe.d/batman-adv.conf.disabled
  run_limited 60 depmod -a || true
}

install_build_deps() {
  export DEBIAN_FRONTEND=noninteractive
  apt-get update -qq
  apt-get install -y build-essential dkms pkg-config wget python3 xz-utils \
    libnl-3-dev libnl-genl-3-dev \
    || die "apt install failed"

  if apt-cache show "linux-headers-${KVER}" >/dev/null 2>&1; then
    apt-get install -y "linux-headers-${KVER}" || die "linux-headers-${KVER} install failed"
  else
    log "linux-headers-${KVER} not in apt — trying meta package"
    local meta=""
    if [[ "$KVER" == *cloud* ]]; then
      meta=linux-headers-cloud-amd64
    else
      meta=linux-headers-amd64
    fi
    apt-get install -y "$meta" \
      || die "no headers for ${KVER}; install matching linux-image+headers and reboot"
  fi

  if [[ ! -d "/lib/modules/${KVER}/build" ]]; then
    local newer=""
    newer="$(echo /lib/modules/*/build 2>/dev/null | tr ' ' '\n' | head -5 | xargs -r dirname | xargs -r -n1 basename | tr '\n' ' ')"
    die "headers for running kernel ${KVER} missing (/lib/modules/${KVER}/build).
A newer kernel is likely installed but not active yet (found build dirs: ${newer:-none}).
Reboot into it, then re-run this script."
  fi
}

# --- start ---
KVER="$(uname -r)"
log "batman-adv ${VER} — kernel $KVER"

if [[ "$SKIP_APT" -eq 0 ]]; then
  install_build_deps
fi

[[ "$REMOVE_OLD" -eq 1 ]] && remove_batman || log "Skipping remove (--keep-old)"

mkdir -p "$SRC_ROOT"
cd "$SRC_ROOT"

if [[ "$KEEP_SRC" -eq 1 ]]; then
  [[ -d "$BAT_SRC" ]] || die "--keep-src set but missing $BAT_SRC"
  [[ -d "$BATCTL_SRC" ]] || die "--keep-src set but missing $BATCTL_SRC"
  log "Reusing source: $BAT_SRC"
else
  for f in "batman-adv-${VER}.tar.gz" "batman-adv-${VER}.tar.gz.sha1" \
           "batctl-${VER}.tar.gz" "batctl-${VER}.tar.gz.sha1"; do
    if [[ ! -f "$f" ]]; then
      log "Downloading $f"
      wget -O "$f" "${BASE_URL}/$f" || die "download failed: $f (release ${VER} missing?)"
    fi
  done
  sha1sum -c "batman-adv-${VER}.tar.gz.sha1" || die "SHA1 check failed (batman-adv)"
  sha1sum -c "batctl-${VER}.tar.gz.sha1" || die "SHA1 check failed (batctl)"

  [[ -L "$BAT_SRC" ]] && rm -f "$BAT_SRC"
  rm -rf "$BAT_SRC" "$BATCTL_SRC"
  tar xf "batman-adv-${VER}.tar.gz"
  tar xf "batctl-${VER}.tar.gz"
  [[ -d "$BAT_SRC" && ! -L "$BAT_SRC" ]] || die "extract batman-adv failed"
  [[ -d "$BATCTL_SRC" ]] || die "extract batctl failed"
  log "Source extracted to $BAT_SRC (patch this tree before DKMS on kernel 6.12)"
fi

log "DKMS…"
rm -rf "$DKMS_SRC"
mkdir -p "$DKMS_SRC"
cp -a "$BAT_SRC"/. "$DKMS_SRC"/
find "$DKMS_SRC" -type f \( -name '*.o' -o -name '*.ko' -o -name '*.mod' -o -name '*.mod.c' \
  -o -name '.*.cmd' -o -name 'Module.symvers' -o -name 'modules.order' \) -delete

cat > "$DKMS_SRC/dkms.conf" << EOF
PACKAGE_NAME="batman-adv"
PACKAGE_VERSION="${VER}"
BUILT_MODULE_NAME[0]="batman-adv"
BUILT_MODULE_LOCATION[0]="net/batman-adv/"
DEST_MODULE_LOCATION[0]="/updates/net/batman-adv"
MAKE[0]="make KERNELPATH=\${kernel_source_dir} CONFIG_BATMAN_ADV_BATMAN_V=y"
CLEAN="make KERNELPATH=\${kernel_source_dir} clean"
AUTOINSTALL="yes"
EOF

dkms remove "batman-adv/${VER}" --all 2>/dev/null || true
dkms add -m batman-adv -v "$VER" || die "dkms add failed"
dkms build -m batman-adv -v "$VER" -k "$KVER" \
  || die "dkms build failed — see /var/lib/dkms/batman-adv/${VER}/build/make.log"
dkms install -m batman-adv -v "$VER" -k "$KVER" || die "dkms install failed"
depmod -a

INST_KO="$(find_ko)" || die "installed batman-adv.ko not found"
log "Module: $INST_KO"

if lsmod | grep -q '^batman_adv'; then
  log "Old batman_adv still loaded — no live reload"
  NEED_REBOOT=1
  echo 'blacklist batman_adv' > /etc/modprobe.d/blacklist-batman-adv.conf
else
  rm -f /etc/modprobe.d/blacklist-batman-adv.conf
  if modprobe batman-adv; then
    MODVER="$(modinfo -F version batman-adv 2>/dev/null || true)"
    [[ "$MODVER" == "$VER" ]] || { log "WARN: version='$MODVER' (expected $VER)"; NEED_REBOOT=1; }
  else
    log "WARN: modprobe failed — load after reboot"
    NEED_REBOOT=1
    echo 'blacklist batman_adv' > /etc/modprobe.d/blacklist-batman-adv.conf
  fi
fi

log "batctl…"
make -C "$BATCTL_SRC" clean
make -C "$BATCTL_SRC" -j"$(nproc)" || die "batctl make failed"
make -C "$BATCTL_SRC" install || die "batctl install failed"
ln -sfn /usr/local/sbin/batctl /usr/local/bin/batctl
/usr/local/sbin/batctl -v || die "batctl failed to run"

echo
echo "OK — batman-adv ${VER}"
echo "  dkms:   $(dkms status 2>/dev/null | grep batman-adv || echo '?')"
echo "  module: $(modinfo -n batman-adv 2>/dev/null || echo '(after reboot)')"
echo "  batctl: $(/usr/local/sbin/batctl -v 2>/dev/null || echo '?')"
if [[ "$NEED_REBOOT" -eq 1 ]]; then
  echo
  echo "REBOOT required, then:"
  echo "  sudo rm -f /etc/modprobe.d/blacklist-batman-adv.conf"
  echo "  sudo depmod -a && sudo modprobe batman-adv"
  echo "  modinfo batman-adv | head"
else
  echo
  echo "Module loaded. Set up mesh (fastd/bat0/bridge) separately."
fi

Netzwerkkonfiguration

netplan

Serveranbieter wie OVH oder Webtropia verwenden auf ihren VPS Netplan zur Netzwerkkonfiguration. Die Konfiguration erfolgt über eine YAML-Datei, beispielsweise:

nano /etc/netplan/60-fffl.yaml
network:
  version: 2
  renderer: networkd

  bridges:
    br-fffl:
      interfaces: []
      parameters:
        stp: false
        forward-delay: 0
      addresses:
        - 10.129.1.[GW_Number]/16
        - fddf:bf7:10:1:1::[GW_Number]/64
      dhcp4: false
      dhcp6: false
      accept-ra: false

      routes:
        - to: 10.129.0.0/16
          scope: link
          table: 42
        - to: fddf:bf7:10:1::/64
          scope: link
          table: 42

      routing-policy:
        - from: 10.129.0.0/16
          table: 42
          priority: 100
        - from: fddf:bf7:10:1::/64
          table: 42
          priority: 100

netplan berechtigung setzen

sudo chmod 600 /etc/netplan/60-fffl.yaml

Konfiguration auf Fehler prüfen:

 sudo netplan generate

Konfiguration testen:

sudo netplan try

Konfiguration dauerhaft übernehmen:

sudo netplan apply

ifupdown

nano /etc/network/interfaces
source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
allow-hotplug eth0

iface eth0 inet dhcp

# Batman
    auto br-fffl
    allow-hotplug bat0

iface eth0 inet6 static
    address [your public ipv6]  # don't change
    netmask [your public ipv6 netmask]  # don't change
    gateway [your public ipv6 gateway]  # don't change

#  HOSTER: Everything above this line is the config from your hoster
# <----------------------------------------------------------------------
#  FREEMESH: Everything after this line is the config for your community

# Batman
    up /sbin/brctl addbr br-fffl

iface br-fffl inet static
    address 10.129.1.[GW_Number]
    netmask 255.255.0.0
    bridge-ports none

iface br-fffl inet6 static
    address fddf:bf7:10:1:1::[GW_Number]
    netmask 64

# batman interface
iface bat0 inet6 manual
   pre-up /usr/sbin/batctl if add tap0
   up /bin/ip link set dev bat0 up
   post-up /sbin/brctl addif br-fffl bat0
   post-up /usr/sbin/batctl it 10000
   post-up /usr/sbin/batctl gw_mode server #Activate the gateway announcements on a node
   #post-up /usr/sbin/batctl gw_mode off  #Disabled the gateway announcements on a node
   post-up /sbin/ip rule add from all fwmark 0x1 table 42
   post-up /sbin/ip route add 10.129.0.0/16 dev br-fffl table 42
   post-up /sbin/ip -6 rule add from all fwmark 0x1 table 42
   post-up /sbin/ip -6 route add fddf:bf7:10:1:1::[GW_Number]/64 dev br-fffl table 42
   pre-down /sbin/brctl delif br-fffl bat0 || true
   down /bin/ip link set dev bat0 down

   # this is for adding the gateway to the map later, not necessarily necessary.
   # post-up start-stop-daemon -b --start --exec /usr/local/sbin/alfred -- -i br-$FREEMESH_TLD -b bat0 -m
   # post-up start-stop-daemon -b --start --exec /usr/local/sbin/batadv-vis -- -i bat0 -s

Netzwerkkarte neustarten

service networking restart
service networking restart

Netzwerkdienste

fastd

Wir brauchen für den neuen Server die Schlüssel für fastd. fastd ist im Grunde ein VPN und der sichert die Leitung zwischen Router und Gateway ab, daher die Notwendigkeit des Schlüsselpaars

Ordner fastd Ordner erstellen

sudo mkdir -p /etc/fastd/mesh-vpn/peers

Berechtigungen setzen

sudo chmod 750 /etc/fastd/vpn

Jedes Freifunk Gateway hat seinen eigenen Fastd Schlüssel, falls dieser bereits vorhanden ist, kann das Generieren übersprungen werden und kann der private key direkt in die secret.conf eingetragen werden.

fastd --generate-key > /root/fastd-keys.pub.sec

Fastd Schlüssel nach der generierung auslesen

cat /root/fastd-keys.pub.sec

key in die fastd secret kopieren (private key)

nano /etc/fastd/vpn/secret.conf
secret "fastd-keys.pub.sec";

Fastd Konfig erstellen

nano /etc/fastd/vpn/fastd.conf
log level verbose;
status socket "/run/fastd-vpn.sock";
mode tap;
interface "mesh-vpn";
bind any:10006 interface "ens18"; # <- Interface muss angepasst werden 
method "salsa2012+umac";        #
mtu 1406;                        # 1280 bytes for the client and 24 bytes for the batman unicast header
include "secret.conf";          # include the secret.conf with your private secret key from the /root/fastd-keys.pub.sec
include peers from "peers";     # your peerlist with the other gateways
on verify "false";              # this allows any unknown node to connect to your fastd
on up "
/bin/ip link set dev mesh-vpn address 00:00:ff:f1:01:03
/bin/ip link set dev mesh-vpn up
";
on down "
/bin/ip link set dev mesh-vpn down
";

Batman soll sauber gestartet werden, sonst gibt es probleme:

nano /etc/systemd/system/ff-bat0.service
[Unit]
Description=Freifunk batman-adv bat0 (BATMAN_V)
Documentation=man:batctl(8)
After=network-online.target fastd@vpn.service
Requires=fastd@vpn.service
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
TimeoutStartSec=25
TimeoutStopSec=25

Environment=MESH_IF=bat0
Environment=HARD_IF=mesh-vpn
Environment=BRIDGE=br-fffl
Environment=ALGO=BATMAN_V
Environment=ORIG_INTERVAL=10000
Environment=GW_MODE=server
Environment=BATCTL=/usr/local/sbin/batctl

ExecStart=/usr/local/sbin/ff-bat0-up.sh
ExecStop=/usr/local/sbin/ff-detach-tap0.sh
ExecStop=/usr/local/sbin/ff-bat0-down.sh

[Install]
WantedBy=multi-user.target


nano /usr/local/sbin/ff-bat0-up.sh
#!/bin/bash
set -u
BATCTL=${BATCTL:-/usr/local/sbin/batctl}
MESH_IF=${MESH_IF:-bat0}
HARD_IF=${HARD_IF:-mesh-vpn}
BRIDGE=${BRIDGE:-br-fffl}
ORIG_INTERVAL=${ORIG_INTERVAL:-10000}
GW_MODE=${GW_MODE:-server}
ALGO=${ALGO:-BATMAN_V}
log() { echo "ff-bat0-up: $*" >&2; }

modprobe batman-adv || exit 1
echo "$ALGO" > /sys/module/batman_adv/parameters/routing_algo

for i in $(seq 1 60); do
  ip link show "$HARD_IF" >/dev/null 2>&1 && break
  sleep 0.5
done
ip link show "$HARD_IF" >/dev/null 2>&1 || { log "ERROR: $HARD_IF fehlt (fastd?)"; exit 1; }
ip link set "$HARD_IF" up || true

ip link show "$BRIDGE" >/dev/null 2>&1 || ip link add name "$BRIDGE" type bridge
ip link set "$BRIDGE" up || true

need_recreate=0
if ! ip link show "$MESH_IF" >/dev/null 2>&1; then
  need_recreate=1
else
  cur=$(cat /sys/class/net/"$MESH_IF"/mesh/routing_algo 2>/dev/null || echo "")
  [ "$cur" = "$ALGO" ] || need_recreate=1
fi

if [ "$need_recreate" -eq 1 ]; then
  timeout 3 ip link set "$MESH_IF" nomaster 2>/dev/null || true
  timeout 3 ip link set "$MESH_IF" down 2>/dev/null || true
  timeout 3 "$BATCTL" -m "$MESH_IF" if del "$HARD_IF" 2>/dev/null || true
  timeout 3 ip link del "$MESH_IF" 2>/dev/null || true
  echo "$ALGO" > /sys/module/batman_adv/parameters/routing_algo
fi

timeout 15 "$BATCTL" -m "$MESH_IF" if add "$HARD_IF"
sleep 0.3
ip link set "$MESH_IF" up
timeout 10 "$BATCTL" -m "$MESH_IF" it "$ORIG_INTERVAL"
timeout 10 "$BATCTL" -m "$MESH_IF" gw_mode "$GW_MODE"
ip link set "$MESH_IF" master "$BRIDGE" || true
ip link set "$BRIDGE" up || true

ra=$(cat /sys/class/net/"$MESH_IF"/mesh/routing_algo)
log "OK algo=$ra table42=fwmark+link"
[ "$ra" = "$ALGO" ]
nano /usr/local/sbin/ff-bat0-down.sh
#!/bin/bash
set -u
BATCTL=${BATCTL:-/usr/local/sbin/batctl}
MESH_IF=${MESH_IF:-bat0}
HARD_IF=${HARD_IF:-mesh-vpn}
DETACH=${DETACH:-/usr/local/sbin/ff-detach-tap0.sh}

# tap0 von batman (kein bat0 down — Reboot-Hang)
if [ -x "$DETACH" ]; then
  HARD_IF="$HARD_IF" "$DETACH" || true
else
  timeout 3 "$BATCTL" -m "$MESH_IF" if del "$HARD_IF" 2>/dev/null || true
fi
exit 0

damit fastd sauber von batman getrennt wird.

nano /usr/local/sbin/ff-detach-tap0.sh
#!/bin/sh
# mesh-vpn von batman loesen — VOR fastd-Stop, sonst unregister_netdevice-Hang
set -u
BATCTL="${BATCTL:-/usr/local/sbin/batctl}"
MESH_IF="${MESH_IF:-bat0}"
HARD_IF="${HARD_IF:-mesh-vpn}"

i=0
while [ "$i" -lt 10 ]; do
        if ! "$BATCTL" -m "$MESH_IF" if 2>/dev/null | grep -q "$HARD_IF"; then
                exit 0
        fi
        timeout 2 "$BATCTL" -m "$MESH_IF" if del "$HARD_IF" 2>/dev/null || true
        i=$((i + 1))
        sleep 0.3
done
timeout 2 "$BATCTL" -m "$MESH_IF" if del "$HARD_IF" 2>/dev/null || true
exit 0

fastd on down reicht oft nicht (Capabilities nach Drop, Reihenfolge). systemd muss zuerst detachieren, dann fastd beenden.

mkdir -p /etc/systemd/system/fastd@vpn.service.d/
nano /etc/systemd/system/fastd@vpn.service.d/safe-stop.conf
[Service]
TimeoutStopSec=20
ExecStop=/bin/sh -c '/usr/local/sbin/ff-detach-tap0.sh; /bin/kill -TERM $MAINPID'

Systemd Dateien neu einlesen

sudo systemctl daemon-reload

Systemd zum starten hinzufügen:

sudo systemctl enable --now ff-bat0.service

DHCP radvd IPv6

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

# Freifunk Flensburg — ULA via SLAAC auf br-fffl
interface br-fffl {
  AdvSendAdvert on;
  IgnoreIfMissing on;
  AdvManagedFlag off;
  AdvOtherConfigFlag off;
  MaxRtrAdvInterval 200;
  MinRtrAdvInterval 60;

  prefix fddf:bf7:10:1::/64 {
    AdvOnLink on;
    AdvAutonomous on;
    AdvRouterAddr on;
    AdvPreferredLifetime 14400;
    AdvValidLifetime 86400;
  };

  RDNSS fddf:bf7:10:1:1::[GW_Number] {
    AdvRDNSSLifetime 600;
  };

  route fc00::/7 {
    AdvRouteLifetime 1200;
  };
};

etzt kann radvd als root auf der Konsole gestartet werden:

service radvd restart

DHCP isc-dhcp-server

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

   ddns-update-style none;
   option domain-name ".fffl";
   option domain-name-servers 10.129.1.[GW_Number]; # make sure to adjust to your gateway fm/ff ipv4
   default-lease-time 300;
   max-lease-time 3600;

   log-facility local7;
   subnet 10.129.0.0 netmask 255.255.0.0 {
     authorative;
     range 10.129.[IP_RANGE_START].1 10.129.[IP_RANGE_ENDE].254;# make sure to adjust to your allocated fm/ff ipv4 range
     option routers 10.129.1.[GW_Number]; # make sure to adjust to your gateway fm/ff ipv4
   }

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

Bitte eine leere Datei /etc/dhcp/static.conf erstellen:

touch /etc/dhcp/static.conf

Und jetzt noch die Konfigurationsdatei /etc/dhcp/dhcpd6.conf wird für IPv6 mit folgenden Zeilen definiert:

log-facility local7;

  subnet6 fddf:bf7:10:1::/64 {
    option dhcp6.name-servers fddf:bf7:10:1:1::[GW_Number];  # make sure to adjust to your gateway fm/ff ipv6
    option dhcp6.domain-search "fffl";
  }

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

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
#DHCPDv4_CONF=/etc/dhcp/dhcpd.conf
#DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
#DHCPDv4_PID=/var/run/dhcpd.pid
#DHCPDv6_PID=/var/run/dhcpd6.pid

# Additional options to start dhcpd with.
#       Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
OPTIONS="-4"

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

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

dhcpd -f -d

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

service isc-dhcp-server restart

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

# Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf).
DHCPD_CONF=/etc/dhcp/dhcpd6.conf

# Path to dhcpd's PID file (default: /var/run/dhcpd.pid).
DHCPD_PID=/var/run/dhcpd6.pid

# Additional options to start dhcpd with.
#   Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead
OPTIONS="-6"

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

Bitte eine leere Datei /etc/dhcp/static.conf erstellen:

touch /var/lib/dhcp/dhcpd6.leases

Kopieren Sie das bestehende Init-Skript des DHCP-Servers, um ein separates Skript für den DHCPv6-Dienst zu erstellen:

cp /etc/init.d/isc-dhcp-server /etc/init.d/isc-dhcp6-server

Bearbeite /etc/init.d/isc-dhcp6-server und bearbeite folgendes: Ersetzte

# Provides:          isc-dhcp-server

durch:

# Provides:          isc-dhcp6-server

Änderung 2: Pfad zur Konfigurationsdatei anpassen

Ersetzte:

DHCPD_DEFAULT="${DHCPD_DEFAULT:-/etc/default/isc-dhcp-server}"

durch:

DHCPD_DEFAULT="${DHCPD_DEFAULT:-/etc/default/isc-dhcp6-server}"

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

update-rc.d isc-dhcp6-server defaults

DHCP Server für Ipv4 und Ipv6 neustarten

service isc-dhcp-server restart
service isc-dhcp6-server restart

DNS bind9

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

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

options {
        directory "/var/cache/bind";

        # Nur Mesh/localhost — kein Listen auf Hoster-GUA (IPv6-Leak/Abuse)
        listen-on { 10.129.0.0/16; };
        listen-on-v6 { fddf:bf7:10:1::/64; };

        # DNS Anfragen dürfen nur über den VPN angefragt werden.
        forwarders {
                10.128.0.1;
                fd7d:76ee:e68f:a993::1;
        };
        forward only;
        dnssec-validation no;
        auth-nxdomain no; # conform to RFC1035
        allow-query { 10.129.0.0/16; fddf:bf7:10:1::/64; };
        recursion yes;
        allow-recursion { 10.129.0.0/16; fddf:bf7:10:1::/64; };
};

Bind9 für die Konfiguration stoppen

service bind9 stop

Der Zone Ordner muss angelegt werden:

mkdir -p /etc/bind/zones
cd /etc/bind/zones
git clone https://github.com/freifunk-flensburg/dns_fffl

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

//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "fffl" {
        type master;
        file "/etc/bind/zones/db.fffl";
};

zone "129.10.in-addr.arpa" {
        type master;
        file "/etc/bind/zones/10.129.zone";
};

Bind9 Dienst wieder starten

service bind9 start
service bind9 status

VPN

VPN Anbieter

Alle genannten VPN-Anbieter geben an, keine Protokolle (Logs) über die Aktivitäten ihrer Nutzer zu speichern. Ob diese Angaben tatsächlich der Realität entsprechen, muss jedoch kritisch hinterfragt werden.

Anbieter Standort VPN-Protokoll Bandbreite Traffic IPv4 IPv6 Kosten Logs / Datenschutz Bemerkungen
AirVPN Perugia, Italien OpenVPN/WireGuard recht voll flat JA JA Halloween/Weihnachten oft im Sale führt angeblich keine Logs / RAM-Disks damals internes wechseln der IP-Adresse (VPN stürtzt ab)
hide.me Labuan, Malaysia OpenVPN/WireGuard flat JA JA führt angeblich keine logs nicht getestet
mullvad Göteborg, Schweden OpenVPN/WireGuard flat JA JA dauerhaft 5 Euro Durchsuchungsbeschluss 2023 / (RAM-Disks) Einer von den Besitzer hat eine Rechte Partei unterstützt: Donation controversy
PIA Denver, Colorado (USA) OpenVPN/WireGuard flat JA Nein ? Halloween oft im Sale führt angeblich keine logs / (RAM-Disks) nicht getestet
protonvpn Genf, Schweiz OpenVPN/WireGuard flat JA JA Transparenzbericht / Festplattenverschlüsselung Für Neutralität: P2P-Server mit IPv6 nutzen filter deaktivieren. Proton Mail FBI-Vorfall 2026

OpenVPN

apt-get install openvpn

OpenVPN Konfigurationsdatei schreiben:

nano /etc/openvpn/exit-vpn.conf
client
dev tun
proto udp
port 443
remote de.vpn.airdns.org
resolv-retry infinite
remote-cert-tls server
cipher AES-256-CBC
comp-lzo no
verb 3
explicit-exit-notify 5
rcvbuf 262144
sndbuf 262144

#Connect to random server
remote-random

#restart after n seconds pass without reception of a ping or other packet from remote. 
ping-restart 20

# Most clients don't need to bind to
# a specific local port number.
nobind

# Try to preserve some state across restarts.
persist-key
persist-tun

#Disabled Logging
log /dev/null
status /dev/null

#############################
script-security 2
route-noexec
up /root/bin/vpn.up
down /root/bin/vpn.down
#############################
ping 10
tun-ipv6

Beim starten von openvpn werden die routen replaced, dafür müssen scripte angelegt werden:

mkdir /root/bin
nano /root/bin/vpn.up
#!/bin/sh
/sbin/ip route replace default dev exit-vpn table 42
/sbin/ip -6 route replace default dev exit-vpn table 42
/sbin/ip route replace 10.4.0.1/32 dev exit-vpn
/sbin/ip route replace 10.5.0.1/32 dev exit-vpn
/sbin/ip -6 route replace fde6:7a:7d20:4::1/128 dev exit-vpn 2>/dev/null || true
nano /root/bin/vpn.up
#!/bin/sh
/sbin/ip route del default dev exit-vpn table 42
/sbin/ip -6 route del default dev exit-vpn table 42
/sbin/ip route del 10.4.0.1/32 dev exit-vpn
/sbin/ip route del 10.5.0.1/32 dev exit-vpn
/sbin/ip -6 route del fde6:7a:7d20:4::1/128 dev exit-vpn 2>/dev/null || true

Folgende Dateien müssen ausführbar sein:

chmod +x /root/bin/vpn.up
chmod +x /root/bin/vpn.down

OpenVPN check

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

nano /root/bin/check-vpn.sh
  #!/bin/bash
  
  # Test gateway is connected to VPN
  test=$(ping -q -I tun0 8.8.8.8 -c 4 -i 1 -W 5 | grep 100 )
  
  if [ "$test" != "" ]
   then
     echo "VPN nicht da - Neustart!"
     service openvpn restart      # Fehler - VPN nicht da - Neustart
   else
     echo "alles gut"
  fi

Dann noch das Script ausführbar machen:

chmod +x /root/bin/check-vpn.sh

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

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

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

service cron restart

Dieses Script stammt von Freifunk Lippe Gateway, danke dafür

WireGuard

Wireguard-tools muss installiert werden

apt-get install wireguard-tools

In der WireGuard config sind routen drin, die gesetzt werden, damit die Verbindung ins Internet aufgebaut werden können, die ,,Table = off" darf nicht aktiviert werden.

nano /etc/wireguard/wg-exit.conf
[Interface]
Address = 10.162.38.142/32,fd7d:76ee:e68f:a993:d66c:f49f:dbf5:a73c/128
PrivateKey = 
MTU = 1320
DNS = 10.128.0.1, fd7d:76ee:e68f:a993::1

Table = off
PostUp = /sbin/ip route replace default dev %i table 42
PostUp = /sbin/ip -6 route replace default dev %i table 42
PostUp = ip route replace 10.128.0.1/32 dev %i
PostUp = ip -6 route replace fd7d:76ee:e68f:a993::1/128 dev %i 2>/dev/null || true

PostDown = ip route replace unreachable default table 42
PostDown = ip -6 route replace unreachable default table 42
PostDown = ip route del 10.128.0.1/32 dev %i 2>/dev/null || true
PostDown = ip -6 route del fd7d:76ee:e68f:a993::1/128 dev %i 2>/dev/null || true

[Peer]
PublicKey = 
PresharedKey = 
Endpoint = de3.vpn.airdns.org:1637
AllowedIPs = 0.0.0.0/0,::/0
PersistentKeepalive = 15
systemctl enable wg-quick@wg-exit
systemctl status wg-quick@wg-exit

WireGuard check

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

nano /etc/cron.d/vpncheck
*/5 * * * * root /usr/local/sbin/wg-watchdog.sh >/dev/null 2>&1
#!/bin/bash
# WireGuard-Watchdog: ping über wg0, bei Ausfall wg-quick@wg0 neu starten.
#
# Crontab (root), z.B. alle 5 Minuten:
#   */5 * * * * /usr/local/sbin/wg-watchdog.sh >/dev/null 2>&1
#
# Optional überschreiben:
#   IFACE=wg0 UNIT=wg-quick@wg0 TARGET=1.1.1.1 /usr/local/sbin/wg-watchdog.sh

set -u

IFACE="${IFACE:-wg-exit}"
UNIT="${UNIT:-wg-quick@${IFACE}}"
TARGET="${TARGET:-8.8.8.8}"
COUNT="${COUNT:-4}"
INTERVAL="${INTERVAL:-1}"
WAIT="${WAIT:-5}"
LOCK="${LOCK:-/run/wg-watchdog.lock}"
LOG="${LOG:-/var/log/wg-watchdog.log}"

log() {
  local msg
  msg="$(date '+%F %T') $*"
  echo "$msg"
  if [[ -w "$(dirname "$LOG")" ]] || [[ -w "$LOG" ]]; then
    echo "$msg" >>"$LOG" 2>/dev/null || true
  fi
}

# Kein paralleler Lauf (cron-Überlappung)
exec 9>"$LOCK"
if ! flock -n 9; then
  exit 0
fi

if ! command -v ping >/dev/null 2>&1; then
  log "ERROR: ping nicht gefunden"
  exit 1
fi

if ! ip link show "$IFACE" >/dev/null 2>&1; then
  log "VPN nicht da ($IFACE fehlt) — Neustart $UNIT"
  systemctl restart "$UNIT"
  exit $?
fi

# -q still, -I Quell-Interface, Exit != 0 bei Verlust / unerreichbar
if ping -q -I "$IFACE" -c "$COUNT" -i "$INTERVAL" -W "$WAIT" "$TARGET" >/dev/null 2>&1; then
  log "alles gut ($IFACE -> $TARGET)"
  exit 0
fi

log "VPN nicht da (Ping $TARGET über $IFACE fehlgeschlagen) — Neustart $UNIT"
systemctl restart "$UNIT"
rc=$?
if [[ "$rc" -eq 0 ]]; then
  log "Neustart $UNIT OK"
else
  log "ERROR: Neustart $UNIT Exit $rc"
fi
exit "$rc"

Firewall

Hoster Firewall

Wenn der Hoster Firewall Regeln unterstützt, die man selber anlegen kann, sollte man dies machen, damit nur die Ports offen sind, die man wirklich braucht:

iptables

Firewalld

Quellen:

Texte Vorlagen wurden teilweise von: Freifunk Lippe Gateway übernommen, danke dafür

Batman-adv: Gateways

Generic Freemesh Gateway

Freemesh Gateway

Gateway-Dokumentation: Cleanup

Freifunk Hamburg: IPv4 DHCP konfigurieren

Stack Overflow: IP-Adresse aus ifconfig auslesen

Freifunk-Flensburg-Gateway