Transparentes NordVPN Gateway auf Fedora 33 Minimal installieren

Dies ist ein aktualisierter Leitfaden auf Basis eines älteren Eintrags aus dem Jahre 2019. In Unterschied zu damals™ wird hier der modernere firewalld statt iptables zur Regelerstellung genutzt.

Installation

Der Fedora Media Writer leistet hier gute Dienste. Das Image als zuerst xz-Datei herunterladen, die MicroSD-Karte mit einem Kartenleser an den Rechner bringen. Die Karte dann im Media Writer auswählen, das Image auswählen, RaspberryPi 3 als Zielplattform und losschreiben! Nach dem erfolgreichen Schreiben sollte die Hauptpartition noch auf die Größe der ganzen Speicherkarte erweitert werden. Dies kann man unter Fedora mittels „Laufwerke“ (aka. gnome-disks) einfach graphisch erledigen.
Nach dem ersten Booten des RaspberryPis die Zeitzone festlegen, einen Benutzernamen eingeben, bei mir „vpn“ und diesen auch als Administrator markieren.

Grundlegende Systemeinstellungen

Nun sollten wir ein Passwort für unseren Benutzer festlegen, sonst können wir uns später nicht per SSH remote einloggen:

$ passwd

Verfügbare Tastaturlayouts anzeigen und das richtige Tastaturlayout einstellen:

$ localectl list-keymaps
$ sudo localectl set-keymap de

Verfügbare Lokalisierungen anzeigen, feststellen dass Deutsch nicht dabei ist, verfügbare Pakete suche, das passende nachinstallieren und einstellen:

$ localectl list-locales
$ dnf search locale | grep glibc-langpack | less
$ sudo dnf -y install glibc-langpack-de"
$ localectl list-locales
 | grep de
$ sudo localectl set-locale LANG=de_DE.UTF8

Ein ganzes Systemupdate mit sudo dnf -y update durch zu führen ist immer eine gute Idee.

Eine fest IP vergeben

Da wir die IP von unserem Router als Standardgateway an die Geräte im LAN verteilen möchten, sollten wir diese an das gewünschten Interface binden. Nicht vergessen, dass diese IP außerhalb Bereichs des verantwortlichen DHCP Servers liegen sollte. Mit ip addr show werden alle Interfaces und derzeitigen IPs angezeigt.

nmcli ist das Kommandozeileninterface des praktischen NetworkManagers:

$ nmcli dev status
DEVICE         TYPE      STATE            CONNECTION         
eth0           ethernet  verbunden        Wired connection 1 
[...]               

Wir nutzen hier das Interface eth0. Dessen Konfiguration hat der NetworkManager automatisch angelegt und „Wired connection 1“ genannt. Nun fügen wir eine neue Verbindung mit dem Namen „eth0-static“ hinzu, die unseren vorhandenen Router als Standardgateway (192.168.178.1) und zwei DNS-Server von OpenNIC nutzt. Die VPN-Gateway-IP legen wir auf 192.168.178.2 fest:

$ sudo nmcli con add con-name eth0-static ifname eth0 type ethernet \
    ipv4.method static ipv4.addresses 192.168.178.2/24 \
    ipv4.gateway 192.168.178.1 ipv4.dns "94.75.228.29 89.233.43.71"

Nun können wir die alte, automatische Verbindung löschen. Achtung: Wenn man dieses remote macht, kann es natürlich sein, dass man seine SSH-Verbindung tötet…:

$ nmcli con del "Wired connection 1"

Danach mit reboot neu starten und der NetworkManager wird die nun einzig verbleibende Verbindung mit der statischen IP automatisch nutzen. Alles weitere können wir ab nun per SSH aus der Entfernung machen. Um vorhandene Verbindungen zu verändern könnte man (zukünftig) nmcli con mod nutzen (nur als Information).

Logdateien in den verschieben

Wir können systemd-journald anweisen die Logfiles, unabh. davon, ob Verzeichnisse wir /var/log o.ä. existieren, nur im RAM zu halten um die SD-Karte zu schonen. In /etc/systemd/journald.conf folgende Einstellungen machen:

