Gateway Konfiguration


apt-get install sudo dbus tmux htop iotop zsh git
mv zshrc /etc/zsh/zshrc; cp /etc/zsh/zshrc /etc/zsh/newuser.zshrc.recommended
timedatectl set-timezone Europe/Berlin
hostnamectl set-hostname gwNN
useradd -m -U -s /bin/zsh -G sudo user
  • Set PermitRootLogin in /etc/ssh/sshd_config to no; append AllowGroups sudo
  • Match /etc/hosts with the previously set hostname. Do not forget to set a FQDN (e.g.


  • Uncomment
    • net.ipv4.ip_forward=1
    • net.ipv6.conf.all.forwarding=1
    • net.ipv4.conf.default.rp_filter=1
    • net.ipv4.conf.all.rp_filter=1
  • Append
    • # Disable IPv6 autoconf
      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
      # Do not process traffic on bridges with iptables
      net.bridge.bridge-nf-call-arptables = 0
      net.bridge.bridge-nf-call-ip6tables = 0
      net.bridge.bridge-nf-call-iptables = 0

General networking packages

sudo apt-get install bridge-utils isc-dhcp-server radvd

Freifunk packages

echo "deb sid main" | sudo tee -a /etc/apt/sources.list.d/freifunk.list
echo "deb [arch=amd64] wheezy main" | sudo tee -a /etc/apt/sources.list.d/freifunk.list
sudo apt-key adv --keyserver --recv 16EF3F64CB201D9C
sudo apt-get update
sudo apt-get install alfred alfred-json batadv-vis batctl fastd


# Freifunk Marburg
auto f-br
iface ffmr-br inet static
	bridge_ports	none
	bridge_fd	0
	bridge_maxwait	0
	address		10.128.0.XXX

iface ffmr-br inet6 static
	address 2a06:4b00:1000::a80:2XX
	netmask 64

allow-hotplug ffmr-fastd
iface ffmr-fastd inet6 manual
	hwaddress	01:01:01:80:00:XX
	pre-up		/sbin/modprobe batman-adv
	post-up		/sbin/ip link set dev ffmr-fastd up
	post-up		/usr/sbin/batctl -m ffmr-bat if add $IFACE
	post-up		/sbin/ip link set dev ffmr-bat up

allow-hotplug ffmr-bat
iface ffmr-bat inet6 manual
	pre-up		/sbin/modprobe batman-adv
	post-up		/sbin/brctl addif ffmr-br $IFACE
	post-up		/usr/sbin/batctl -m $IFACE it 10000
	post-up		/usr/sbin/batctl -m $IFACE gw server 96mbit/96mbit
	pre-down	/sbin/brctl delif ffmr-br $IFACE || true



log level debug;
log to syslog level debug;

hide ip addresses yes;
hide mac addresses yes;

status socket "/var/run/ffmr-fastd.status";

interface "ffmr-fastd";

method "null";
method "salsa2012+umac";
method "null+salsa2012+umac";

mtu 1280;
mode tap;

bind PUBLIC_IPV4:3334 interface "eth0";
bind [PUBLIC_IPV6]:3334 interface "eth0";
bind PUBLIC_IPV4:10000 interface "eth0";
bind [PUBLIC_IPV6]:10000 interface "eth0";

include "secret.conf";
include peers from "peers";


secret "0000…ffff";


key "ffff…0000";


# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

option domain-name "";

default-lease-time 600;
max-lease-time 3600;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

subnet netmask {
	range 10.128.XX.1 10.128.XX.254;
	option routers 10.128.0.XX;
	option domain-name-servers 10.128.0.XX;
	option ntp-servers;
	option interface-mtu 1280;


sudo systemctl enable isc-dhcp-server
sudo systemctl start isc-dhcp-server


interface ffmr-br {
	AdvSendAdvert on;
	MaxRtrAdvInterval 200;
	AdvLinkMTU 1280;
	prefix 2a06:4b00:1000::/64 {
	RDNSS 2a06:4b00:1000::a80:2XX {
sudo systemctl enable radvd
sudo systemctl start radvd


# This .service-file does not define a socket per instance because of compatibility reasons with older versions of alfred. Therefore can't start multiple instances.
Description=A.L.F.R.E.D. (connection %I)

ExecStart=/usr/sbin/alfred -m -i %i-br -b %i-bat
ExecStartPost=/bin/chown root:alfred /var/run/alfred.sock
ExecStartPost=/bin/chmod 0660 /var/run/alfred.sock

sudo systemctl enable alfred@ffmr.service
sudo systemctl start alfred@ffmr.service

Batadv-vis Server


Description=batadv-vis server (connection %I)

ExecStart=/usr/sbin/batadv-vis -s -i %i-bat

sudo systemctl enable batadv-vis@ffmr
sudo systemctl start batadv-vis@ffmr

Alfred Announce

git clone


map ALL = NOPASSWD: /usr/sbin/batctl


Description=announces information on the batman network (connection %I)

ExecStart=/home/map/ffnord-alfred-announce/ -b %i-bat -i %i-br -f %i-fastd


Description=announces information on the batman network (connection %I)


sudo systemctl enable alfred-announce@ffmr.timer
sudo systemctl start alfred-announce@ffmr.timer

NAT + iptables

sudo iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --to-source XXX.XXX.XXX.XXX
sudo iptables -A FORWARD -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -o eth0 -m state --state INVALID -j DROP
sudo iptables -A FORWARD -i eth0 -o ffmr-br -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
sudo iptables -A FORWARD -i ffmr-br -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
sudo iptables -A FORWARD -p tcp -s --dport 25 -j REJECT
sudo iptables -A FORWARD -d -o eth0 -j REJECT --reject-with icmp-net-unreachable
sudo iptables -A FORWARD -d -o eth0 -j REJECT --reject-with icmp-net-unreachable
sudo iptables -A FORWARD -d -o eth0 -j REJECT --reject-with icmp-net-unreachable

sudo ip6tables -A FORWARD -i eth0 -o ffmr-br -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
sudo ip6tables -A FORWARD -i ffmr-br -o eth0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
sudo ip6tables -A FORWARD -p tcp -s 2a06:4b00:1000::/56 --dport 25 -j REJECT
sudo ip6tables -t raw -A PREROUTING -m rpfilter -j ACCEPT
sudo ip6tables -t raw -A PREROUTING -j DROP
sudo ip6tables -A FORWARD -d fc00::/7 -o eth0 -j REJECT --reject-with icmp6-no-route

sudo iptables-save | sudo tee /etc/iptables.up.rules
echo -e '#!/bin/sh\n/sbin/iptables-restore < /etc/iptables.up.rules' | sudo tee /etc/network/if-pre-up.d/iptables
sudo chmod +x /etc/network/if-pre-up.d/iptables

sudo ip6tables-save | sudo tee /etc/ip6tables.up.rules
echo -e '#!/bin/sh\n/sbin/ip6tables-restore < /etc/ip6tables.up.rules' | sudo tee /etc/network/if-pre-up.d/ip6tables
sudo chmod +x /etc/network/if-pre-up.d/ip6tables


    # The following line will configure unbound to perform cryptographic
    # DNSSEC validation using the root trust anchor.
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    interface: ::1
    interface: 10.128.0.XXX
    interface: 2a06:4b00:1000::a80:2XX
    access-control: allow
    access-control: 2a06:4b00:1000::/56 allow
sudo systemctl enable unbound
sudo systemctl start unbound


sudo apt-get install python3-pip python3-dev
git clone


map ALL = NOPASSWD: /bin/systemctl reload fastd@ffmr.service


Description=Automatic deployment of fastd public keys. Accept everyone's keys!

Environment="FASTD_PEERS_DIR=/etc/fastd/ffmr/peers/" "FASTD_SITE=ffmr" "TRAVIS_REPO_SLUG=hackspace-marburg/ffmr-peers" "TRAVIS_TOKEN=XXXX"

sudo systemctl enable yolokey-server.service
sudo systemctl start yolokey-server.service


server {
	listen 80;
	listen [::]:80;


	location / {
		rewrite ^(.*)$ https://$host$1 permanent;

	location /.well-known/acme-challenge/ {
		alias /var/lib/acme/challenges;
		try_files $uri =404;

	location /yolokey/ {
		proxy_pass http://[::1]:8081/;


server {
	listen 80 default_server;
	listen [::]:80 default_server ipv6only=on;

	server_name _;

	location / {
		rewrite ^(.*)$$1 permanent;

	location /.well-known/acme-challenge/ {
		alias /var/lib/acme/challenges;
		try_files $uri =404;

	location /yolokey/ {
		proxy_pass http://[::1]:8081/;

server {
	listen 443 default_server ssl;
	listen [::]:443 default_server ssl ipv6only=on;

        ssl_certificate_key /var/lib/acme/live/;
        ssl_certificate /var/lib/acme/live/;
        ssl_trusted_certificate /var/lib/acme/live/;

	server_name _;

	location / {
		return 403;

	location /yolokey/ {
		proxy_pass http://[::1]:8081/;
sudo acmetool want

ACME V2-Update

Hackisches Update um auf einem gut abgehangenen Debian via ACME v2 noch Zertifikate zu bekommen. Dieser Abschnitt ist als Update zu dem obigen gedacht.

Als Software wird dehydrated eingesetzt, da es minimale Abhängigkeiten hat - lediglich coreutils, curl und openssl.


  1. dehydrated-Repository nach /opt/dehydrated geklont und letzten Tag - v0.7.0 - auschecken.
  2. ln -s /opt/dehydrated/dehydrated /usr/bin/dehydrated

Konfiguration, dehydrated

root@gw01 /etc/dehydrated # ls -la
total 32
drwxr-xr-x  6 www-data www-data 4096 Jul 22 20:56 .
drwxr-xr-x 92 root     root     4096 Jul 22 20:05 ..
drwxr-xr-x  3 www-data www-data 4096 Jul 22 20:29 accounts
drwxr-xr-x  3 www-data www-data 4096 Jul 22 20:30 certs
drwx------  2 www-data www-data 4096 Jul 22 20:30 chains
-rw-r--r--  1 root     root      285 Jul 22 20:55 config
-rw-r--r--  1 root     root      144 Jul 22 20:21 domains.txt
drwxr-xr-x  2 www-data www-data 4096 Jul 22 20:31 well-known

root@gw01 /etc/dehydrated # cat config




root@gw01 /etc/dehydrated # cat domains.txt

Konfiguration, nginx

server {
        ssl_certificate_key /etc/dehydrated/certs/;
        ssl_certificate /etc/dehydrated/certs/;
        ssl_trusted_certificate /etc/dehydrated/certs/;

        location ^~ /.well-known/acme-challenge {
                alias /etc/dehydrated/well-known;

Konfiguration, systemd

root@gw01 ~ # systemctl cat letsencrypt-renew.service
# /etc/systemd/system/letsencrypt-renew.service
Description=Renew Let's Encrypt certificates

ExecStart=/usr/bin/dehydrated -c
ExecStartPost=/bin/systemctl reload nginx

root@gw01 ~ # systemctl cat letsencrypt-renew.timer
# /etc/systemd/system/letsencrypt-renew.timer
Description=Daily renewal of Let's Encrypt's certificates