Als ich mich vor ein paar Jahren mit virtuellen privaten Netzwerken - kurz VPN - beschäftigt habe, war das ganze ein ziemliches Geknorze und für den Durschnittsbenutzer mühselig zu installieren.

Glücklicherweise hat sich in den letzten 5 Jahren vorallem (aber nicht nur) dank der immer besser werdenden und günstig erhältlichen Raspberry Pi und deren breiten Einsatzmöglichkeiten viel in der Entwicklung getan.

Da Raspian - das Betriebssystem des Raspberry Pi - abgesehen von ein paar Optimierungen für die ARM-Prozessoren und Raspberry Pi Hardware und einer ressourcenschonenderen Desktopumgebung praktisch identisch mit Debian ist, lassen sich viele Konzepte 1:1 auch auf "echten" (als ob der Raspberry Pi kein richtiger Computer wäre) bzw. virtuellen Computern in Debian umsetzen.

Eines dieser Konzepte ist, wie ich es nennen, die heilige Dreifaltigkeit der Privatsphäre - PiVPN, Pi-Hole und Unbound

Hier werde ich nun erklären wie man dieses Konzept mit wenigen Schritten selbst in einer Debian-basierten (virtuellen) Maschine erstellt.

Übrigens ist ein Raspberry Pi die bevorzugte Methode um dies zu realisieren und die Befehle sind, wie bereits erwähnt, 1:1 die selben! Ich habe das ganze Szenario auf eine virtuelle Maschine portiert, weil ich auch ohne einen Raspberry Pi bereits genügend Kabelsalat in meiner Wohnung habe und mein PC eh die ganze Zeit läuft.

Wichtig: hier geht es rein um die Privatsphäre und den Zugriff auf das eigene Netzwerk auch wenn man nicht zuhause ist! Mit diesem Konzept ist man nicht anonym im Internet!

Virtuelle Maschine

Ich setze voraus, dass man weiss wie man eine virtuelle Maschine erstellt!
Ansonsten gibt es dazu genügend Anleitungen im Internet.
Wichtig ist nur, dass die Maschine eine fixe IP hat und im LAN erreichbar ist!
Ausserdem sollte sie auf einem Computer laufen der permanent läuft, ansonsten hat man keinen Internetzugang mehr!

Ich habe folgende Grundeinstellungen gewählt

  • 1-2 CPUs
    Je nachdem wieviele Clients man bedienen will - in meinem Netzwerk benutzen um die 10 Clients das Netz weshalb 1 CPU völlig ausreicht
  • 2GB Arbeitsspeicher
  • 20GB Harddisk
    Bei mir wird aktuell etwa 25% davon benutzt

Betriebssystem

Für das Betriebssystem habe ich, wie schon erwähnt, Debian 11 Bullseye benutzt.

Das Betriebssystem wird ganz normal installiert, allerdings wählt man keinen Desktop sondern installiert nur das minimale Basissystem und den SSH-Server.
Der SSH-Server ist grundsätzlich optional, allerdings ist er praktisch da man Befehle einfacher kopieren und einfügen kann und wird auch im Zuge dieses Tutorials verwendet.
Als Benutzer habe ich pivpn gewählt.

Anschliessend müssen ein paar Kleinigkeiten wie die fixe IP und sudo für den Benutzer konfiguriert werden.

Am besten logged man sich direkt in der VM als root ein um die statische IP und sudo zu konfigurieren. Anschliessend kann man sich über SSH einloggen um die Software zu installieren und konfigurieren.

Statische IP

Um eine statische IP zu setzen muss die /etc/network/interfaces Datei geändert werden.
Ich benutze die IP 192.168.0.2 da die in einem freien Bereich meines Netzwerks liegt.
Wichtig ist, dass man den korrekten Namen des Interfaces benutzt, in meinem Fall ist das enp1s0.
Da ich später noch Unbound installiere setze ich 127.0.0.1 als primären DNS-Server ein und 1.1.1.1 (Cloudflare) als Backup.
Das Gateway ist die IP des Routers.

nano /etc/network/interfaces
# The primary network interface
auto enp1s0
iface enp1s0 inet static
  address 192.168.0.2
  netmask 255.255.255.0
  gateway 192.168.0.1
  dns-nameservers 127.0.0.1 1.1.1.1

Anschliessend startet man den Netzwerk Service neu.

systemctl restart networking.service

Jetzt kann ich bereits auf SSH wechseln um den Rest der Konfiguration vorzunehmen.
Da ich mit einem Linux Betriebssystem arbeite, kann ich mich bequem in der Konsole verbinden.

