neunzehn83.de

Ein Mann, ein Blog, kein Plan.

Debian Router statt FritzBox mit Glasfaser von der Deutschen Giganetz

Ich habe nun einen Glasfaser-Anschluss von der Deutschen Giganetz (DGN). Yay! Ein Debian Linux soll das Routing übernehmen, wie zuvor auch schon für meinen DSL-Anschluss.

Mein Router ist ein LXC-Container auf einem Raspberry Pi4 mit Debian bookworm Linux. Wir wollen routen ganz ohne Klimbim, ausschließlich mit Systemd-Networkd und ein paar Scripts! Wir brauchen kein radvd oder wide-dhcp.

Der Pi hat einen separaten Netzwerk-Dongle zur PPPoE-Einwahl - dieser ist wahrscheinlich nicht unbedingt erforderlich, da PPPoE über ein VLAN stattfindet.

eth0: Internes Netzwerk
eth1: Patchkabel zum ONT (Glasfaser-Modem)

Von der DGN gibt es einen DS-Lite Anschluss mit 24h Zwangstrennung (!). Das IPv6 Subnetz ändert sich alle 24 Stunden. IPv4 gibt es nur über einen Tunnel zu einem AFTR mit Carrier-Grade-Nat.

Mit der PPPoE-Einwahl bekommen wir eine IPv6 und ein /56 IPv6 Subnetz. Ein /64 davon geben wir per RA/Router Advertisement in unser Netzwerk zur selbständigen Konfiguration der Clients (SLAAC).

Part 1: Netzwerk-Config für PPPoE

Wir benötigen ein VLAN mit der ID=7 für die PPPoe Einwahl:

root@rtr:~# vi /etc/systemd/network/00-vlan.netdev

[NetDev]
Name=myvlan
Kind=vlan

[VLAN]
Id=7

Dem Interface mit der Verbindung zum ONT geben wir dieses vlan (hier eth1).

root@rtr:~# vi /etc/systemd/network/10-eth1.netdev

[Match]
Name=eth1
Type=ether

[Network]
VLAN=myvlan
DHCP=no

Dem PPP-Interface sagen wir, dass es ein RA akzeptieren soll (das ist unser /56-Netz für Clients). DHCP (Client) wird benötigt um selbst via PPP eine einzelne IPv6 zu erhalten.

root@rtr:~# vi /etc/systemd/network/11-ppp0.network

[Match]
Name=ppp0
Type=ppp

[Network]
DHCP=ipv6
IPv6AcceptRA=yes
IPv6PrivacyExtensions=yes
KeepConfiguration=yes

[DHCPv6]
UseDelegatedPrefix=true
WithoutRA=solicit

Jetzt Netzwerk neustarten

systemctl restart systemd-networkd

Part 2: PPPoE Einwahl

Wir installieren die Tools ppp und pppoe und legen eine Config an. Außerdem packen wir die Zugangsdaten in eine Datei.

apt install ppp pppoe

root@rtr:~# vi /etc/ppp/peers/DGN

noipdefault
defaultroute
replacedefaultroute
hide-password
lcp-echo-interval 20
lcp-echo-failure 3
connect /bin/true
noauth
persist
noaccomp
default-asyncmap
plugin rp-pppoe.so
nic-myvlan					# Anpassen auf VLAN-Name
user "XXX@dgn.digital"		# Anpassen auf Username
nodetach
persist

root@rtr:~# vi /etc/ppp/chap-secrets

"XXX@dgn.digital" * "XXX"	# Anpassen Username und Passwort

PPPoE-Dienst anpassen vi /etc/systemd/system/pppoe.service

ExecStart=/usr/sbin/pppd call DGN

Hier den Config-Namen mit der PPPoE-Config (in /etc/ppp/peers) angeben. Hier: DGN

PPPoE-Einwahl!

systemctl restart pppoe

Mit systemctl status pppoe prüfen, ob die Verbindung geklappt hat. IPv6-Zugriff sollte nun funktionieren: ping6 heise.de.
Bei mir musste ich noch eine Route hinzufügen um IPv6-Konnektivität zu erhalten: ip -6 route add 0::/0 dev ppp0

Part 3: IPv4

Wir benötigen einen 4in6 Tunnel zum AFTR von DGN (bzw. Purtel, der tech. Provider von DGN)

