Gateway Konfiguration
alles zu fuß weil lol egal
System
apt-get install sudo tmux git timedatectl set-timezone Europe/Berlin hostnamectl set-hostname gwNN useradd -m -U -G sudo user
- Set
PermitRootLogin
in/etc/ssh/sshd_config
tono
; appendAllowGroups sudo
- Match
/etc/hosts
with the previously set hostname. Do not forget to set a FQDN (e.g. gw01.marburg.freifunk.net).
/etc/sudoers.d/99-ffmr
# do not as root for password root ALL=(ALL:ALL) NOPASSWD: ALL # Allow members of group sudo to execute any command without providing password %sudo ALL=(ALL:ALL) NOPASSWD: ALL
GRUB
Serial Console
/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS1,115200" GRUB_TERMINAL="serial" GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=1 --word=8 --parity=no --stop=1"
update-grub
/etc/sysctl.d/99-ffmr.conf
# IP forwarding net.ipv4.ip_forward = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv6.conf.all.forwarding = 1 # 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
/etc/systemd/network/10-eth0.link
[Match] MACAddress=aa:aa:aa:aa:aa:aa [Link] Name=eth0
sudo update-initramfs -k all -u
General networking packages
sudo apt-get install bridge-utils isc-dhcp-server radvd unbound
Freifunk packages
sudo apt install batctl fastd
/etc/network/interfaces
# Freifunk Marburg auto ffmr-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 mtu 1280 iface ffmr-br inet6 static address 2a06:4b00:1000::a80:XXX netmask 64 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 orig_interval 10000 # pick one, or none, lol idk # post-up /usr/sbin/batctl -m $IFACE gw server 96mbit/96mbit # post-up batctl meshif $IFACE gw server 960mbit/960mbit pre-down /sbin/brctl delif ffmr-br $IFACE || true allow-hotplug ffmr-fastd-1 iface ffmr-fastd-1 inet6 manual hwaddress 00:01:01:80:00:02 post-up ip link set dev ffmr-fastd-1 up post-up batctl meshif ffmr-bat if add $IFACE post-up ip link set dev ffmr-bat up allow-hotplug ffmr-fastd-2 iface ffmr-fastd-2 inet6 manual hwaddress 00:01:01:80:00:02 post-up ip link set dev ffmr-fastd-2 up post-up batctl meshif ffmr-bat if add $IFACE post-up ip link set dev ffmr-bat up allow-hotplug ffmr-fastd-3 iface ffmr-fastd-3 inet6 manual hwaddress 00:01:01:80:00:02 post-up ip link set dev ffmr-fastd-3 up post-up batctl meshif ffmr-bat if add $IFACE post-up ip link set dev ffmr-bat up allow-hotplug ffmr-fastd-4 iface ffmr-fastd-4 inet6 manual hwaddress 00:01:01:80:00:02 post-up ip link set dev ffmr-fastd-4 up post-up batctl meshif ffmr-bat if add $IFACE post-up ip link set dev ffmr-bat up allow-hotplug ffmr-fastd-5 iface ffmr-fastd-5 inet6 manual hwaddress 00:01:01:80:00:02 post-up ip link set dev ffmr-fastd-5 up post-up batctl meshif ffmr-bat if add $IFACE post-up ip link set dev ffmr-bat up allow-hotplug ffmr-fastd-6 iface ffmr-fastd-6 inet6 manual hwaddress 00:01:01:80:00:02 post-up ip link set dev ffmr-fastd-6 up post-up batctl meshif ffmr-bat if add $IFACE post-up ip link set dev ffmr-bat up
/etc/fastd/ffmr
fastd-base.conf
log level debug; log to syslog level debug; hide ip addresses yes; hide mac addresses yes; method "null"; method "salsa2012+umac"; method "null+salsa2012+umac"; mtu 1312; mode tap; include "secret.conf"; include peers from "peers";
secret.conf
secret "0000…ffff";
peers/GW-gwXX
key "ffff…0000";
systemctl cat fastd@
# /etc/systemd/system/fastd@.service [Unit] Description=Fast and Secure Tunnelling Daemon (fastd no %I) After=network.target [Service] Type=notify ExecStart=/usr/bin/fastd \ --syslog-level info \ --syslog-ident fastd@%I \ --status-socket /var/run/ffmr-fastd-%I.status \ --interface ffmr-fastd-%I \ --bind any:1000%I \ --config /etc/fastd/ffmr/fastd-base.conf ExecReload=/bin/kill -HUP $MAINPID [Install] WantedBy=multi-user.target
$ for i in $(seq 1 6); do systemctl enable --now fastd@$i; done
fastd Peer Synchronization
Only if the yolokeyserver is not in use.
systemctl cat fastd-peers-pull.service # /etc/systemd/system/fastd-peers-pull.service [Unit] Description=Refresh fastd ffmr peers [Service] WorkingDirectory=/etc/fastd/ffmr/peers ExecStart=/usr/bin/git pull ExecStartPost=/usr/bin/systemctl reload fastd@1 ExecStartPost=/usr/bin/systemctl reload fastd@2 ExecStartPost=/usr/bin/systemctl reload fastd@3 ExecStartPost=/usr/bin/systemctl reload fastd@4 ExecStartPost=/usr/bin/systemctl reload fastd@5 ExecStartPost=/usr/bin/systemctl reload fastd@6 systemctl cat fastd-peers-pull.timer # /etc/systemd/system/fastd-peers-pull.timer [Unit] Description=Refresh fastd ffmr peers every five minutes [Timer] OnCalendar=*:0/5 [Install] WantedBy=timers.target
/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
INTERFACESv4="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 | nftables)
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
nftables
/etc/nftables.conf
#!/usr/sbin/nft -f flush ruleset table inet filter { chain input { type filter hook input priority filter; } chain forward { type filter hook forward priority filter; policy drop; # ipv4 (ipv6 may be asymmetric): allow related, drop invalid (conntrack) #meta nfproto ipv4 oifname "eth0" ct state related,established accept; #meta nfproto ipv4 oifname "eth0" ct state invalid drop; # mss clamping (path mtu discovery is hard) iifname "eth0" oifname "ffmr-br" meta l4proto tcp tcp flags & (syn|rst) == syn tcp option maxseg size set rt mtu; iifname "ffmr-br" oifname "eth0" meta l4proto tcp tcp flags & (syn|rst) == syn tcp option maxseg size set rt mtu; # do not forward to martians oifname "eth0" ip daddr { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10 } reject with icmpx type no-route; oifname "eth0" ip6 daddr { fc00::/7 } reject with icmpx type no-route; # reject port 25 oifname "eth0" tcp dport 25 reject with icmpx type admin-prohibited; # allow freifunk to internet iifname "ffmr-br" oifname "eth0" ip saddr { 10.128.0.0/18 } accept; iifname "ffmr-br" oifname "eth0" ip6 saddr { 2a06:4b00:1000::/56 } accept; iifname "eth0" oifname "ffmr-br" ip daddr { 10.128.0.0/18 } accept; iifname "eth0" oifname "ffmr-br" ip6 daddr { 2a06:4b00:1000::/56 } accept; } chain output { type filter hook output priority filter; } } table inet raw { chain PREROUTING { type filter hook prerouting priority raw; policy drop; # rpfilter (BCP 38) fib saddr . iif oif != 0 accept } } table inet nat { chain PREROUTING { type nat hook prerouting priority dstnat; # load balance fastd udp dport 10000 redirect to numgen inc mod 6 map { 0 : 10001, 1 : 10002, 2 : 10003, 3 : 10004, 4 : 10005, 5 : 10006 }; } } table ip nat { chain POSTROUTING { type nat hook postrouting priority srcnat; policy accept; oifname "eth0" ip saddr 10.128.0.0/18 snat to 195.138.247.20; } }
sudo /etc/nftables.conf
/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 private-domain: "dn42" domain-insecure: "dn42" local-zone: "20.172.in-addr.arpa." nodefault local-zone: "22.172.in-addr.arpa." nodefault local-zone: "23.172.in-addr.arpa." nodefault local-zone: "d.f.ip6.arpa." nodefault forward-zone: name: "dn42" forward-addr: fd42:d42:d42:53::1 forward-addr: 172.22.0.53 forward-zone: name: "20.172.in-addr.arpa" forward-addr: fd42:d42:d42:53::1 forward-addr: 172.22.0.53 forward-zone: name: "22.172.in-addr.arpa" forward-addr: fd42:d42:d42:53::1 forward-addr: 172.22.0.53 forward-zone: name: "23.172.in-addr.arpa" forward-addr: fd42:d42:d42:53::1 forward-addr: 172.22.0.53 forward-zone: name: "d.f.ip6.arpa" forward-addr: fd42:d42:d42:53::1 forward-addr: 172.22.0.53
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
- dehydrated-Repository nach
/opt/dehydrated
geklont und letzten Tag - v0.7.0 - auschecken. 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