Freifunk

Gateway Konfiguration

System

apt-get install sudo dbus tmux htop iotop zsh git
wget http://git.grml.org/f/grml-etc-core/etc/zsh/zshrc
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. gw01.marburg.freifunk.net).

/etc/sysctl.conf

  • 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 http://repo.universe-factory.net/debian/ sid main" | sudo tee -a /etc/apt/sources.list.d/freifunk.list
echo "deb [arch=amd64] http://debian.draic.info/ wheezy main" | sudo tee -a /etc/apt/sources.list.d/freifunk.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 16EF3F64CB201D9C
sudo apt-get update
sudo apt-get install alfred alfred-json batadv-vis batctl fastd

/etc/network/interfaces

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

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

/etc/fastd/ffmr

fastd.conf

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.conf

secret "0000…ffff";

peers/GW-gwXX

key "ffff…0000";

/etc/dhcp/dhcpd.conf

# 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 "marburg.link";

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 10.128.0.0 netmask 255.255.192.0 {
	authoritative;
	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 ntp01.marburg.link;
	option interface-mtu 1280;
}

/etc/default/isc-dhcp-server

INTERFACES="ffmr-br"
sudo systemctl enable isc-dhcp-server
sudo systemctl start isc-dhcp-server

/etc/radvd.conf

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

/etc/systemd/system/alfred@.service

# 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.
[Unit]
Description=A.L.F.R.E.D. (connection %I)
After=network.target

[Service]
Type=simple
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

[Install]
WantedBy=multi-user.target
sudo systemctl enable alfred@ffmr.service
sudo systemctl start alfred@ffmr.service

Batadv-vis Server

/etc/systemd/system/batadv-vis@.service

[Unit]
Description=batadv-vis server (connection %I)
Requires=alfred@%i.service

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

[Install]
WantedBy=multi-user.target
sudo systemctl enable batadv-vis@ffmr
sudo systemctl start batadv-vis@ffmr

Alfred Announce

git clone https://github.com/freifunk-mwu/ffnord-alfred-announce.git

/etc/sudoers.d/map

map ALL = NOPASSWD: /usr/sbin/batctl

/etc/systemd/system/alfred-announce@.service

[Unit]
Description=announces information on the batman network (connection %I)
Requires=alfred@%i.service

[Service]
Type=oneshot
User=map
ExecStart=/home/map/ffnord-alfred-announce/announce.sh -b %i-bat -i %i-br -f %i-fastd

/etc/systemd/system/alfred-announce@ffmr.timer

[Unit]
Description=announces information on the batman network (connection %I)
Requires=alfred@%i.service

[Timer]
OnBootSec=0
OnUnitActiveSec=60
Persistent=false

[Install]
WantedBy=timers.target
sudo systemctl enable alfred-announce@ffmr.timer
sudo systemctl start alfred-announce@ffmr.timer

NAT + iptables

sudo iptables -t nat -A POSTROUTING -s 10.128.0.0/18 -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 10.128.0.0/18 --dport 25 -j REJECT
sudo iptables -A FORWARD -d 10.0.0.0/8 -o eth0 -j REJECT --reject-with icmp-net-unreachable
sudo iptables -A FORWARD -d 172.16.0.0/12 -o eth0 -j REJECT --reject-with icmp-net-unreachable
sudo iptables -A FORWARD -d 192.168.0.0/16 -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

/etc/unbound/unbound.conf

server:
    # 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: 127.0.0.1
    interface: ::1
    interface: 10.128.0.XXX
    interface: 2a06:4b00:1000::a80:2XX
    access-control: 10.128.0.0/18 allow
    access-control: 2a06:4b00:1000::/56 allow
sudo systemctl enable unbound
sudo systemctl start unbound

yolokey-server

sudo apt-get install python3-pip python3-dev
git clone https://github.com/hackspace-marburg/yolokey-server

/etc/sudoers.d/map

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

/etc/systemd/system/yolokey-server.service

[Unit]
Description=Automatic deployment of fastd public keys. Accept everyone's keys!
After=network.target

[Service]
Type=simple
User=map
Environment="FASTD_PEERS_DIR=/etc/fastd/ffmr/peers/" "FASTD_SITE=ffmr" "TRAVIS_REPO_SLUG=hackspace-marburg/ffmr-peers" "TRAVIS_TOKEN=XXXX"
WorkingDirectory=/home/map/yolokey-server
ExecStart=/home/map/yolokey-server/bootstrap.sh

[Install]
WantedBy=multi-user.target
sudo systemctl enable yolokey-server.service
sudo systemctl start yolokey-server.service

/etc/nginx/sites-enabled/api_marburg_freifunk_net.conf

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

	server_name api.marburg.freifunk.net;

	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/;
	}
}

/etc/nginx/conf.d/default.conf

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

	server_name gw01.marburg.freifunk.net;
	server_name _;

	location / {
		rewrite ^(.*)$ https://gw01.marburg.freifunk.net$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/gw01.marburg.freifunk.net/privkey;
        ssl_certificate /var/lib/acme/live/gw01.marburg.freifunk.net/fullchain;
        ssl_trusted_certificate /var/lib/acme/live/gw01.marburg.freifunk.net/chain;

	server_name gw01.marburg.freifunk.net;
	server_name _;

	location / {
		return 403;
	}

	location /yolokey/ {
		proxy_pass http://[::1]:8081/;
	}
}
sudo acmetool want gw01.marburg.freifunk.net out.gw01.marburg.freifunk.net

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.

Installation

  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
DEHYDRATED_USER=www-data
DEHYDRATED_GROUP=www-data

CHALLENGETYPE="http-01"

BASEDIR="/etc/dehydrated"
DOMAINS_TXT="${BASEDIR}/domains.txt"
CERTDIR="${BASEDIR}/certs"
ACCOUNTDIR="${BASEDIR}/accounts"
WELLKNOWN="${BASEDIR}/well-known"

KEY_ALGO=secp384r1
CONTACT_EMAIL=freifunk@hsmr.cc

root@gw01 /etc/dehydrated # cat domains.txt
gw01.marburg.freifunk.net api.marburg.freifunk.net firmware.marburg.freifunk.net map.marburg.freifunk.net opkg.marburg.link update.marburg.link

Konfiguration, nginx

server {
        ssl_certificate_key /etc/dehydrated/certs/gw01.marburg.freifunk.net/privkey.pem;
        ssl_certificate /etc/dehydrated/certs/gw01.marburg.freifunk.net/cert.pem;
        ssl_trusted_certificate /etc/dehydrated/certs/gw01.marburg.freifunk.net/fullchain.pem;

        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
[Unit]
Description=Renew Let's Encrypt certificates

[Service]
Type=oneshot
RequiredBy=nginx
ExecStart=/usr/bin/dehydrated -c
ExecStartPost=/bin/systemctl reload nginx

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

[Timer]
OnCalendar=04:15
Persistent=true

[Install]
WantedBy=timers.target