ip -6 tunnel add ip6tnl mode ipip6 local <lokale IPv6> remote 2a01:41e3:ffff:cafe:face::3 dev eth1
ip addr add 192.0.0.2/29 peer 192.0.0.1 dev ip6tnl
ifconfig ip6tnl up
ip route add default via 192.0.0.1 dev ip6tnl

Damit sollte auf dem Router IPv4 funktionieren: ping 8.8.8.8

Part 4: Konfiguration für die Clients

Wir konfigurieren das interne Interface (hier: eth0) wie folgt:

root@rtr:# vi /etc/systemd/network/eth0.network

[Match]
Name=eth0
[Network]
Address=10.11.12.254/24

IPv6AcceptRA=yes
IPv6SendRA=yes
DHCPPrefixDelegation=yes
DHCPv6PrefixDelegation=yes

DHCPServer=true

[DHCPServer]
PoolOffset=100
PoolSize=100
EmitDNS=yes
DNS=10.11.12.254

[IPv6SendRA]
EmitDNS=true
DNS=fe80::1

Bei [Network] vergeben wir eine eigene IPv4 für den Router - das ist die Gateway-Adresse für alle v4-Verbindungen. Bei [DHCPServer] konfigurieren wir den v4 DNS: jeder Client bekommt eine IPv4 aus dem Pool 10.11.12.100-199.
Interessant ist hier, dass wir kein NAT in unserem Netzwerk brauchen! Die Pakete mit den privaten IPs gehen in den Tunnel und werden erst beimAFTR umgeschrieben.
Bei [IPv6SendRA] verteilen wir auch einen DNS via IPv6. Der Router selbst ist DNS-Server. Hier könnte auch ein öffentlicher IPv6-DNS-Server stehen.

Wenn der Router selbst der DNS-Server sein soll (um bspw. Adblocking-Aufgaben zu übernehmen) muss zusätzlich bspw. dnsmasq installiert und konfiguriert werden.

Damit Clients via ICMP die MTU der Pakete anpassen können müssen wir die Kommunikation zulassen:

iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Part 5: Automatisierung

Da die PPPoE-Verbindung nach 24h getrennt wird, muss bspw. die Default-Route und der IPv4-Tunnel nach jedem Verbinden erneut aufgebaut werden. Dazu kann man die Befehle in ein "IPv6-up" Script packen, welches PPPoE automatisch ausführt:

root@rtr:# vi /etc/ppp/ipv6-up.d/rtr

#!/bin/sh
sleep 1
ip -6 route add 0::/0 dev ppp0
sleep 1
ipv6=$(ip -6 addr show ppp0 | grep inet6 | awk -F '[ \t]+|/' '{print $3}' | grep -v '^\(::1\|fe80\)' | head -n1)
ip -6 tunnel add ip6tnl mode ipip6 local $ipv6 remote 2a01:41e3:ffff:cafe:face::3 dev eth1
ip addr add 192.0.0.2/29 peer 192.0.0.1 dev ip6tnl
ifconfig ip6tnl up
ip route add default via 192.0.0.1 dev ip6tnl

iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Das Script holt automatisch die IPv6 und nutzt diese als Tunnel-Eingang. Tunnel-Ausgang ist der AFTR von Purtel (aftr.fra.purtel.com). Das Script muss executable sein: chmod +x /etc/ppp/ipv6-up.d/rtr

Automatischer Reconnect

Damit die Zwangstrennung nicht in ungünstige Zeiten fällt, kommen wir ihr zuvor, indem wir täglich ppp neustarten und damit eine Neueinwahl auslösen. Zudem gibt es ein neues IPv6 Subnetz.

crontab -e

30 4 * * * systemctl restart pppoe

Part 6: ToDos

Das alles ist erst der Anfang! Wir benötigen zwangläufig noch eine Firewall (ufw) und eventuell die ein oder andere IPv6-Portfreigabe. Diese Portfreigabe soll dann auch trotz ständig wechselndem IPv6-Präfix von außen erreichbar sein. Auch wollen wir unterwegs, wenn nur IPv4 verfügbar ist, uns nach Hause verbinden! Ideen dazu folgen im nächsten Blog-Beitrag ..

OpenVPN in einem LXC-Container auf einem Raspberry Pi 4 mit Ubuntu

Der LXC-Container braucht ein "tun" device. Dazu gibt es viele Artikel im Internet. Keiner davon hat so richtig funktioniert, deshalb hier die Notiz an mich selbst.

Es ist eigentlich ganz einfach. Die Container-Config (/var/lib/lxc/<container-name>/config) benötigt folgende zwei Einträge:

