z_Archiv
Alte Anleitungen und Dokumentationen, die nicht zwingend korrekt funktionieren, allerdings als Inspiration dienen können.
Alte Anleitungen und Dokumentationen, die nicht zwingend korrekt funktionieren, allerdings als Inspiration dienen können.
Die Anleitung kann veraltet sein und kann als Inspiration genutzt werden!
Wer kennt es nicht, man möchte mehrere Geräte durch einen VPN Tunnel leiten, aber nicht auf jedem die App installieren, oder andere VPN Konfigurationen nutzen.Deshalb möchte ich hier beschreiben, wie ein Nordvpn Tunnel im Docker gebaut wird und beliebig viele Wireguard-Clients angebunden werden können.Der gesamte Traffic der Wireguard-Clients wird in den Nordvpn Tunnel geroutet, sodass die Clients die ausgehende IP-Adresse des Nordvpn Tunnels erhalten. Die Anleitung geht davon aus, dass systemd-networkd und Docker verwendet wird! Das verwendete IP-Netz für die Clients ist 192.168.20.0/24 (192.168.20.1 - 192.168.20.254). Der Server erhält die .1, alle Clients aufsteigend ab .2.
Im Archlinux-Wiki ist eine ausführliche Anleitung zu finden (https://wiki.archlinux.org/title/WireGuard), deshalb hier eine kurze Zusammenfassung:
Hier wird ein private Key (server.key), der daraus abgeleitete public Key (server.pub) und ein Preshared Key (server_client1.psk) generiert. Für den Server wird nur ein einziger privater Schlüssel benötigt, allerdings sollte jede Verbindung einen eigenen PSK erhalten. Der letzte Befehl kann beliebig wiederholt werden (client1 zu client2, client3, … ändern!):
mkdir /etc/wireguard
cd /etc/wireguard
(umask 0077; wg genkey > server.key)
wg pubkey < server.key > server.pub
wg genpsk > server_client1.psk
Bitte beachten, dass jeder Client eine eigene WireGuardPeer Sektion erhalten muss. In diese muss der Public-Key des Clients und der gemeinsame, beidseitig identische PSK hinterlegt werden. Die IP-Adressen können ebenfalls angepasst werden, je nach Bedarf.
mkdir -p /etc/systemd/network/
cd /etc/systemd/network/
PKEY=$(cat /etc/wireguard/server.key)
PSK1=$(cat /etc/wireguard/server_client1.psk)
echo "
[NetDev]
Name=wg0
Kind=wireguard
Description=Wireguard VPN direct tunnel for multi devices
[WireGuard]
PrivateKey = ${PKEY}
ListenPort = 12345
[WireGuardPeer]
PublicKey = <CLIENTS_PUBLIC_KEY>
AllowedIPs = 192.168.20.2/32
PresharedKey = ${PSK1}" > wg0.netdev
echo "
[Match]
Name=wg0
[Network]
Address=192.168.20.1/24" > wg0.network
Wie bereits erwähnt, wird Docker benötigt und der Container baut die VPN Verbindung auf. Dadurch dass dieser in einem eigenen Netzwerkbereich isoliert ist, kann Nordpvn zwar Firewall-Regeln und Routen konfigurieren, diese verändern aber nichts am Host selbst, was sehr wünschenswert ist.
Hierfür bietet sich die Erstellung eines Tokens an, diesen erhält man von Nordpvn:https://my.nordaccount.com/de/dashboard/nordvpn/Runterscrollen zum Punkt Zugangstoken, einen erstellen und in die Variable TOKEN speichern (xxxxxxxxxxxxxxxxxxx ersetzen):
# Debian / Ubuntu
apt-get update; apt-get install docker-compose
# Archlinux
pacman -Syu docker-compose
TOKEN="xxxxxxxxxxxxxxxxxxx"
mkdir -p /srv/docker/nordvpn
cd /srv/docker/nordvpn
echo "
version: "3"
services:
nvpn1:
image: ghcr.io/bubuntux/nordvpn
container_name: "nordvpn_1"
restart: unless-stopped
environment:
TOKEN: ${TOKEN}
# alle Netze die über Nordvpn geroutet werden sollen, kommasepariert hinterlegen
NET_LOCAL: 192.168.20.0/24
cap_add:
- NET_ADMIN
- NET_RAW
networks:
default:
ipv4_address: 192.168.21.2
networks:
default:
driver: bridge
ipam:
driver: default
config:
- subnet: 192.168.21.0/24
driver_opts:
com.docker.network.bridge.name: br_nordvpn" > docker-compose.yml
# Container hochfahren
docker-compose up -d
Die Routing Tabelle 333 ist wilkürlich gewählt und kann eine beliebige Zahl sein. Beim Eintrag ist wichtig, dass der Name des Interfaces (br_nordvpn) dem der Bridge entspricht, damit in der Routing-Tabelle das richtige Interface hinterlegt wird!
echo "
[Match]
Name=br_nordvpn
# Docker setzt auf dem Host nicht zwingend die IP-Adresse
# dies wird Systemd-Networkd korrigieren
[Network]
Address=192.168.20.1/24
ConfigureWithoutCarrier=yes
# das Netz der Docker Bridge muss in die Routing Tabelle 333
[Route]
Destination=192.168.21.0/24
Table=333
# der gesamte Internet-Traffic wird über den Nordvpn Docker-Container geroutet
[Route]
Destination=0.0.0.0/0
Gateway=192.168.21.2
Table=333
# Traffic eingehend vom Absendernetz (Wireguard) wird über Einträge aus der Routing-Tabelle 333 geroutet
# ohne die Policy würde die Haupttabelle gelten und es ohne Nordvpn im Internet landen
# sollen weitere Tunnel / Netze berücksichtigt werden, einfach pro Netz (!) eine RoutingPolicyRule hinterlegen
[RoutingPolicyRule]
From=192.168.20.0/24
Table=333" > /etc/systemd/network/br_nordvpn.network
# Berechtigungen korrigieren
chown -R systemd-network:systemd-network /etc/systemd/networkd/
chmod 750 /etc/systemd/networkd/
chmod 640 /etc/systemd/networkd/
# Netzwerk Daemon reload
systemctl reload systemd-networkd
Im Anschluss wird die Routing Tabelle und Rule angelegt. Dies kann man nun prüfen:
ip rule show
...
32765: from 192.168.20.0/24 lookup 333 proto static
ip route show table 333
default via 192.168.21.2 dev br_nordvpn proto static
192.168.21.0/24 dev br_nordvpn proto static scope link
Nun sollte Traffic bereits über Nordvpn geleitet werden. Im Container kann man auch die Routen prüfen:
docker exec -ti nordvpn_1 bash
ip route
# der Gesamte Traffic wird nach der Verpackung in das Nordvpn Paket über den Host in das Internet geroutet
default via 192.168.21.1 dev eth0
# das Wireguard Netz muss bekannt sein, bzw. wird vom Container explizit hinterlegt. Ohne die Angabe in LOCAL_NET (docker-compose.yml) würde Traffic von diesem Netz verworfen...
192.168.20.0/24 via 192.168.21.1 dev eth0
# das Docker Netz mit Absender-IP des Docker Containers
192.168.21.0/24 dev eth0 proto kernel scope link src 192.168.21.2
# für technisch interessierte Personen kann man sich auch die Firewall-Regeln ansehen:
iptables -nvL
iptables -t nat -nvL
Je nachdem welchen Client man verwendet (App, Windows App, etc.) muss die Konfiguration ggf. etwas angepasst werden. Aber hier ein Beispiel für die Windows App:
[Interface]
PrivateKey = <CLIENTS PRIVATE KEY MEIST VORGENERIERT>
Address = 192.168.20.11/32
[Peer]
PublicKey = <PUB KEY DES SERVERS>
PresharedKey = <SERVER CLIENT1 PSK>
# route das gesamte Internet über den Tunnel (wenn nicht gewünscht 0.0.0.0/0 durch entsprechende Netze ersetzen. Zum Beispiel 1.1.1.1, 8.8.8.8, 8.8.4.0/24, ...)
AllowedIPs = 0.0.0.0/0
Endpoint = <IP DES SERVERS>:12345
# Keepalive check alle 30 Sekunden
PersistentKeepalive = 30
Nach einer Verbindung mit dem Wireguard Tunnel dürfte man nun für den Traffic ins Internet eine IP-Adresse aus dem Nordvpn Netz nutzen. Natürlich nur, wenn auch der Wireguard Port (12345 UDP) freigeschaltet wurde. Sollte ein anderer Port gewählt worden sein, müsste man dies berücksichtigen ;)
Die Anleitung kann veraltet sein und kann als Inspiration genutzt werden!
Oft benötigt man verschiedene Betriebssysteme als Bootstick, möchte aber nicht für jedes einen eigenen USB Stick bereithalten, oder den einen dauernd überschreiben.
Um das Chaos zu vermeiden, lässt sich relativ schnell ein Multi-Boot-Stick erstellen, der Betriebssysteme wie Linux, Windows und auch diverse Boot CDs bereithält.
In dieser Anleitung wird folgendes getan:
Folgende Betriebssysteme sind angedacht:
Vorab möchte ich erwähnen, dass diese Anleitung für Linux gedacht ist. Falls gerade kein Linux zur Hand ist, einfach einen Stick mit Ubuntu vorbereiten und diesen booten.
Alle Befehle sind mit Vorsicht zu verwenden, bei fehlerhafter Handhabung können Daten gelöscht werden. Man sollte also sicher sein, welche Festplatte / USB-Device man verwendet. In diesem Beispiel ist stets von /dev/sda die Rede, weil mein Laptop eine NVME nutzt. Je nach eigener Hardware kann dies anders sein und der USB-Stick z.B. /dev/sd[b,c,d,e…] lauten.
Die meisten Befehle benötigen Root-Rechte, deswegen wurde das oft vorangestellte “sudo” weg gelassen…
# Ubuntu
apt-get update && apt-get install util-linux parted ntfs-3g dosfstools wget
# Archlinux
pacman -Syu util-linux parted ntfs-3g dosfstools wget
# Auflistung aller Disks
lsblk -d
# bei Unsicherheit (auch Partitionen anzeigen)
lsblk
# -s sorgt für "script"-Modus (keine Rückfragen)
# GPT-Partionstabelle anlegen (für UEFI Boot nötig)
parted -s /dev/sda mklabel gpt
parted -s /dev/sda mkpart primary 1m 2m
# ESP//dev/sda Boot Partition
parted -s /dev/sda mkpart primary 2m 100m
# EXT4 Partition für GRUB (Bootloader) und Isos
parted -s /dev/sda mkpart primary 100m 30g
# Windows Partition
parted -s /dev/sda mkpart primary 30g 40g
# UEFIs ESP Partition muss FAT32 formatiert sein
mkfs.vfat -F 32 /dev/sda2
# Grub liest ext4-Dateisysteme
mkfs.ext4 /dev/sda3
# -f (fast, quick) (für Windows)
mkfs.nfts -f /dev/sda4
mount /dev/sda3 /mnt/
cd /mnt/
# Isos werden unter /mnt/boot/iso gelegt (Grub sucht in seinem Root-Dir)
mkdir -p /mnt/boot/{EFI,iso}
# EFI Partition
mount /dev/sda2 /mnt/boot/EFI
# temporärer Ordner für GPT-Parittion 4 (Windows)
mkdir -p /tmp/windows_part
mount /dev/sda4 /tmp/windows_part
Die Links können und werden nach einiger Zeit veraltet sein. Die aktuellen findet man in Suchmaschinen…
cd /mnt/boot/iso
# Die Links werden zukünftig veraltet oder nicht mehr verfügbar sein, einfach aktuelle Images suchen!
wget https://releases.ubuntu.com/22.04/ubuntu-22.04-desktop-amd64.iso
wget https://mirror.fra10.de.leaseweb.net/archlinux/iso/2022.07.01/archlinux-2022.07.01-x86_64.iso
# Windows Image runterladen (und unter /tmp/ legen)
https://www.microsoft.com/en-in/software-download/windows10
# das Windows.iso liegt nun unter /tmp/windows10.iso
mkdir -p /tmp/win_iso_mount
# ISO read-only unter /tmp/win_iso_mount mounten
mount -o loop /tmp/windows.iso /tmp/win_iso_mount
# Dateien auf die 4. Partition des USB Sticks kopieren
cp -R /tmp/win_iso_mount/* /tmp/windows_part
# danach kann die 4. Partition wieder unmounted werden
umount /tmp/windows_part
Es wird davon ausgegangen, dass Grub im System installiert ist…
grub-install --target=i386-pc --recheck --boot-directory=/mnt/boot /dev/sda
grub-install --target=x86_64-efi --recheck --removable --efi-directory=/mnt/boot/EFI/ --boot-directory=/mnt/boot/
Vorgefertige Templates findet man im Internet, zum Beispiel hier: https://github.com/hackerncoder/multibootusb/blob/master/grub.cfg.example
Diese kopiert man und legt die Datei unter /mnt/boot/grub/grub.cfg:
wget https://raw.githubusercontent.com/hackerncoder/multibootusb/master/grub.cfg.example -O /mnt/boot/grub/grub.cfg
Danach werden weitere Einträge angelegt, zur Orrientierung habe ich die Stelle mit ### markiert. Darüber und darunter sind die Einstiegspunkte zu erkennen:
# Load MBUSB configuration
if [ -e "$prefix/mbusb.cfg" ]; then
source "$prefix/mbusb.cfg"
fi
### HIER EINFUEGEN
# die UUID des aktuellen RootFS wird ermittelt und in rootuuid gespeichert
probe -u $root --set=rootuuid
# die Disk wird anhand der ermittelten UUID referenziert (für Arch relevant)
set imgdevpath="/dev/disk/by-uuid/$rootuuid"
menuentry "ubuntu-22.04-desktop-amd64.iso" {
insmod ext2
# Die ISO-Datei sollte im Pfad liegen, pruefen!
set isofile="/boot/iso/ubuntu-22.04-desktop-amd64.iso"
loopback loop $isofile
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile quiet noeject noprompt splash
initrd (loop)/casper/initrd
}
menuentry 'archlinux-2022.07.01-x86_64.iso' {
# Die ISO-Datei sollte im Pfad liegen, pruefen!
set isofile='/boot/iso/archlinux-2022.07.01-x86_64.iso'
loopback loop $isofile
linux (loop)/arch/boot/x86_64/vmlinuz-linux img_dev=$imgdevpath img_loop=$isofile earlymodules=loop
initrd (loop)/arch/boot/x86_64/initramfs-linux.img
}
menuentry "Windows 10 (20H2) UEFI" {
# die 4. Partition ist fuer Windows vorgesehen!
set root=(hd0,gpt4)
insmod part_gpt
insmod ntfs
insmod chain
chainloader /efi/boot/bootx64.efi
}
### ENDE
# Grub options
submenu "GRUB2 options ->" {
Wenn alles fertig ist, sollte man die Ordnerstruktur verlassen, falls man sich noch in dieser befindet (/mnt/…).
# Wenn alles fertig ist, sollte man die Ordnerstruktur verlassen, falls man sich noch in dieser befindet (/mnt/...).
cd
umount /mnt/boot/EFI
umount /mnt/
sync
Und im Anschluss sollte der Stick genutzt werden können.
MultibootUSB Projekt für Beispielkonfigurationen
Archlinux Wiki
Beispielkonfigurationen für GRUB
Die Anleitung kann veraltet sein und kann als Inspiration genutzt werden!
Diese Anleitung installiert sowohl nginx, als auch den Certbot, damit das Webinterface von Pihole per HTTPS erreichbar ist.
Möchte man das Webinterface nur intern verwenden und hat keine feste IP-Adresse oder Dyndns für die äußere IP, wird das ausstellen des Zertifikats komplizierter und man muss ggf. zur DNS Validierung greifen. Diese wird aber nicht Bestandteil der Anleitung sein, weil je nach DNS-Anbieter unterschiedliche Plugins und Schritte nötig sind…
In dieser Anleitung wird allerdings auch der Fall berücksichtigt, dass man intern ohne HTTPS auf das Webinterface zugreifen möchte. In diesem Fall bietet es sich an, einen DNS Eintrag anzulegen, der auf die internet IP-Adresse zeigt.
Für dieses Beispiel wird der Hostname pihole.dr3st.de gewählt, dieser muss den persönlichen Vorstellungen nach angepasst werden!Alle Befehle sind mittels Root-Rechten auszuführen. Es empfiehlt sich ein Root-Login oder “sudo -i”!
Zuerst installiert man Nginx und den Certbot, sofern noch nicht passiert:
#Archlinux
pacman -Syu nginx certbot
# Ubuntu
apt-get update
apt-get install -y nginx certbot
Sofern der Pfad der Standardseite von Nginx nicht anders konfiguriert wurde, sollte dieser Befehl das Zertifikat ausstellen lassen.Hierfür ist aber ein externer Zugang zum Nginx nötig.
PI_DOMAIN=pihole.dr3st.de
EMAIL="email@domain.de"
certbot certonly --webroot -w /var/www/html/ --email ${EMAIL} --non-interactive --agree-tos -d ${PI_DOMAIN} --rsa-key-size 4096
Sollte Pihole nur intern laufen, müssen die Konfigurationen unten angepasst werden. Hierfür bitte die Kommentare berücksichtigen!Erst den Befehl ausführen und dann die gewünschten Parameter anpassen.
Außerdem kann der Hostname auch auf die lokale private IP-Adresse zeigen. Beispielsweise könnte pihole.dr3st.de auf 192.168.178.222 zeigen und somit per Hostname im internen Netz erreichbar gemacht werden.
Wichtig:
Die IP-Adresse im proxy_pass Parameter muss mit der Adresse im docker-compose.yml übereinstimmen!Außerdem sollte das Webinterface noch abgesichert werden, hierfür sind allow / deny Beispiele vorbereitet, allerdings auskommentiert. Einfach die Netze freigeben die Zugriff haben dürfen.
cat > /etc/nginx/sites-enabled/${PI_DOMAIN}.conf <<EOF
server {
server_name ${PI_DOMAIN};
listen 0.0.0.0:80;
location ~ .well-known {
root /var/www/html;
}
# HTTPS Umleitung falls HTTPS genutzt wird, wenn nicht, auskommentieren!
location / {
return 301 https://${PI_DOMAIN}$request_uri;
}
# Falls kein HTTPS verwendet wird, diese Sektion aktivieren
#location / {
# include /etc/nginx/proxy_params;
# proxy_pass http://10.11.12.3:80;
# bestimmte Netze erlauben, alle anderen verbieten
# allow 192.168.178.0/24;
# allow 10.10.10.0/24;
# allow 192.168.1.33/32; # /32 bedeutet eine einzelne IP-Adresse
# deny all;
#}
}
# Falls kein HTTPS gewünscht oder möglich, kann diese ganze Sektion auskommentiert werden
server {
server_name ${PI_DOMAIN};
listen 0.0.0.0:443 ssl http2;
access_log /var/log/nginx/${PI_DOMAIN}.access.log;
error_log /var/log/nginx/${PI_DOMAIN}.error.log;
root /var/www/html;
ssl_certificate /etc/letsencrypt/live/${PI_DOMAIN}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${PI_DOMAIN}/privkey.pem;
# bestimmte Netze erlauben, alle anderen verbieten
#allow 192.168.178.0/24;
#allow 10.10.10.0/24;
#deny all;
# Proxy for pihole docker
location / {
proxy_set_header Host \$host;
proxy_set_header X-Forwarded-Proto \$scheme;
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options SAMEORIGIN;
proxy_cookie_path / "/; secure; HttpOnly";
include /etc/nginx/proxy_params;
proxy_pass http://10.11.12.3:80;
}
}
EOF
Um das Webinterface aufzurufen, sollten die Ports 80 und 443 (bei Verwendung von HTTPS) freigeschaltet sein. Da der Certbot bereits oben im Einsatz war und im Standardfall eine HTTP-Anfrage durchgeführt wurde, sollte der Port bereits offen sein.
Außerdem muss der Zugang zu den DNS-Ports ermöglicht werden. Weil Pihole aber in einem isolierten Bereich aktiv ist und auf vielen Servern der Systemd-Resolved schon läuft, muss dieser erst deaktiviert werden, bevor die Ports im System gebunden werden können. Kurz gesagt Systemd-Resolved blockiert Port 53!
Eine Alternative zum Docker-Proxy kann Firewall-NAT sein, allerdings unterbindet hier die iptables-Isolation von Docker eine Konfiguration mittels NFTables. Ich möchte aber nicht unerwähnt lassen, dass wenn man iptables in Docker deaktivieren und Konfiguration mittels NFTables vornehmen kann …
systemctl stop systemd-resolved.service
systemctl disable systemd-resolved.service
Falls noch nicht passiert, wird ein Docker Netzwerk angelegt. Dies wurde in der Nextcloud Anleitung (https://dr3st.de/komplettanleitung-mariadb-nextcloud-mit-nginx-proxy/) genauer erklärt:
docker network create \
--gateway 10.11.12.1 \
--subnet 10.11.12.0/24 \
--opt com.docker.network.bridge.name=br_apps \
br_apps
# Logverzeichnis für Lighttp (Webserver)
mkdir -p /srv/docker/containers/pihole/log/lighttpd/
Diese compose-Datei bindet sich global an Port 53 (TCP und UDP). Möchte man nur bestimmte Netze mit DNS versorgen, kann auch auf bestimmte IP-Adressen gebunden werden (siehe unten) und mittels Firewall-Regeln der Zugriff unterbunden werden.
# Ordner anlegen
mkdir -p /srv/docker/git/pihole
# Variablen nach Wunsch anpassen
DNS_1="1.1.1.1"
DNS_2="8.8.8.8"
PASSWORD="WEB_P4SSW0RD"
# docker-compose.yml erzeugen
cat > /srv/docker/git/pihole/docker-compose.yml <<EOF
version: "3"
# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
pihole:
container_name: pihole
image: pihole/pihole:latest
hostname: "${PI_DOMAIN}"
environment:
TZ: 'Europe/Berlin'
DNS_1: "${DNS_1}"
DNS_2: "${DNS_2}"
WEBPASSWORD: "${PASSWORD}"
SERVERIP: "0.0.0.0"
ServerIP: "0.0.0.0"
volumes:
- '/srv/docker/containers/pihole/etc-pihole/:/etc/pihole/'
- '/srv/docker/containers/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/'
- '/srv/docker/containers/pihole/log:/var/log/'
restart: unless-stopped
ports:
- 53:53/tcp
- 53:53/udp
networks:
default:
ipv4_address: 10.11.12.3
networks:
default:
external:
name: br_apps
EOF
cd /srv/docker/git/pihole
docker-compose pull
docker-compuse up -d
Dies ist nicht zwingend notwendig und dient nur wie bereits erwähnt als Beispiel!
services:
pihole:
...
ports:
- 127.0.0.1:53:53
- 127.0.0.1:53:53/udp
- 10.20.30.7:53:53
- 10.20.30.7:53:53/udp
networks:
...
Nun sollte der Zugriff über die gewünschte Domain funktionieren (je nachdem wie konfiguriert):
Das Passwort kann in der docker-compose.yml angepasst und ausgelesen werden.
Die Auflösung des DNS kann ebenfalls getestet werden, denn der Docker-Proxy leitet die Anfragen in den Container:
# Test via NSLookup
nslookup dr3st.de 127.0.0.1
Server: 127.0.0.1
Address: 127.0.0.1#53
Non-authoritative answer:
Name: dr3st.de
Address: 85.10.199.104
# Test via dig
root@docker-etst:/srv/docker/git/pihole# dig www.dr3st.de @127.0.0.1
; <<>> DiG 9.16.1-Ubuntu <<>> www.dr3st.de @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11441
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.dr3st.de. IN A
;; ANSWER SECTION:
www.dr3st.de. 3600 IN CNAME dr3st.de.
dr3st.de. 3600 IN A 85.10.199.104
Pihole-Projekt