ssh -o TCPKeepAlive=yes -o ServerAliveCountMax=20 -o ServerAliveInterval=15 pivpn@192.168.0.2

Sudo

Nun fügt man noch den Benutzer pivpn der sudo Gruppe hinzu.

Falls man bereits über SSH eingeloggt ist, muss man sich mit folgendem Befehl zu root machen:

su -

Der "-" ist notwendig weil sonst die PATH-Variable nicht geladen wird.
Anschliessend folgt:

apt install sudo
usermod -aG sudo pivpn

Damit die Gruppenänderung des Benutzers aktiv wird, muss man sich kurz aus- und wieder einloggen.
Nun ist das Betriebssystem bereit um die heilige Dreifaltigkeit der Privatsphäre zu installieren.

Unbound

Als erstes installiere ich den Unbound DNS Server gemäss der Anleitung von der Pi-Hole Webseite.
Dort hat es auch noch zusätzliche interessante Informatione die sich zu lesen lohnen.
Ich habe einfach die benötigten Befehle kopiert.

Installieren

sudo apt install unbound

Danach erstellt man eine Konfigurationsdatei wie folgt

sudo nano /etc/unbound/unbound.conf.d/pi-hole.conf

und fügt folgende Konfiguration ein

server:
    # If no logfile is specified, syslog is used
    # logfile: "/var/log/unbound/unbound.log"
    verbosity: 0

    interface: 127.0.0.1
    port: 5335
    do-ip4: yes
    do-udp: yes
    do-tcp: yes

    # May be set to yes if you have IPv6 connectivity
    do-ip6: no

    # You want to leave this to no unless you have *native* IPv6. With 6to4 and
    # Terredo tunnels your web browser should favor IPv4 for the same reasons
    prefer-ip6: no

    # Use this only when you downloaded the list of primary root servers!
    # If you use the default dns-root-data package, unbound will find it automatically
    #root-hints: "/var/lib/unbound/root.hints"

    # Trust glue only if it is within the server's authority
    harden-glue: yes

    # Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
    harden-dnssec-stripped: yes

    # Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
    # see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
    use-caps-for-id: no

    # Reduce EDNS reassembly buffer size.
    # IP fragmentation is unreliable on the Internet today, and can cause
    # transmission failures when large DNS messages are sent via UDP. Even
    # when fragmentation does work, it may not be secure; it is theoretically
    # possible to spoof parts of a fragmented DNS message, without easy
    # detection at the receiving end. Recently, there was an excellent study
    # >>> Defragmenting DNS - Determining the optimal maximum UDP response size for DNS <<<
    # by Axel Koolhaas, and Tjeerd Slokker (https://indico.dns-oarc.net/event/36/contributions/776/)
    # in collaboration with NLnet Labs explored DNS using real world data from the
    # the RIPE Atlas probes and the researchers suggested different values for
    # IPv4 and IPv6 and in different scenarios. They advise that servers should
    # be configured to limit DNS messages sent over UDP to a size that will not
    # trigger fragmentation on typical network links. DNS servers can switch
    # from UDP to TCP when a DNS response is too big to fit in this limited
    # buffer size. This value has also been suggested in DNS Flag Day 2020.
    edns-buffer-size: 1232

    # Perform prefetching of close to expired message cache entries
    # This only applies to domains that have been frequently queried
    prefetch: yes

    # One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
    num-threads: 1

    # Ensure kernel buffer is large enough to not lose messages in traffic spikes
    so-rcvbuf: 1m

    # Ensure privacy of local IP ranges
    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    private-address: 172.16.0.0/12
    private-address: 10.0.0.0/8
    private-address: fd00::/8
    private-address: fe80::/10

Danach startet man Unbound neu

sudo service unbound restart

Pi-Hole

Zuerst muss man noch curl installieren danach kann man Pi-Hole mit einem einzigen Befehl installieren

sudo apt install curl
curl -sSL https://install.pi-hole.net | bash

Nach dem Abschluss der Installation sichert man das generierte Passwort in einem Passwortmanager.
Man kann das Passwort für den Admin-Benutzer aber auch jederzeit durch folgenden Befehl ändern

pihole -a -p

Damit nun automatisch alle Geräte welche über DHCP im Netzwerk verbunden sind von Pi-Hole profitieren können gibt es 2 Möglichkeiten

  • Man macht Pi-Hole zum DHCP-Server und deaktiviert den bisherigen DHCP-Server
    (dieser läuft bei den meisten Nutzern im Router)
  • Man benutzt Pi-Hole als DNS-Server im bisherigen DHCP-Server

