Subsections of z_Archiv

Host-Wireguard mit NordVPN Container

Hinweis

Die Anleitung kann veraltet sein und kann als Inspiration genutzt werden!

Wireguard Clients durch Nordvpn tunneln

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.

Wireguard einrichten

Im Archlinux-Wiki ist eine ausführliche Anleitung zu finden (https://wiki.archlinux.org/title/WireGuard), deshalb hier eine kurze Zusammenfassung:

Keypairs des Servers erstellen

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
Wireguard Tunnel einrichten

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

Nordvpn konfigurieren

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.

Docker-Container Konfiguration

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
Systemd-Networkd Netzwerkkonfiguration

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

Wireguard auf Client

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 ;)


Multiboot USB Stick

Hinweis

Die Anleitung kann veraltet sein und kann als Inspiration genutzt werden!

Multiboot USB Stick bauen

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:

  • Partitionstabelle erstellen und Flags setzen
  • Partitionen formatieren
  • Images herunterladen und auf den Stick kopieren
  • Grub (Bootloader) konfigurieren

Folgende Betriebssysteme sind angedacht:

  • Ubuntu 22.04 Desktop
  • Archlinux
  • Windows 10

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.

Warnung

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.

Warnung

Die meisten Befehle benötigen Root-Rechte, deswegen wurde das oft vorangestellte “sudo” weg gelassen…

USB-Stick ermitteln

# 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

Partitionierung

# -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

Formatierung

# 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

Dateisysteme mounten

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

Images laden & kopieren

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

Grub installieren

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/
Grub-Config schreiben

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 ->" {

Dateisysteme umounten

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


Pihole Installation mit Nginx Proxy

Hinweis

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”!

Nginx

Installation

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
Zertifikat anfragen

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
Konfiguration anlegen

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

Firewall und DNS Zugriff

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 …

Systemd-Resolved ausschalten und deaktivieren
systemctl stop systemd-resolved.service
systemctl disable systemd-resolved.service

Docker

Netzwerk anlegen

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
Orderstruktur anlegen
# Logverzeichnis für Lighttp (Webserver)
mkdir -p /srv/docker/containers/pihole/log/lighttpd/
Docker-Compose

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
Port-Binding anpassen

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:
    ...

Tests

Nun sollte der Zugriff über die gewünschte Domain funktionieren (je nachdem wie konfiguriert):

  • https://$PI_DOMAIN/admin
  • http://$PI_DOMAIN/admin

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