IPv4 trotz DS-Lite – so geht’s mit WireGuard & Nginx Proxy Manager

Viele Provider geben nur noch IPv6 mit DS-Lite raus eine echte Katastrophe, wenn man von außen auf seine Dienste zugreifen möchte.
In diesem Tutorial zeige ich euch, wie ihr euch trotzdem eine funktionierende IPv4-Verbindung aufbaut mit WireGuard und Nginx Proxy Manager.


Quellen:

Nginx Proxy Manager
Docker container and built in Web Application for managing Nginx proxy hosts with a simple, powerful interface, providing free SSL support via Let’s Encrypt

Was wird alles benötigt?

  • Ubuntu 22.04
  • Zwei Server einen bei euch (z.B. als VM) und einen VPS Server (z.B. Hetzner, Ionos, Strato etc.)
  • SSH Zugriff zu beiden Servern

WireGuard Tunnel einrichten 🔐

Zuerst richten wir einen Tunnel zwischen zwei Standorten ein.

💡
Als Info zum Merken:
Server 1 = Heimserver (steht bei euch Zuhause)
Server 2 = externer Server bei einem Anbieter (z. B. Hetzner, Ionos, Strato …)

Als erstes: (Auf beiden Servern ausführen!)

apt update && apt upgrade

WireGuard installieren

apt install wireguard -y

IP Forwarding aktivieren

nano /etc/sysctl.conf

Kommentar entfernen bei:

net.ipv4.ip_forward=1

Änderungen übernehmen:

sysctl -p

Schlüssel erzeugen

cd /etc/wireguard
umask 077; wg genkey | tee privatekey | wg pubkey > publickey

Konfiguration: Server 2 (Anbieter)

🔥
Firewall:
Denkt daran, die folgenden Ports auf Server 2 (Anbieter-Server) zu öffnen:
443 -> für Nginx Proxy Manager (HTTPS)
80 -> für Nginx Proxy Manager (HTTP)
81 -> nur vorübergehend für das NPM-Webinterface
51820 -> für die WireGuard-VPN-Verbindung
[Interface] 
PrivateKey = <site-1 private-key>
Address = 10.0.0.1/24
SaveConfig = true 
PostUp   = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820

[Peer]
PublicKey = <site-2 public-key>
AllowedIPs = 10.0.0.0/24, 192.168.178.0/24
PersistentKeepalive = 25

Hinweise zur Konfiguration 🔑

  • PrivateKey = <site-1 private-key> -> hier kommt der Private Key von Server 1 (Heimserver) rein
  • PublicKey = <site-2 public-key> -> hier tragt ihr den Public Key von Server 2 (Anbieter-Server) ein
  • AllowedIPs = -> hier könnt ihr eure interne Heimnetz-IP eintragen, z. B. 192.168.X.0, damit der Anbieter-Server Zugriff auf euer Heimnetz bekommt

Konfiguration: Server 1 (Heimserver)

[Interface] 
PrivateKey = <site-2 private-key>
Address = 10.0.0.3/24
SaveConfig = true 
PostUp   = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer] 
PublicKey = <site-1 public-key>
Endpoint = <FQDN>:51820 
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25

Hinweise zur Konfiguration 🔑

  • PrivateKey = <site-2 private-key> -> hier kommt der Private Key von Server 2 (Anbieter-Server) rein
  • PublicKey = <site-1 public-key> -> hier tragt ihr den Public Key von Server 1 (Heimserver) ein
  • Endpoint = <FQDN>:51820 -> hier müsst ihr die öffentliche IP-Adresse oder Domain von Server 2 (Anbieter) eintragen

Verbindung starten (auf beiden Servern)

wg-quick up wg0
wg show

Nginx Proxy Manager einrichten 🌐

Damit wir sauber weiterleiten können, nehmen wir den Nginx Proxy Manager.

💡
Hinweis:
Den Nginx Proxy Manager (NPM) installiert ihr auf Server 2, also dem Server bei eurem Anbieter!

Docker installieren

apt install docker.io && apt install docker-compose -y

Projektverzeichnis anlegen

mkdir npm
cd npm

config.json erstellen

nano config.json
{
  "database": {
    "engine": "mysql",
    "host": "db",
    "name": "npm",
    "user": "npm",
    "password": "npm",
    "port": 3306
  }
}

docker-compose.yml

nano docker-compose.yml
version: "3"
services:
  app:
    image: jc21/nginx-proxy-manager:latest
    restart: always
    ports:
      - 80:80
      - 81:81
      - 443:443
    volumes:
      - ./config.json:/app/config/production.json
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - db
    environment:
      - FORCE_COLOR=1
  db:
    image: mariadb:latest
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "npm"
      MYSQL_DATABASE: "npm"
      MYSQL_USER: "npm"
      MYSQL_PASSWORD: "npm"
    volumes:
      - ./data/mysql:/var/lib/mysql

Container starten

docker-compose up -d

Zugriff auf NPM:

  • Web: http://hostip:81
  • Default-Login:User: admin@example.comPasswort: changeme

iptables Forwarding 🔀

Damit der Zugriff sauber klappt, müssen wir noch Ports weiterleiten:

💡
Wichtig:
Die iptables Forwarding-Regeln setzt ihr auf Server 1 (Heimserver).
iptables -t nat -A PREROUTING -p tcp --dport 81 -j DNAT --to-destination 10.0.0.1:81
iptables -t nat -A POSTROUTING -j MASQUERADE

👉 Ihr könnt danach mit 10.0.0.1:81 auf euren Server zugreifen.

Den Port 81 in der Firewall bei eurem Anbieter könnt ihr danach wieder schließen.


Bonus: Regeln dauerhaft machen 💡

Standardmäßig sind iptables-Regeln nach einem Neustart weg.
Wenn ihr die Regeln permanent haben wollt, könnt ihr iptables-persistent nutzen:

apt install iptables-persistent -y
netfilter-persistent save

👉 Damit werden eure aktuellen iptables-Regeln automatisch beim Booten geladen.


WireGuard beim Boot starten ⚡

Auf beiden Servern Ausführen:

systemctl enable wg-quick@wg0

Fertig 🎉

Damit habt ihr jetzt trotz DS-Lite eine funktionierende IPv4-Erreichbarkeit über den WireGuard-Tunnel und könnt eure Dienste mit dem Nginx Proxy Manager sauber erreichbar machen.

💡 Tipp: Denkt daran, eure Firewall-Regeln regelmäßig zu checken und Updates einzuspielen – Sicherheit first!