lxc.cgroup2.devices.allow = c 10:200 rwm
lxc.mount.entry = /dev/net/tun dev/net/tun none bind,create=file

Ganz wichtig ist natürlich "cgroup2" (beachte: die Zwei) zu verwenden - ist ja klar!

Das ganze bezieht sich auf einen Privileged Container.

Debian Linux Fileserver für Windows und Mac Clients

Ich mag keine NAS-Boxen. Zu eingeschränkt, zu langsam, zu unflexibel. Natürlich besteht für mich der perfekte Fileserver aus einem Debian-System mit ein paar wenigen Standardpaketen. In diesem Fall Debian 10 Buster.

Idee: Für den Zugriff von Windows benötigen wir Samba, für Linux und Mac Clients genügt ein entsprechender SSH-Zugang für SSHFS.

Doch beim Zugriff mit SSHFS ergibt sich ein Problem..

Die Rechtesituation

Eigentlich einfach. Wir möchten verschiedene Linux-Systembenutzer. Gleichzeitig sind dies Samba-Nutzer. Über die Gruppenzugehörigkeit können Zugriffsrechte auf Verzeichnisebene für SSH vergeben werden.

Damit neu erzeugte Dateien der Gruppe gehören und nicht dem User selbst, müssen wir das SETGID Bit beim Hauptverzeichnis setzen.

chmod g+s /storage

Problem: neue Dateien haben je nach Umask des Clients(!) nur Leserechte für die Gruppe. Noch schlimmer: wird eine Datei kopiert, die auf dem Client nur Schreib-/Leserechte für den User und keine Rechte für die Gruppe hat, wird diese so auf den Fileserver kopiert - ganz egal welche Umask gilt. Das ist ein Problem, da andere User diese Datei dann nicht bearbeiten oder vielleicht sogar nicht einmal lesen können.

SSHFS ist auf Serverseite ein SFTP-Server. Genauer gesagt der sftp-server von OpenSSH. Dieser hat leider keine Möglichkeit wie bspw. bei Samba mit inherit permissions die Dateirechte beim Schreiben explizit zu setzen.

OpenSSH sftp-server patchen

Ich habe lange hierzu eine Lösung gesucht - mir erschien der Use-Case eigentlich straight-forward - scheinbar gibt es aber keine einfache Lösung. Auf folgenden Patch für den sftp-server von OpenSSH bin ich gestoßen:

https://bugzilla.mindrot.org/show_bug.cgi?id=1844

Dieser ermöglicht mit dem dann zur Verfügung stehenden "-m" Parameter eine Umask zu forcen. Leider hat es dieser Patch auch nach 10 Jahren noch nicht ins offizielle sftp-server-Paket von Debian geschafft. Außerdem genügt das forcen einer Umask nicht, wenn die Datei auf dem Client grundsätzlich zu wenig Rechte hat. Denn eine Umask erhöht niemals die Rechte.

Ade Standardpakete, selbst ist der Mann - wir erweitern den Patch um das wirkliche Forcieren von Permissions bei allen Schreibvorgängen.

Wir benötigen zunächst grundsätzliche Zugriff auf die Sourcen von Debian-Paketen:

vi /etc/apt/sources.list
deb-src http://ftp.debian.org/debian buster main contrib

apt update

Source holen

apt source openssh-sftp-server
cd openssh-7.9p1/

Patch anwenden

Ich habe den originalen Patch erweitert, so dass Permissions von Dateien nicht übernommen sondern immer die Permissions wie im "-m" Parameter angegeben gesetzt werden.

Der Unterschied zum Originalpatch:

--- sftp-server.c.2     2020-07-13 17:17:58.152172604 +0000
+++ sftp-server.c       2020-07-13 17:18:39.136288633 +0000
@@ -919,7 +919,7 @@
                if (r == -1)
                        status = errno_to_portable(errno);
        }
-       if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
+       if (permforce == 0 && a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
                logit("set \"%s\" mode %04o", name, a.perm);
                r = chmod(name, a.perm & 07777);
                if (r == -1)
@@ -972,7 +972,7 @@
                        if (r == -1)
                                status = errno_to_portable(errno);
                }
-               if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
+               if (permforce == 0 && a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
                        logit("set \"%s\" mode %04o", name, a.perm);
 #ifdef HAVE_FCHMOD
                        r = fchmod(fd, a.perm & 07777);    

Entweder der Reihe nach den Originalpatch anwenden, dann die zwei Änderungen oben oder hier auch als Komplett-Patch herunterladen.

wget https://neunzehn83.de/blog/files/2020/openssh-sftp-server-patch.diff
patch sftp-server.c openssh-sftp-server-patch.diff

Bauen & installieren

apt build-dep devscripts openssh-sftp-server
cd debian
debuild -b -uc -us
cd ../../
dpkg -i openssh-sftp-server_7.9p1-10+deb10u2_amd64.deb

Damit haben wir den openssh-ftp-server mit "-m" Parameter gebaut!

Konfiguration

Damit bei SSHFS-Verbindungen der neue Parameter auch genutzt wird, muss die openssh-Konfiguration entsprechend angepasst werden:

vi /etc/ssh/sshd_config
Subsystem sftp /usr/lib/openssh/sftp-server -m 770
/etc/init.d/sshd restart

Testen

Wir kopieren eine Datei mit den lokalen Rechten "700" auf ein SSHFS-Mount (hier: /mnt/files/test). Nach dem Kopieren hat die Datei die Rechte "770".

Mailjet und die Deliverability zu @t-online.de

Als kleiner Mailserver-Betreiber tut man sich bekanntlich schwer, eine gute Zustellbarkeit zu erreichen. Für wirklich wichtige E-Mails, bspw. transaktionale E-Mails eines Online-Shops wie Bestellbestätigungen usw., sollte man daher auf einen externen SMTP-Service zurückgreifen.

Da gibt es einige: Mailgun, Amazon SES, etc. Wer dann noch darauf achten muss oder will, dass die über den SMTP-Service versendeten Daten nicht in irgendwelchen US-Clouds landen hat es schon schwerer. Mailjet sieht hier nach einer ordentlichen Alternative aus.

Aus aktueller Erfahrung kann ich aber sagen, dass es dort selbst mit den bezahlten Paketen ohne exklusive IP immer wieder zu Problemen mit der Zustellbarkeit kommt. Insbesondere mit @t-online.de Adressen aber auch des öfteren zu @yahoo.de und ähnliche.

Ich wollte das zuerst nicht so recht glauben, dass so ein großer Anbieter solche Probleme mit der Zustellbarkeit zu einem der größten deutschen Mailprovider hat. Der Support wollte darauf aber nicht eingehen, hat das Problem aber bestätigt und als Alternative dazu nur ein Upgrade auf eine exklusive IP angeboten (Kosten: ab 50 Euro im Monat).

Da meiner Meinung nach eine exklusive IP nur mit entsprechend hohen Versandzahlen Sinn macht, scheidet für mich wie es scheint Mailjet als Mailversender aus.

Es ist verständlich, dass deren shared IP-ranges blacklist-anfällig sind, da darüber jeder free-user wilde E-Mails versenden darf. Warum bietet Mailjet dann aber keine premium shared IP-ranges an, welche nur bezahlte Accounts nutzen dürfen? Hier hätte Mailjet die bessere Kontrolle über blacklisting.

Ich bin also auf der Suche nach einer Alternative zu Mailjet, einem zuverlässigen SMTP-Service gehostet in Deutschland oder der EU. Selbstverständlich darf dieser Service auch etwas kosten. Das ist gar nicht so einfach, hier etwas zu finden. Vorschläge willkommen.

Kündigungs-Bluff: 25% Rabatt bei UnityMedia / KabelBW

Da ich demnächst in ein Gebiet umziehe, das nicht von UnityMedia versorgt wird, habe ich meinen Kabelanschluss kürzlich gekündigt. Und das kann ich allen Bestandskunden auch nur empfehlen, denn: Seit meiner Kündigung erhalte ich immer tollere Angebote von UnityMedia.

Zuerst kam eine E-Mail mit dem Betreff "Ihre Kündigung - Letzte Chance" und bot mir 20% auf alle Internet-Produkte. Zwei Wochen später kam dann die "Allerletzte Chance" mit 25% auf alle Produkte sowie:

Noch nicht überzeugt? Dann finden wir sicher ein individuelles Angebot, das Ihnen besser gefällt. Wir freuen uns auf Sie!

Donnerwetter! Das nenn ich Service. Für mich kommen diese Angebote mangels Versorgung im neuen Wohngebiet natürlich nicht in Frage - und UnityMedia sollte das eigentlich wissen - aber allen Bestandskunden würde ich den Kündigungs-Bluff schon empfehlen!

Archiv »