Einrichten eines via Bridging arbeitenden OpenVPN-Gateways, um externe (mobile) Geräte über das Internet in das heimische Netzwerk als reguläre LAN-Clients zu integrieren.
Der wichtigste Hinweis gleich zu Beginn: Dieses Tutorial baut auf wesentlichen Teilen meines OpenVPN-Routing-Tutorials auf, wie zum Beispiel bei der Verwendung des selbst erstellten aktuellen OpenVPN-Binarys, Erstellung einer Certificate Authority und der Port-Einstellungen im DSL-Router, weswegen ich diese Komponenten jetzt hier als „fertig erstellt“ deklariere. Die dazu notwendigen Schritte sind im Artikel http://www.thlu.de/openvpn.html umfassend beschrieben.
Der wesentliche Unterschied zum Routing-Tutorial liegt bei dieser Bridging-Lösung in der Prämisse, die entfernten mobilen Clients in das heimische Netzwerk als tatsächlich reguläre LAN-Clients zu integrieren, mit einer eigenen LAN-internen Client-IP. Es ist dabei ausdrücklich nicht das Ziel, auch den normalen Internet-Datenverkehr der mobilen Clients ebenfalls durch das VPN zu routen, stattdessen soll für alle Zugriffe auf das Internet unverändert das am Ort des Clients lokal aktive Netzwerk verwendet werden. Bei meinem Routing-Setup wird der vollständige Datenverkehr (der Zugang zum heimischen LAN und die Zugriffe aufs Internet via heimischen DLS-Router) durch den VPN-Tunnel geroutet, dem entgegen wird hier beim Bridging die Integration der entfernten Geräte als LAN-Clients realisiert, ohne zusätzlich auch die Internet-Zugriffe des Clients beim Surfen zu routen.
Die markanten Unterschiede in meinen beiden Tutorials sind also: der Lösungsansatz Nur-ein-Zugang ist was anderes als echte Integration, einmal wird auch der Inet-Traffic durch den Tunnel geroutet, beim anderen nicht. Ein weiterer technischer Unterschied besteht darin, das Bridging eine besondere Netzwerk-Konfiguration erfordert, die man von Hand und mit Sachkenntnis herstellen muss. Hier in diesem Tutorial ist der Datenverkehr über eine Netzwerk-Brücke zwischen physischen (eth) und virtuellen (tap) Interface gelöst.
Wie man hier in dieser Grafik erkennen kann, befinden sich die Client-Geräte auf beiden Netzwerk-Seiten allesamt im gleichen Subnet 10.0.1.0/24. Das bedeutet, alle Client-Geräte können untereinander kommunizieren. Achtung, hierzu ein wichtiger Hinweis: Derzeit wird in der von mir favorisierten Android-App „OpenVPN for Android“ der Bridging-Mode via TAP-Device nicht unterstützt. Die FAQ auf der Projekt-Seite sagt dazu folgendes: „Tap Mode is not possible with the non root VPN API. Therefore this application cannot provide tap support .“ Das bedeutet, die Integration von mobilen Android-Geräten über das Internet in das heimische Netzwerk ist zur Zeit vermutlich deshalb nicht möglich, weil ungerootete Geräte anscheinend kein dynamisch generiertes TAP-Device erstellen können.
Grundsätzlich existieren hierbei die gleichen Risiken, wie ich sie bereits hier schon beschrieben habe. Ich persönlich würde auf Reisen und mit Verbindungen an fremden und somit potentiell unsicheren Accesspoints eine solche Konfiguration eher nicht einsetzen. Im Gegensatz dazu wäre das allerdings meine favorisierte Lösung, wenn ich selber an den 2 Standorten der Herr der Netzwerke bin, zum Beispiel einmal beim Netzwerk zuhause und einmal beim Netzwerk in meinem beruflich notwendigen Zweitwohnsitz.
Darüber hinaus hat dieses Bridging-Setup durchaus noch einige Überraschungen parat. So ist es z.B. auf einem heimischen Dual-Stack-Account durchaus möglich, dass durch den IPv4-Tunnel über die Link-Local-IP des TAP-Devices auch das Neighbor Discovery Protocol (NDP (Router Solicitation und Router Advertisement)) übertragen wird und somit das Tap-Device des Clients eine IPv6 passend zur Site-ID des heimischen Netzwerks erhält. In dem Fall kann es passieren, dass bei einer Web-Abfrage der eigenen IP-Adressen bei IPv4 die öffentliche IP des örtlichen Internets angezeigt wird und für IPv6 eine Site-ID aus dem Heimnetzwerk…. im Endeffekt auf diesen Aspekt bezogen also sogar mit 2 unterschiedlichen DSL-Providern. Für das eigentliche Ziel, die Integration des Clients via Tunnel ins heimische Netzwerk mit Zugriff auf die dortigen Ressourcen, ist dieses zusätzliche Verhalten für mich allerdings irrelevant, weil das eigentliche Ziel erreicht wurde.
Um das hier also noch einmal deutlich abzugrenzen: Will ich den vollständigen Datenverkehr eines mobilen Clients durch den Tunnel schicken, also gleichzeitig Internet und auch für den Zugriff auf die heimischen Netzwerk-Ressourcen und will ich zudem auch noch Android-Geräte verwenden, ist Routing meiner Meinung nach die bessere bzw. sogar einzige Wahl. Für dieses Ziel einer zeitweisen Ad-hoc-Verbindung spielt es auch keine Rolle, ob ich eine IP aus dem Heimnetzwerk erhalte oder via NAT geroutet werde…. das Ergebnis ist für mich und mein mobiles Client-Gerät funktional betrachtet das gleiche. Natürlich besteht auch beim Routing die Möglichkeit, den Tunnel ins Heimnetz und den Datenverkehr ins Internet über das lokale Netzwerk zu trennen. Das bedeutet, ich greife über den Tunnel zwar auf das Heimnetz zu, aber Zugriffe aufs Internet werden im lokalen Gastgeber-Netz direkt geroutet. Ist es aufgrund ganz besonderer Anforderungen jedoch zwingend notwendig, dass der Client mit LAN-interner IP ins heimische Netzwerk integriert wird, ist Bridging die richtige Wahl. Allerdings, das muss ich gestehen, ich kann mir kein Szenario für mich als Privat-Reisenden vorstellen, wo mir eine solche Installation Vorteile bringen würde…. deshalb verwende ich selber immer und ausschließlich das Routing-Setup.
Bei der Installation eines OpenVPN-Default-Setups aus dem Debian/Raspbian-Repository muss außerdem beachtet werden, dass darüber ein automatischer Start via init.d-Scripte (sysv) eingerichtet wird, was in Konflikt mit dem hier eingeschlagenen Weg steht.
Dieses Tutorial richtet sich an erfahrene Linux-Anwender!
Inhaltsübersicht
> Ein wichtiger Hinweis zum Schluss
Anhang:
> Service-Unit für Bridge und DHCP
|
IP-Range des lokalen regulären Heimnetzwerks: 10.0.1.0/24 Default-Gateway: 10.0.1.1 VPN-Server: 10.0.1.200 VPN-Client-Range: 10.0.1.201-10.0.1.210 ETH-NIC-Name: eth0 Bridge-NIC-Name: br0 UDP-Port: 55553
- Setup eines Raspberry PI als (zunächst) dedizierten VPN-Server ohne User-Interaktion und ohne grafisches Environment - Integration von mobilen Clients in das heimische Netzwerk via Bridging durch einen VPN-Tunnel - Normaler Traffic des Clients ins Internet wird über das lokale Netzwerk geroutet (nicht durch Tunnel) - Aktive Verbindung via Patchkabel über Kabelinterface (eth0) ist zur Erst-Einrichtung zwingend notwendig - Alle unbenötigten Dienste werden aus Sicherheitsüberlegungen deaktiviert - Die Netzwerk-Connectivity wird vollständig direkt eingerichtet | |
Hinweise: Bei allen Schritten nur dann mit dem nächsten Schritt fortfahren, wenn der vorherige keine Fehler verursacht hat!
CLI-Prompt: $ = normaler User # = root
Kommentare! Beachten! Auf lokale Gegebenheiten anzupassender Parameter
ne = Nice Editor strg-s = save file strg-q = quit |
|
Mein PC zum Durchführen aller Arbeiten
$ lsb_release -a Distributor ID: Debian Description: Debian GNU/Linux 10 (buster) Release: 10 Codename: buster
$ date Sa 14. Mär 12:07:31 CET 2020
|
$ su -
# cd /media/Install/Images
# wget -c "https://downloads.raspberrypi.org/raspbian_lite_latest" -O raspbian_buster_lite_latest.zip --2020-03-13 19:14:30-- https://downloads.raspberrypi.org/raspbian_lite_latest Wird in »raspbian_buster_lite_latest.zip« gespeichert. raspbian_buster_lite_latest.zip 100%[=============================================>] 433,01M 5,79MB/s in 14s 2020-03-13 19:14:44 (1,93 MB/s) - »raspbian_buster_lite_latest.zip« gespeichert [454047405/454047405]
# mkdir /tmp/rp # cd /tmp/rp # unzip /media/Install/Images/raspbian_buster_lite_latest.zip Archive: raspbian_buster_lite_latest.zip inflating: 2019-06-20-raspbian-buster-lite.img | |
# lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL,UUID,TYPE NAME FSTYPE SIZE MOUNTPOINT LABEL UUID TYPE sda 238,5G disk └─sda1 ext4 208,6G / debian10 6c5dbab8-40680 part sdb 465,8G disk └─sdb1 ext4 500G /media/sdb1 33daf003-08ac5 part sdc 7,5G disk ├─sdc1 vfat 256M /media/sdc1 boot F661-303B part └─sdc2 ext4 7,2G /media/sdc2 rootfs 8dfa-47f4 part
| Device mit Card-Reader/Writer für SD-Card ermitteln
<<<===== |
# umount /media/sdc*
# ls *lite.img -rw-r--r-- 1 thomas thomas 2,1G 2019-06-20 02:21 2019-06-20-raspbian-buster-lite.img
# dd bs=1M if=2020-02-13-raspbian-buster-lite.img of=/dev/sdc status=progress 2191523840 bytes (2,2 GB, 2,0 GiB) copied, 80 s, 27,4 MB/s 2096+0 Datensätze ein 2096+0 Datensätze aus 2197815296 bytes (2,2 GB, 2,0 GiB) copied, 103,626 s, 21,2 MB/s # sync # df Dateisystem Typ Größe Benutzt Verf. Verw% Eingehängt auf /dev/sdc1 vfat 253M 40M 213M 16% /media/sdc1 /dev/sdc2 ext4 1,8G 995M 669M 60% /media/sdc2 | |
# touch /media/sdc1/ssh # umount /dev/sdc1; umount /dev/sdc2 # exit $ | <<<===== vfat |
| |
// RPi mit neuer Karte booten und IP-Adresse über DSL-Router ermitteln, hier = 10.0.1.56
$ ping 10.0.1.56 -c 3 PING 10.0.1.56 (10.0.1.56) 56(84) bytes of data. 64 bytes from 10.0.1.56: icmp_seq=1 ttl=64 time=0.429 ms 64 bytes from 10.0.1.56: icmp_seq=2 ttl=64 time=0.462 ms 64 bytes from 10.0.1.56: icmp_seq=3 ttl=64 time=0.410 ms | |
$ ssh pi@10.0.1.56 -p 22 | pwd = raspberry |
|
$ lsb_release -a Distributor ID: Raspbian Description: Raspbian GNU/Linux 10 (buster) Release: 10 Codename: buster |
|
$ sudo su - # passwd # adduser toml # dpkg-reconfigure tzdata # dpkg-reconfigure locales | root shell root-pwd setzen neuer Default-User Europa / Berlin de.de utf8 |
# hostnamectl set-hostname tomsvpngw # cat /etc/hostname tomsvpngw | Hostname beschreibt die Bestimmung |
# systemctl reboot $ ssh toml@10.0.1.56 -p 22 $ su - | Wichtig!!! |
# deluser pi # apt purge --remove sudo rsyslog avahi-daemon | Sicherheitsrisiken und Müll beseitigen |
| |
# ip link show | grep -i broadcast 2: enp1s0: <BROADCAST,MULTICAST> mtu 1500 … 3: wlanx00c0ca8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 … | NIC-Names prüfen! Alle Netzwerkinterfaces sind entsprechend dieser Anleitung mit Bindung an die MAC-Adresse (s.u.) umzubenennen. Sofern weitere Interfaces mit Möglichkeiten zu Namenskonflikten installiert sind, sind alle in eindeutiger Reihenfolge ebenfalls eindeutig mit MAC-Bindung zu benennen. Das gilt auch für Devices, die schon von vornherein die korrekte Bezeichnung hatten. |
# ip link show | MAC-Adressen mit ip-Command ermitteln. Bei externen USB-Devices ggf. nacheinander einstecken und dann jeweils mit ip link show eindeutig identifizieren. |
# nano /etc/systemd/network/10-eth0.link [Match] MACAddress=aa:bb:cc:dd:ee:ff
[Link] Name=eth0 | Jedes Netzwerkinterface wird mit seiner Bezeichnung an die MAC-Adresse gebunden. Falls das NIC jetzt schon mit eth0 bezeichnet ist, kann diese Maßnahme übersprungen werden. An jede der 3 Link-Dateien als letzte Zeile eine Leerzeile anfügen! |
# nano /etc/systemd/network/11-wlan-client.link [Match] MACAddress=ab:cd:ef:12:34:56 Type=wlan
[Link] Name=wlan0 | WLAN-Interface (wird hier nur der Vollständigkeit wegen beachtet, ohne das es hinterher hier im Tutorial verwendet wird) |
# systemctl reboot
| Geänderte Bezeichnungen sind erst nach Reboot aktiv. Externe WLAN-Devices sollten jetzt angeschlossen sein! |
| |
$ ssh toml@10.0.1.56 -p 22 $ su -
# ip link show | grep -i broadcast 2: eth0: <BROADCAST,MULTICAST> mtu 1500 ... 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ... | Netzwerk einrichten. Unbedingt sorgfältig arbeiten! Fehler können dazu führen, dass das Netzwerk beim Boot nicht startet und Fehler anschließend direkt auf der SD-Card korrigiert werden müssen.
Bezeichnung der Devices kontrollieren. Wenn fehlerhaft, dann gemäß der Anleitung oberhalb mit Bindung an MAC-Adresse korrigieren. |
# nano /etc/systemd/system/network.service [Unit] Description=thlu:network.service: Start network connectivity After=basic.target Before=network.target shutdown.target Wants=network.target Conflicts=shutdown.target
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" Type=oneshot RemainAfterExit=yes
ExecStartPre=ip link set dev eth0 up ExecStart=dhclient -4 eth0
ExecStop=dhclient -r eth0 ExecStopPost=ip link set dev eth0 down
[Install] WantedBy=multi-user.target
| Diese Service-Unit ist nur eine Zwischenlösung, damit nach dem Ausplanen aktiver Netzwerk-Services (siehe unterhalb) trotzdem eine Netzwerkverbindung hergestellt werden kann. An diese und jeder folgenden Service-Unit immer als letzte Zeile eine Leerzeile anfügen! |
# cd /etc/systemd/system # systemctl start network.service | Neue Netzwerkverbindung aktivieren Teststart, um auf Fehler zu prüfen |
# systemctl status network.service ● network.service - thlu:network.service: Start network connectivity Loaded: loaded (/etc/systemd/system/network.service; enabled; vendor preset: enabled) Active: active (exited) since Wed 2020-03-25 16:55:12 CET; 4s ago Process: 521 ExecStartPre=/sbin/ip link set dev eth0 up (code=exited, status=0/SUCCESS) Process: 522 ExecStart=/sbin/dhclient -4 eth0 (code=exited, status=0/SUCCESS) Main PID: 522 (code=exited, status=0/SUCCESS) Tasks: 1 (limit: 2200) Memory: 3.5M CGroup: /system.slice/network.service └─523 /sbin/dhclient -4 eth0 Mär 25 16:55:11 tomsvpngw systemd[1]: Starting thlu:network.service: Start network connectivity... Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 6 Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPOFFER of 10.0.1.56 from 10.0.1.1 Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPREQUEST for 10.0.1.56 on eth0 to 255.255.255.255 port 67 Mär 25 16:55:11 tomsvpngw dhclient[523]: DHCPACK of 10.0.1.56 from 10.0.1.1 Mär 25 16:55:11 tomsvpngw dhclient[522]: RTNETLINK answers: File exists Mär 25 16:55:12 tomsvpngw dhclient[523]: bound to 10.0.1.56 -- renewal in 429397 seconds. Mär 25 16:55:12 tomsvpngw systemd[1]: Started thlu:network.service: Start network connectivity. # systemctl enable network.service Created symlink /etc/systemd/system/multi-user.target.wants/network.service → /etc/systemd/system/network.service. | |
|
|
# cd / # find /etc -iname "*networking" -print /etc/rc0.d/K01networking /etc/rc6.d/K01networking /etc/rcS.d/S01networking /etc/default/networking /etc/init.d/networking | Alte Verbindung gefunden = sysv = obsolet => ausplanen
Bei der Ausplanung geht es primär um das Ziel, potentielle Störer von vornherein auszuschalten, sowie überflüssige Services zu deaktivieren.
Für Services, die nicht aktiv sind oder möglicherweise gar nicht installiert sind, werden die Schritte übersprungen.
Dieses Tutorial funktioniert unter Debian, Raspbian und aller Wahrscheinlichkeit gleichermaßen auch unter Ubuntu oder Arch Linux. Deshalb kann es sein, dass die folgenden Services unterschiedlich auf den Systemen eingerichtet und aktiviert sind. |
# systemctl status ifup@eth0.service ● ifup@enp2s0.service - ifup for eth0 Loaded: loaded (/lib/systemd/system/ifup@.service; static; vendor preset: enabled) Active: active (exited) since Sat 2019-06-08 # systemctl mask ifup@eth0.service Created symlink /etc/systemd/system/ifup@eth0 .service → /dev/null. | |
# update-rc.d networking remove # systemctl status networking.service ● networking.service - Raise network interfaces Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled) Active: active (exited) since Thu 2020-03-05 14:37:31 CET; 21s ago # systemctl mask networking.service Created symlink /etc/systemd/system/networking.service → /dev/null. # find /etc -iname "*networking" -print /etc/default/networking /etc/init.d/networking | |
# systemctl status NetworkManager.service ● NetworkManager.service - Network Manager Loaded: loaded (/lib/systemd/system/NetworkManager.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2019-06-08 # systemctl mask NetworkManager.service Created symlink /etc/systemd/system/NetworkManager.service → /dev/null. | |
# systemctl status systemd-networkd ● systemd-networkd.service - Network Service Loaded: loaded (/lib/systemd/system/systemd-networkd.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2019-06-08 # systemctl mask systemd-networkd Created symlink /etc/systemd/system/systemd-networkd.service → /dev/null. | |
# systemctl status wpa_supplicant.service ● wpa_supplicant.service - WPA supplicant Loaded: loaded (/lib/systemd/system/wpa_supplicant.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2020-03-05 15:01:35 CET; 9min ago) # systemctl mask wpa_supplicant.service Created symlink /etc/systemd/system/wpa_supplicant.service → /dev/null. | |
# systemctl status dhcpcd.service ● dhcpcd.service - LSB: IPv4 DHCP client with IPv4LL support Loaded: loaded (/etc/init.d/dhcpcd; generated) Active: active (running) since Thu 2020-03-05 15:01:35 CET; 9min ago # systemctl mask dhcpcd.service Created symlink /etc/systemd/system/dhcpcd.service → /dev/null. | |
# systemctl status triggerhappy.service ● triggerhappy.service - triggerhappy global hotkey daemon Loaded: loaded (/lib/systemd/system/triggerhappy.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2020-03-13 20:39:52 CET; 14h ago # systemctl mask triggerhappy.service triggerhappy.socket Created symlink /etc/systemd/system/triggerhappy.service → /dev/null. | |
# systemctl status bluetooth.service ● bluetooth.service - Bluetooth service Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled) Active: inactive (dead) # systemctl mask bluetooth.service Created symlink /etc/systemd/system/bluetooth.service → /dev/null. | |
# systemctl status networking.service wpa_supplicant.service # systemctl status network.service | Aufmerksam kontrollieren! = maskiert = enabled |
# apt update; apt full-upgrade # echo -e "\nStorage=persistent\nSystemMaxUse=20M\nRuntimeMaxUse=20M\nForwardToSyslog=no\nMaxLevelConsole=warning\n" >>/etc/systemd/journald.conf # systemctl reboot | |
| |
$ scp "openvpn-2.4.8_buster_armhf.deb" "toml@10.0.1.56:/tmp" $ scp "openvpn-setup.tar" "toml@10.0.1.56:/tmp" | Vom PC das vorbereitete deb-Package sowie die notwendigen Key-Files (hier im Tar-File enthalten) auf den Raspberry Pi (Server) kopieren, siehe: http://www.thlu.de/openvpn.html. |
| |
$ ssh toml@10.0.1.56 -p 22 $ su - # apt autoremove; apt autoclean | |
# systemctl status ifup@eth0 networking NetworkManager systemd-networkd wpa_supplicant dhcpcd triggerhappy bluetooth ● ifup@eth0.service Loaded: masked (Reason: Unit ifup@eth0.service is masked.) Active: inactive (dead) ● networking.service Loaded: masked (Reason: Unit networking.service is masked.) Active: inactive (dead) ● NetworkManager.service Loaded: masked (Reason: Unit NetworkManager.service is masked.) Active: inactive (dead) ● systemd-networkd.service Loaded: masked (Reason: Unit systemd-networkd.service is masked.) Active: inactive (dead) ● wpa_supplicant.service Loaded: masked (Reason: Unit wpa_supplicant.service is masked.) Active: inactive (dead) ● dhcpcd.service Loaded: masked (Reason: Unit dhcpcd.service is masked.) Active: inactive (dead) ● triggerhappy.service Loaded: masked (Reason: Unit triggerhappy.service is masked.) Active: inactive (dead) ● bluetooth.service Loaded: masked (Reason: Unit bluetooth.service is masked.) Active: inactive (dead) | |
# dpkg -l mc ne htop bridge-utils dpkg-query: no packages found matching mc dpkg-query: no packages found matching ne dpkg-query: no packages found matching htop dpkg-query: no packages found matching bridge-utils | Sind notwendige Pakete bereits vorhanden? mc = midnight commander ne = Nice Editor, vor mir bevorzugter Editor htop = Taskmanager bridge-utils |
# apt install mc ne htop bridge-utils | Nur fehlende Pakete installieren! |
# dpkg -l libc6 liblz4-1 liblzo2-2 libpam0g libssl1.1 libsystemd0 iproute2 lsb-base openssl # apt install $(fehlende) |
|
# cd /tmp # dpkg -i openvpn-2.4.8_buster_armhf.deb | OpenVPN ist zum jetzigen Zeitpunkt notwendig, da das Programm zum Generieren des Tap-Devices von der folgenden Service-Unit gestartet wird. Ohne OpenVPN würde die Unit fehlschlagen und somit auch die Netzwerkverbindung. |
# tar -xf openvpn-setup.tar # mkdir -p /etc/openvpn/keys # mv /tmp/openvpn/keys /etc/openvpn # rm -r /tmp/openvpn # chown -R root:root /etc/openvpn # chmod 700 /etc/openvpn # chmod 600 /etc/openvpn/keys/* | Der Zugriff (auch lesend) auf die Keyfiles sowie der OpenVPN-Konfiguration ist ausschließlich ‚root‘ erlaubt. |
# adduser vpnuser --no-create-home --gecos "" --disabled-password | Virtueller User, unter dessen UID der OpenVPN-Daemon laufen wird |
# ip a s dev eth0 | grep -i "link/ether" link/ether b8:27:dd:kk:yz:5d brd ff:ff:ff:ff:ff:ff | MAC-Adresse des physischen NICs zur Übernahme in die Bridge-Konfiguration ermitteln |
# ne /etc/systemd/system/network-bridge-static.service [Unit] Description=thlu:network-bridge-static.service Bridged Network for VPN After=basic.target Before=network.target shutdown.target Wants=network.target Conflicts=shutdown.target
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" Type=oneshot RemainAfterExit=yes
ExecStartPre=openvpn --mktun --dev tap0 ExecStartPre=ip link add br0 type bridge ExecStartPre=ip link set br0 type bridge stp_state 0 ExecStartPre=ip link set br0 type bridge forward_delay 0 ExecStartPre=ip link set br0 address b8:27:dd:kk:yz:5d ExecStartPre=ip addr add 10.0.1.200/24 dev br0 ExecStartPre=sysctl -w net.ipv6.conf.br0.forwarding=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.disable_ipv6=0 ExecStartPre=sysctl -w net.ipv6.conf.br0.autoconf=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.use_tempaddr=2 ExecStartPre=sysctl -w net.ipv6.conf.br0.accept_ra=2 ExecStartPre=ip link set eth0 master br0 ExecStartPre=ip link set eth0 up ExecStartPre=ip link set tap0 master br0 ExecStartPre=ip link set tap0 up ExecStartPre=ip link set br0 up ExecStartPre=ip route add default via 10.0.1.1 ExecStart =true
ExecStop =ip link set tap0 nomaster ExecStopPost=ip link set tap0 down ExecStopPost=ip addr flush dev tap0 ExecStopPost=openvpn --rmtun --dev tap0 ExecStopPost=ip link set eth0 nomaster ExecStopPost=ip link set eth0 down ExecStopPost=ip addr flush dev eth0 ExecStopPost=ip link set br0 down ExecStopPost=ip addr flush dev br0 ExecStopPost=ip link del br0 type bridge
[Install] WantedBy=multi-user.target | Service-Unit zum Starten des Netzwerkes
--mktun erzeugt eigentlich ein persistentes TAP-Device... sollte es, eigentlich. Aber aufgrund von wiederholten Unstimmigkeiten habe ich mich entschieden, das bei Systemstart explizit zu veranlassen MAC-Adresse synchronisieren und statische IP-Adresse aus lokalen Netzwerk vorgeben (siehe oben Prämissen)
Default-Gateway |
# ne /etc/sysctl.d/ip_setup.conf net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.disable_ipv6=0 net.ipv6.conf.default.forwarding=1 net.ipv6.conf.default.autoconf=0 net.ipv6.conf.default.use_tempaddr=0 net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.eth0.disable_ipv6=1 net.ipv6.conf.eth0.forwarding=1 net.ipv6.conf.eth0.autoconf=0 net.ipv6.conf.eth0.use_tempaddr=0 net.ipv6.conf.eth0.accept_ra=0 | Konfigruation der Interfaces für TCP/IP-Handling: - Forwarding für alle Interfaces erlauben - IPv6 default erlauben, aber ausdrücklich für eth0 verbieten
eth0 bekommt keine IPv4-Adresse, mit dem ‚disable‘ wird sichergestellt, dass auch der Kernel keine IPv6-Adresse via SLAAC generiert.
Das neue Bridge-Interface ‚br0‘ erhält sowohl eine aktive manuell zugewiesene Static-IPv4 aus dem LAN, als auch bei Verfügbarkeit von IPv6 eine durch SLAAC generierte öffentliche IPv6.
In reinen IPv4-Umgebungen sollten diese Einstellungen trotzdem keine negativen Auswirkungen haben. |
# systemctl disable network.service # systemctl enable network-bridge-static.service # systemctl reboot |
|
$ ping 10.0.1.200 -c 3 PING 10.0.1.200 (10.0.1.200) 56(84) bytes of data. 64 bytes from 10.0.1.200: icmp_seq=1 ttl=64 time=0.433 ms 64 bytes from 10.0.1.200: icmp_seq=2 ttl=64 time=0.442 ms 64 bytes from 10.0.1.200: icmp_seq=3 ttl=64 time=0.409 ms $ ssh toml@10.0.1.200 -p 22 $ su - | Achtung: Neue statische IP = 200. Bridge = OK? |
# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000 link/ether b8:27:dd:kk:yz:5d brd ff:ff:ff:ff:ff:ff 3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether b8:27:dd:kk:yz:5d brd ff:ff:ff:ff:ff:ff inet 10.0.1.200/24 scope global br0 valid_lft forever preferred_lft forever inet6 2003:z2b9:ybcv:x344:5d3:3661:e819:c4f6/64 scope global temporary dynamic valid_lft 6672sec preferred_lft 3072sec inet6 2003:z2b9:ybcv:x344:ba27:ebff:feee:dd5d/64 scope global dynamic mngtmpaddr valid_lft 6672sec preferred_lft 3072sec inet6 fe80::ba27:ebff:feee:dd5d/64 scope link valid_lft forever preferred_lft forever | |
# ne /etc/openvpn/server_udp_br.conf server-bridge 10.0.1.200 255.255.255.0 10.0.1.201 10.0.1.210 #client-to-client
proto udp dev tap0 port 55553
ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/server.crt key /etc/openvpn/keys/server.key
cipher AES-256-GCM auth SHA256 auth-nocache
dh /etc/openvpn/keys/dh.pem ecdh-curve secp384r1 tls-version-min 1.3 tls-crypt /etc/openvpn/keys/ta.key
ping-timer-rem keepalive 10 60 persist-key persist-tun group vpnuser user vpnuser
verb 3 mute 10 log-append /var/log/openvpn/openvpn_udp.log | OpenVPN-Konfiguration: Sollen örtlich voneinander getrennte VPN-Clients auch untereinander kommunizieren können, muss der Comment-Tag ‚#‘ bei dieser Zeile entfernt werden. Sofern die Datei-Namen der Key-Files anders lauten, entweder die Conf anpassen oder Symlinks erstellen, z.B.: # cd /etc/openvpn/keys # ln -s RaspiSrv.key server.key # ln -s RaspiSrv.crt server.crt # ln -s dh4096.pem dh.pem |
# ne /etc/systemd/system/openvpn.service | Service-Unit für den Start des OpenVPN-Servers beim Systemstart. |
[Unit] Description=thlu:openvpn.service Start a OpenVPN-Daemon After=network-bridge-static.service Requires=network-bridge-static.service
[Service] Type=forking PIDFile=/var/run/openvpn/pid
ExecStartPre=/bin/mkdir -p /var/run/openvpn ExecStartPre=/bin/mkdir -p /var/log/openvpn ExecStartPre=/bin/chmod 770 /var/log/openvpn ExecStartPre=/bin/chown root:vpnuser /var/log/openvpn ExecStartPre=/bin/sleep 2 ExecStart=/usr/sbin/openvpn --daemon --writepid /var/run/openvpn/pid --status /var/run/openvpn/status 60 --config /etc/openvpn/server_udp_br.conf
KillMode=process
[Install] WantedBy=multi-user.target |
Die Installations-Schritte sind bis auf ein unterschiedliches Konfigurationsfile sowie unterschiedliche Keyfiles (Client != Server) identisch... Symlinks siehe also oberhalb beim Server. | |
# ne /etc/openvpn/client_udp_br.conf tls-client remote-cert-tls server remote myprivateddnslink.net
proto udp port 55553
dev tap0 lladdr 02:b8:39:89:5d:30
pull ping 60
cipher AES-256-GCM auth SHA256 auth-nocache
ca /etc/openvpn/keys/ca.crt cert /etc/openvpn/keys/client.crt key /etc/openvpn/keys/client.key tls-crypt /etc/openvpn/keys/ta.key
mute 10 verb 3 explicit-exit-notify log-append /var/run/openvpn/client.log | --remote-cert-tls stellt sicher, dass der angesprochene Server auch wirklich der ist, der er sein soll und nicht ein fremdes System, was sich als Server ausgibt. Dieser Parameter ist ein Sicherheitsparameter. Im Regelfall generiert OpenVPN bei der Erstellung eines TAP-Devices jedesmal eine zufällige MAC-Adresse für das Device. Das ist meistens unkritisch, kann allerdings dann aber auch zu Problemen führen, wenn man in seinem heimischen DSL-Router für gerouteten Internet-Verkehr für alle neuen Geräte die Default-Einstellung „Gesperrt“ eingerichtet hat. In dem Falle, wäre der VPN-Client jedesmal wegen einer neuen MAC-Adresse ein neues Gerät und wäre somit per Default blockiert. Das kann man mit einer statischen MAC umgehen, die man sich einmalig via Random-Device selbst erzeugt: $ hexdump -vn5 -e '/5 "02"' -e '/1 ":%02x"' -e '"\n"' /dev/urandom 02:b8:39:89:5d:30 Die 02 im ersten Segment ist eine Besonderheit, aber nicht zwingend. Ich habe die 02 einfach aus Bequemlichkeit gewählt, um die beiden ‚Least Significant Bits‘ im ersten Byte zu setzen. Bit 0 ist ein "multicast bit“, was anzeigt, das ist eine multicast oderr broadcast adresse Bit 1 ist "local bit“, was anzeigt, die MAC ist nicht „assigned by vendor“ und deshalb möglicherweise nicht unique. Somit ist das erste Segment der IP wie folgt gesetzt: 02 = 0000 0010 |
|
Der Funktionstest findet als manuell durchgeführter Test statt. Weil sowohl in der Server- als auch der Client-Conf explizite Log-Datei-Angaben gesetzt sind, sind dazu vorher einige Vorbereitungen durchzuführen.
Für den Test verwende ich neben dem RPi als stationären VPN-Server mein Smartphone, um darüber via Tethering einen WLAN-Accesspoint zur Verfügung zu stellen. Das bedeutet, das Handy ist über „mobile Daten“ mit dem Internet verbunden und öffnet gleichzeitig quasi als WLAN-Router einen WLAN-Zugang für meinen mobilen Laptop. Damit ist eine Testumgebung hergestellt, wie ich sie auch auf Reise ständig erlebe. Den eigentlichen Verbindungs-Test zum Heimnetzwerk führt nun als OpenVPN-Client mein Laptop durch, der sich über das Handy-Netzwerk und damit über eine Internetverbindung mit dem Raspi verbindet.
Sowohl auf dem Server als auch auf dem Laptop (auf beiden ist hier das aktuelle Debian ‚Stable‘ installiert) werden jeweils 2 Terminals geöffnet, einmal zur fließenden Anzeige des lokalen VPN-Logs, das zweite zum Starten und Beenden von OpenVPN. Zum Raspi öffne ich für diesen Zweck 2 SSH-Sitzungen, auf dem Laptop bin ich direkt angemeldet. Die beiden Terminal-Fenster sollten jeweils so angeordnet werden, dass sie beide gleichzeitig sichtbar sind, wobei man das Log-Fenster durchaus großzügiger bemessen kann. Ich lege bei meinen Tests beide Fenster in ganzer Bildschirmbreite übereinander, wobei das obere Log-Fenster etwa ¾ des Bildschirms erhält, der Programm-Aufruf nur ¼ bzw. wegen der Taskbar sogar etwas weniger.
VPN-Server:
$ su - # mkdir /var/log/openvpn # touch /var/log/openvpn/openvpn_udp.log # tail -f /var/log/openvpn/openvpn_udp.log | Log-Anzeige im ersten Terminal des Servers |
# openvpn --config /etc/openvpn/server_udp_br.conf | Start des Programms im zweiten Terminal des Servers |
| |
Terminal | |
Mon Mar 30 14:32:56 2020 OpenVPN 2.4.8 armv7l-unknown-linux-gnueabihf [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] built on Mar 14 2020 Mon Mar 30 14:32:56 2020 library versions: OpenSSL 1.1.1d 10 Sep 2019, LZO 2.10 Mon Mar 30 14:32:56 2020 Diffie-Hellman initialized with 4096 bit key Mon Mar 30 14:32:56 2020 ECDH curve secp384r1 added Mon Mar 30 14:32:56 2020 Outgoing Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key Mon Mar 30 14:32:56 2020 Outgoing Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication Mon Mar 30 14:32:56 2020 Incoming Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key Mon Mar 30 14:32:56 2020 Incoming Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication Mon Mar 30 14:32:56 2020 TUN/TAP device tap0 opened Mon Mar 30 14:32:56 2020 TUN/TAP TX queue length set to 100 Mon Mar 30 14:32:56 2020 Could not determine IPv4/IPv6 protocol. Using AF_INET Mon Mar 30 14:32:56 2020 Socket Buffers: R=[163840->163840] S=[163840->163840] Mon Mar 30 14:32:56 2020 UDPv4 link local (bound): [AF_INET][undef]:55553 Mon Mar 30 14:32:56 2020 UDPv4 link remote: [AF_UNSPEC] Mon Mar 30 14:32:56 2020 GID set to vpnuser Mon Mar 30 14:32:56 2020 UID set to vpnuser Mon Mar 30 14:32:56 2020 MULTI: multi_init called, r=256 v=256 Mon Mar 30 14:32:56 2020 IFCONFIG POOL: base=10.0.1.201 size=10, ipv6=0 Mon Mar 30 14:32:56 2020 Initialization Sequence Completed |
VPN-Client:
$ su - # mkdir /var/run/openvpn # touch /var/run/openvpn/client.log # tail -f /var/run/openvpn/client.log | Log-Anzeige im ersten Terminal des Client-Geräts |
# openvpn --config /etc/openvpn/client_udp_br.conf | Start des Programms im zweiten Terminal des Client-Geräts |
| |
Terminal | |
Mon Mar 30 15:28:44 2020 OpenVPN 2.4.8 x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [MH/PKTINFO] [AEAD] built on Nov 13 2019 Mon Mar 30 15:28:44 2020 library versions: OpenSSL 1.1.1d 10 Sep 2019, LZO 2.10 Mon Mar 30 15:28:44 2020 Outgoing Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key Mon Mar 30 15:28:44 2020 Outgoing Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication Mon Mar 30 15:28:44 2020 Incoming Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key Mon Mar 30 15:28:44 2020 Incoming Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication Mon Mar 30 15:28:44 2020 TCP/UDP: Preserving recently used remote address: [AF_INET]189.45.649.808:55553 Mon Mar 30 15:28:44 2020 Socket Buffers: R=[212992->212992] S=[212992->212992] Mon Mar 30 15:28:44 2020 UDP link local (bound): [AF_INET][undef]:55553 Mon Mar 30 15:28:44 2020 UDP link remote: [AF_INET]189.45.649.808:55553 Mon Mar 30 15:28:45 2020 TLS: Initial packet from [AF_INET]189.45.649.808:55553, sid=44968a94 a552338d Mon Mar 30 15:29:00 2020 VERIFY OK: depth=1, CN=toml.de Mon Mar 30 15:29:00 2020 VERIFY KU OK Mon Mar 30 15:29:00 2020 Validating certificate extended key usage Mon Mar 30 15:29:00 2020 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication Mon Mar 30 15:29:00 2020 VERIFY EKU OK Mon Mar 30 15:29:00 2020 VERIFY OK: depth=0, CN=Server Mon Mar 30 15:29:00 2020 Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, 384 bit EC, curve: secp384r1 Mon Mar 30 15:29:00 2020 [Server] Peer Connection Initiated with [AF_INET]189.45.649.808:55553 Mon Mar 30 15:29:01 2020 SENT CONTROL [Server]: 'PUSH_REQUEST' (status=1) Mon Mar 30 15:29:01 2020 PUSH: Received control message: 'PUSH_REPLY,route-gateway 10.0.1.200,ping 10,ping-restart 60,ifconfig 10.0.1.201... Mon Mar 30 15:29:01 2020 OPTIONS IMPORT: timers and/or timeouts modified Mon Mar 30 15:29:01 2020 OPTIONS IMPORT: --ifconfig/up options modified Mon Mar 30 15:29:01 2020 OPTIONS IMPORT: route-related options modified Mon Mar 30 15:29:01 2020 OPTIONS IMPORT: peer-id set Mon Mar 30 15:29:01 2020 OPTIONS IMPORT: adjusting link_mtu to 1656 Mon Mar 30 15:29:01 2020 OPTIONS IMPORT: data channel crypto options modified Mon Mar 30 15:29:01 2020 Outgoing Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key Mon Mar 30 15:29:01 2020 Incoming Data Channel: Cipher 'AES-256-GCM' initialized with 256 bit key Mon Mar 30 15:29:01 2020 TUN/TAP device tap0 opened Mon Mar 30 15:29:01 2020 TUN/TAP TX queue length set to 100 Mon Mar 30 15:29:01 2020 /usr/sbin/ifconfig tap0 hw ether 02:b8:39:89:5d:30 Mon Mar 30 15:29:01 2020 TUN/TAP link layer address set to 02:b8:39:89:5d:30 Mon Mar 30 15:29:01 2020 /usr/sbin/ifconfig tap0 10.0.1.201 netmask 255.255.255.0 mtu 1500 broadcast 10.0.1.255 Mon Mar 30 15:29:01 2020 Initialization Sequence Completed |
Sofern weder beim Start von OpenVPN auf den beiden Systemen Fehlermeldungen berichtet wurden, noch beim Herstellen der Verbindung, die Verbindung offensichtlich funktioniert und die Systeme untereinander sowie zu und von anderen Clients vollständig erreichbar waren, kann nun der Server ‚produktiv‘ gesetzt werden.
# systemctl enable openvpn.service # systemctl start openvpn.service | Sofern der Verbindungs-Test erfolgreich durchgeführt war und die manuellen Starts beendet sind, kann der VPN-Server nur für den Systemstart aktiviert und sofort als Daemon gestartet werden. |
|
Ein wichtiger Hinweis zum Schluss! Das hier beschriebene Bridging-Modell für einen OpenVPN-Tunnel ins Heimnetzwerk benötigt für die reine Funktion der Verbindung von außerhalb über das Internet zum Heimnetzwerk keine Paketfilter-Regeln. Das bedeutet, Einstellungen für iptables oder nftables sind nicht notwendig. Aber, und das ist der wichtigste Hinweis: Man sollte in seinem eigenen Interesse auf gar keinen Fall sein mobiles Gerät einfach so an einem fremden Gastgeber-Netzwerk (Restaurants, Cafes, Hotels oder irgendwo in der City an zufällig gefundenen offenen WLAN-Netze) ohne Schutzmaßnahmen anmelden und verbinden, wenn die Absicht besteht, anschließend einen VPN-Tunnel via Bridging nachhause zu öffnen. Schlimmstenfalls hat man damit eine Durchmarsch-Route für fremde und ebenfalls im im Gastgeber-Netz aktive Geräte bis hin in sein eigenes Netzwerk zuhause eröffnet. | |
Aber die notwendigen Firewall-Regeln, um solche Gefahren zu eliminieren, können natürlich hier aufgrund des kritischen Umfangs der möglichen Security-Verstöße kein Thema sein. Das Einrichten restriktiver Firewall-Regeln, deaktivieren unbenötigter Services, restriktive User-Berechtigungen, beschränken von ‚lauschenden Diensten‘ und weitergehende Erklärungen habe ich im Artikel Security beschrieben. Und ja, man kann diese Hinweise natürlich auch ignorieren und sich selbstherrlich über berechtigte Warnungen hinwegsetzen. Nun ja, da kann man nichts machen... Sicherheit existiert jedenfalls nur solange, wie der ‚Admin‘ nicht selber auf Sicherheit verzichtet oder schlimmstenfalls sogar fahrlässig eine vorhandene Sicherheit außer Kraft setzt. Mach Dir einfach bewusst, wenn Du auf eine absolute und exklusive Kontrolle Deines Netzwerk verzichtest, hast Du auch keine Kontrolle darüber, wer die Hardware Deines Netzwerks unerlaubt mitbenutzt und darüber Zugang zu privaten Daten und Ressourcen im Netzwerk hat. Wenn Deine Netzwerkzugänge einmal kompromittiert sind, hast Du auch kaum eine Möglichkeit das im Nachgang noch festzustellen. Irgendwelche Antiviren-Programme können da jedenfalls keinen Schutz herstellen, weil sie solche ausgenutzten Exploits gar nicht feststellen können. |
|
Haftungsausschluss: Ich erhebe keinen Anspruch darauf, dass diese Dokumentation vollständig fehlerfrei ist und ich behaupte das auch nicht. Sowohl - durch meine Fehler hier im Tutorial - wie auch durch vorhandene Fehler in den hier verwendeten Linux-Programmen - sowie durch ggf. zeitgleich auftretende äußere mechanische Einflüsse - oder durch den Anwender selber verursacht durch Änderungen an Programmen - oder durch unsachgemäße oder fehlerhafte Einrichtung der Programme beim Setup, z.B. wegen fehlerhafter Parameter kann es zu Datenverlust kommen. Durch unsachgemäße Sicherung und dem Betrieb eines deswegen unsicheren von außen erreichbaren Zugang ins Heimnetzwerk kann sogar das ganze private Netzwerk kompromittiert werden. Deshalb schließe ich jede Haftung für Schäden an Software oder Hardware oder Vermögensschäden oder für Datenverlust aus, die durch die Benutzung dieses Tutorials enstehen. Die Benutzung dieses Tutorials, die Einrichtung der Services danach und der produktive Einsatz erfolgt auf eigenes Risiko. |
|
Service-Unit für Bridge und DHCP
# ne /etc/systemd/system/network-bridge-dhcp.service [Unit] Description=thlu:network-bridge-dhcp.service Bridged Network for VPN After=basic.target Before=network.target shutdown.target Wants=network.target Conflicts=shutdown.target
[Service] Environment="PATH=/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" Type=oneshot RemainAfterExit=yes
ExecStartPre=openvpn --mktun --dev tap0 ExecStartPre=ip link add br0 type bridge ExecStartPre=ip link set br0 type bridge stp_state 0 ExecStartPre=ip link set br0 type bridge forward_delay 0 ExecStartPre=ip link set br0 address b8:27:dd:kk:yz:5d ExecStartPre=sysctl -w net.ipv6.conf.br0.forwarding=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.disable_ipv6=0 ExecStartPre=sysctl -w net.ipv6.conf.br0.autoconf=1 ExecStartPre=sysctl -w net.ipv6.conf.br0.use_tempaddr=2 ExecStartPre=sysctl -w net.ipv6.conf.br0.accept_ra=2 ExecStartPre=ip link set eth0 master br0 ExecStartPre=ip link set eth0 up ExecStartPre=ip link set tap0 master br0 ExecStartPre=ip link set tap0 up ExecStartPre=ip link set br0 up ExecStartPre=dhclient -v br0 ExecStart =true
ExecStop =ip link set tap0 nomaster ExecStopPost=ip link set tap0 down ExecStopPost=ip addr flush dev tap0 ExecStopPost=openvpn --rmtun --dev tap0 ExecStopPost=ip link set eth0 nomaster ExecStopPost=ip link set eth0 down ExecStopPost=ip addr flush dev eth0 ExecStopPost=ip link set br0 down ExecStopPost=ip addr flush dev br0 ExecStopPost=ip link del br0 type bridge
[Install] WantedBy=multi-user.target | Alternative Service-Unit zum Starten des Netzwerkes, die hier nicht als Static-IP-Setup, sondern mit IP via DHCP-Server realisiert ist.
|