Wichtig: wenn man Geräte im Netzwerk hat welche mit einer statischen IP konfiguriert wurden, dann muss man dort in der Konfiguration die IP-Adresse von Pi-Hole als DNS-Server eintragen.
Ich setze bei meinen statischen Geräten immer noch den Cloudflare DNS-Server 1.1.1.1 als 2. DNS-Server, falls mein Pi-Hole mal aussteigen sollte.
Dies kann man übrigens auch beim DHCP-Server machen.

Weiterführende Informationen wie man Pi-Hole weiter konfigurieren und nutzen kann oder zusätzliche Blocklisten finden sich auf der offiziellen Webseite oder im Netz.

PiVPN

Da ich eine statische öffentliche IP habe, habe ich das Tutorial auch so geschrieben. Für alle die keine statische IP haben gibt's hier eine Anleitung wie man mit DuckDNS eine Domain bekommt und mit Hilfe eines Cron die eigene IP updated (Punkt 1 bis 3).

Wenn man dies vor der Installation von PiVPN einrichtet, muss man anschliessend die config-Dateien (Punkt 4) nicht manuell Anpassen!

Anmerkung: wenn man einen Glasfaseranschluss hat (zum Teil reicht auch schon ein Kupferkabelanschluss) hat man bei einigen ISP bereits quasi eine statische IP die selbst bei einem Neustart des Modems nicht wechselt.
Wer nach der devise Lebt "no risk, no fun" kann PiVPN so auch mit einer statischen IP konfigurieren. Allerdings besteht das Risiko, dass man bei einem wechsel der IP sowohl den Wireguard-Server wie auch alle Geräte die das VPN nutzen entsprechend anpassen muss.

PiVPN ist mit einem einzelnen Befehl ähnlich einfach zu installieren wie Pi-Hole

curl -L https://install.pivpn.io | bash

Nun muss man im Router den vorher konfigurierten Port 51820 von Wireguard auf die IP 192.168.0.2 weiterleiten.
Da dies bei jedem Router ein wenig anders funktioniert, gehe ich nicht näher darauf ein und verweise auf die Betriebsanleitung des Routers.
Man muss nach Einstellungen im Bereich NAT bzw. Portweiterleitung suchen.
Bei meinem TP-Link Router heisst die Einstellung, warum auch immer, "Virtuelle Server".
Wird der Port nicht korrekt weitergeleitet kann man sich nicht zum VPN verbinden!

Anschliessend kann man ganz einfach ein Gerät hinzufügen mit

pivpn add --name pmjgalaxy

Damit habe ich eine Konfiguration für mein Samsung Galaxy erstellt welche ich nun nutzen kann.
Anmerkung: den Namen für den Client kann man frei wählen.
Wichtig: Man muss für jedes Gerät, mit dem man das VPN nutzen möchte, eine eigene Konfiguration erstellen, da alle Geräte eine eigene IP benötigen.

Da ich das VPN mit Wireguard erstellt habe, kann ich nun ganz einfach mit dem Wireguard Client eine Verbindung in das VPN herstellen.
Es gibt praktisch für jedes Betriebssystem einen Client.

Dazu kopiere ich entweder die Konfiguration (in meinem Falle pmjgalaxy.conf) im Verzeichnis /home/pivpn/configs in den Client oder, für Geräte mit QR-Code-leser, scanne mit Wireguard Client den QR-Code der sich mit folgendem Befehl erstellen lässt

pivpn qrcode pmjgalaxy

So!
Damit ist der gesamte Traffic meins Samsung Galaxy verschlüsselt, läuft zuerst duch Pi-Hole und Unbound und ich habe zusätzlich von überall auf der Welt Zugriff auf mein Heim-Netzwerk.
Feine Sache :)

Noch eine Bemerkung zum Schluss

Falls das Gerät mal verloren gehen sollte oder verkauft oder entsorgt wird, ist es äusserst ratsam die VPN Konfiguration umgehend aus dem VPN-Server zu entfernen!
Ansonsten besteht die Gefahr dass Dritte den Server und das Netzwerk kompromitieren könnten!

pivpn remove pmjgalaxy

Es ist auch ratsam mindestens einmal pro Woche den Server auf Updates zu prüfen und diese zu installieren

sudo apt-get update && sudo apt-get upgrade

Es ist ebenfalls ratsam anschliessend den Server neu zu starten

sudo reboot

Enjoy!