Storage=volatile
RuntimeMaxUse=64M

Damit werden max. 64MB Arbeitsspeicher für Logs genutzt und, wenn es dann eng wird, die ältesten weggeworfen. Schlussendlich den Journaldienst noch neustarten:

$ sudo systemctl restart systemd-journald

Swap deaktivieren

Ab Fedora 33 wird standardmäßig keine Auslagerungspartition mehr eingerichtet. Hier gibt es also nichts zu tun (Quelle). Das zur Laufzeit komprimierte Blockgerät kann man unter /dev auch als zram sehen:

$ ls -la /dev/z*
crw-rw-rw-. 1 root root   1, 5  2. Feb 01:00 /dev/zero
brw-rw----. 1 root disk 252, 0  2. Feb 01:00 /dev/zram0

Automatische Updates

Mit dnf-automatic können Pakete automatisch aktuell gehalten werden:

$ sudo dnf -y install dnf-automatic
$ sudo systemctl enable --now dnf-automatic-install.timer

In /usr/lib/systemd/system/dnf-automatic-install.timer kann man Tage und Zeiten für die Updates einstellen. Standardmäßig ist dies jeden morgen um 6 Uhr (±60 Minuten). Dies soll uns genügen. Ändert man etwas muss man die Timer neu laden:

$ sudo systemctl daemon-reload

Aktive Timer können so angezeigt werden:

$ sudo systemctl list-timers

OpenVPN installieren

Nachdem ein VPN-Anbieter auserkoren ist, durch den man seinen Internetverkehr routen möchte, muss man sich OpenVPN und wget installieren:

$ dnf install openvpn wget

NordVPN Server und Zertifikate

Die Zugangsdaten für NordVPN legen wir in einer Textdatei unter /etc/openvpn/nordvpn ab. Erste Zeile der Benutzername, zweite Zeile das Passwort. Sie soll nur für uns als Besitzer lesbar sein. Wenn man sich bei NordVPN einloggt bekommt man die „user credentials for manual setup“ direkt angezeigt.

$ sudo -i
$ cd /etc/openvpn
$ sudo mkdir nordvpn
$ cd nordvpn
$ echo -e "[Benutzername]\n[Passwort]" > auth.txt
$ sudo chmod 600 auth.txt
$ exit

Die zip-Datei, die NordVPN früher anbot, in der alle OpenVPN-Konfigurationen in passendem Dateiformat enthalten waren, scheint nicht mehr abrufbar. aus diesem Grund muss man sich nun die gewünschten Konfigurationsdateien einzeln aussuchen und herunterladen.

Zu der Frage, ob man nun eine UDP oder TCP-Verbindung nutzen soll, gibt es einige Abhandlungen. Wenn man (zu Hause) nicht zwingend auf Port 443 an einer Firewall unauffällig „vorbei“ muss, dann kann man getrost das schnellere UDP nehmen. Eventueller Datenverlust wird innerhalb der getunnelten TCP-Verbindungen sowieso ausgeglichen.

Auf dieser Seite gibt es (derzeit) die eine Liste der verfügbaren OpenVPN-Servern aus denen die interessantesten aussuchen kann, den Link kopiert und dann in /etc/openvpn/nordvpn ablegt:

$ sudo -i
$ cd /etc/openvpn/nordvpn
$ wget https://downloads.nordcdn.com/configs/files/[...].ovpn
$ ...

Auch die nötigen Zertifikate in diesen Dateien bereits enthalten. Man muss in der Zeile auth-user-pass dahinter die Datei mit den Zugangsdaten angeben und das Ergebnis danach umbenennen, da OpenVPN lediglich Dateien mit .conf-Suffix automatisch startet. Folgender Befehl fügt den Verweis auf die Logindaten ein und benennt das Ergenis in .conf um:

$ for FILE in *nordvpn*.ovpn; do \
     while read LINE; do \
         echo ${LINE/auth-user-pass/auth-user-pass /etc/openvpn/nordvpn/auth.txt}; \
     done < "$FILE" > "$(basename -s .ovpn ${FILE}).conf"; \
done

Man kann der Verbindungsaufbau direkt testen (mit CTRL+C beenden):

$ openvpn --config [Konfigurationsdatei.conf]
[...] Initialization Sequence Completed

Damit systemd selbst OpenVPN mit gewünschter Konfiguration starten kann, müssen sie im entsprechenden Verzeichnis liegen. Wir legen uns einen symbolischen Link an, der auf die Konfigurationsdatei verweist. So kann man diese aktivierte Konfiguration durch überschreiben des Links auch schnell austauschen. Danach wird der Start direkt getestet:

$ ln -s /etc/openvpn/nordvpn/[Konfigurationsdatei.conf] \
  /etc/openvpn/client/nordvpn.conf
$ systemctl start openvpn-client@nordvpn
$ systemctl status openvpn-client@nordvpn
● openvpn-client@nordvpn.service - OpenVPN tunnel for nordvpn
     Loaded: loaded (/usr/lib/systemd/system/openvpn-client@.service; disabled; vendor preset: disabled)
     Active: active (running) since Sat 2021-03-06 18:38:51 CET; 1min 24s ago
       Docs: man:openvpn(8)
             https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage
             https://community.openvpn.net/openvpn/wiki/HOWTO
   Main PID: 1374 (openvpn)
     Status: "Initialization Sequence Completed"
      Tasks: 1 (limit: 1013)
     Memory: 1.0M
        CPU: 117ms
     CGroup: /system.slice/system-openvpn\x2dclient.slice/openvpn-client@nordvpn.service
             └─1374 /usr/sbin/openvpn --suppress-timestamps --nobind --config nordvpn.conf

$ systemctl stop openvpn-client@nordvpn

Wenn dies alles erfolgreich ist, aktiviert man den OpenVPN-Dienst für den Bootvorgang und nach einem Neustart sollte der VPN-Tunnel von selbst stehen:

$ systemctl enable openvpn-client@nordvpn

NAT und Routing aktivieren

Nachdem OpenVPN läuft sehen wir das tun0-Gerät im NetworkManager:

$ nmcli dev status
DEVICE         TYPE      STATE                   CONNECTION  
eth0           ethernet  verbunden               eth0-static 
tun0           tun       connected (externally)  tun0      
[...]

Nach einer frischen Installation ist unsere Ethernetverbindung wahrscheinlich der Zone „öffentlich“ (public) zugewiesen. Über diese Zugehörigkeit steuert firewalld die Regelanwendung. Wir wollen uns hier lediglich versichern, dass dem so ist:

$ sudo firewall-cmd --get-active-zone 
public
  interfaces: eth0

Nun aktivieren wir das NAT für diese Zone. firewalld aktiviert im Normalfall automatisch das IP-Fordwarding.

$ sudo firewall-cmd --zone=public --add-masquerade --permanent
success
$ sudo firewall-cmd --reload
success
$ sudo firewall-cmd --zone=public --query-masquerade
yes
$ cat /proc/sys/net/ipv4/ip_forward 
1

Sollte der letzte Befehl eine „0“ als Ergebnis liefern, muss ein Eintrag in /etc/sysctl.conf hinzugefügt werden:

$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
$ sudo echo -e "\n# IP forwarding\nnet.ipv4.ip_forward = 1" >> /etc/sysctl.conf
$ sudo sysctl -p
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

Wenn wir uns die erlaubten Dienst für die Zone, in der eth0 ist, ansehen…

$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: dhcpv6-client mdns ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

…stellen wir fest, dass ssh bereits erlaubt ist. Wir müssen uns lediglich noch um die Weiterleitung des Datenverkehrs von eth0 nach tun0 und zurück kümmern:

$ sudo firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 \
    -o tun0 -j MASQUERADE
success
$ sudo firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 \
    -i eth0 -o tun0 -j ACCEPT
success
$ sudo firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 \
    -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
success

Wenn nun von einem Rechner, derr unser VPN-Gateway als neues Gateway einstellt, Verbindungen nach „draußen“ möglich ist hat dies funktioniert. Daher werden die Regeln permanent angewendet:

$ sudo firewall-cmd --runtime-to-permanent

Nach einem Neustart folgendermaßen geprüft werden, dass alle Regeln korrekt wiederhergestellt wurden:

$ sudo firewall-cmd --direct --get-all-rules
ipv4 nat POSTROUTING 0 -o tun0 -j MASQUERADE
ipv4 filter FORWARD 0 -i eth0 -o tun0 -j ACCEPT
ipv4 filter FORWARD 0 -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT

Performance und Stromaufnahme

Auf einen Raspberry PI 3B+ zeigt top auf einem Kern 65 % Auslastung bei 45 MBit/s Download an. Da ein einzelner Tunnel sicherlich nicht auf die vier Kerne der CPU verteilt wird, ist damit rechnerisch bei 70 MBit/s Schluss. Allerdings langweilen sich die 3 weiteren Kerne zu Tode, sodass man da sicherlich noch hübsche Sachen parallel laufen lassen könnte. Das Gateway läuft ja dauerhaft.
Mit einem unkalibriertem USB-Billigstmessgerät nimmt der RaspbeeryPi 0.44 A bei 4.94 V auf, bei dem erwähnten Durchsatz von 47 MBit/s 0.56 A. Die meiste Zeit ist sicher Langweilen angesagt. Insofern kann man bei einem Netzteilwirkungsgrad von vllt. 80 % von einen ungefähren Jahresverbrauch von um die 25 kWh ausgehen.

DHCP-Server

Um an das VPN-Gateway automatisiert an Geräte im lokalen Netz zu verteilen, brauchen wir einen DHCP-Server. D.h. jedoch auch, dass der bereits vorhandene Server auf dem Router deaktiviert werden muss (oder eben dort das neue Gateway und die DNS-Server eintragen, falls möglich).
Die Installation wird mit folgenden Kommando angestoßen:

$ sudo dnf install -y dhcp

Die Konfiguration findet man unter /etc/dhcp/dhcpd.conf. Diese passen wir an, setzen dabei den gewünschten Bereich der IPs, die ausgeteilt werden, die DNS-Server von OpenNIC und unser VPN-Gateway als Standardgateway:

# DHCP Server Configuration file.
# see /usr/share/doc/dhcp-server/dhcpd.conf.example
# see dhcpd.conf(5) man page

# Options common to all networks
option domain-name "ich-war-hier.de";
option domain-name-servers 172.104.136.243, 192.71.245.208;

# Default lease time is 7 days
default-lease-time 604800;
# Maximum lease time is 31 days
max-lease-time 2678400;

# This server is active!
authoritative;

subnet 192.168.178.0 netmask 255.255.255.0
{
    range 192.168.178.64 192.168.178.192;
    option routers 192.168.178.2;
    option broadcast-address 192.168.178.255;
}

Noch den Port 67/UDP in firewalld öffnen, damit der DHCP Server erreichbar ist:

$ sudo firewall-cmd --add-service=dhcp --permanent
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all

Nun starten wir den DHCP-Server:

$ sudo systemctl start dhcpd
$ sudo systemctl enable dhcpd

Sicherung der SD-Karte

Wenn man alles fertig eingestellt hat ist das Anlegen einer Sicherheitskopie der Installation sicherlich eine gute Idee. Wenn man weiß, welches Device das die SD-karte nach dem Einstecken mit einem Kartenleser ist (bei bei /dev/sdb), stellt man sicher, dass man keine der Partitionen gemountet hat (df -h) und kopiert mit dd die ganze Karte 1-zu-1 in eine Datei:

$ sudo umount /dev/sdb*
$ sudo dd status=progress if=/dev/sdb of=~/image.img

Es ist sicherlich sinnvoll diese noch zu komprimieren, damit das Backup nicht unnötig viel Platz belegt.

Wiederherstellen einer Sicherung

$ sudo dd status=progress bs=4M if=~/image.img of=/dev/sdb
$ sync
$ eject /dev/sdb

Dieser Beitrag wurde unter Computer abgelegt und mit , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert