Self-Hosting trotz CG-NAT für Dummies

Das Skript sieht bei mir wie folgt aus (zum Testen wollte ich Port 30013 von meinem NAS erreichen):

Skript

#!/bin/bash

echo „###################“
echo „Erlaube IPv4 Forwards“
echo „###################“
sed -i ‚s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/‘ /etc/sysctl.conf && sysctl -p

echo „###################“
echo „IPTables bereinigen“
echo „###################“
iptables -t nat -F
iptables -F

echo „###################“
echo „Erstelle IPTables INPUT Regeln“
echo „###################“
iptables -A INPUT -i ens6 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i ens6 -p udp --dport 51820 -j ACCEPT
iptables -A INPUT -i ens6 -p tcp --dport 30013 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -P INPUT DROP

echo „###################“
echo „Erstelle IPTables NAT Regeln“
echo „###################“
iptables -t nat -A PREROUTING -i ens6 -p tcp -m multiport --dport 30013 -j DNAT --to-destination 172.31.0.1
iptables -t nat -A POSTROUTING -o wg0 -p tcp -m multiport --dport 30013 -d 172.31.0.1 -j SNAT --to-source 192.168.178.29

echo „###################“
echo „Erstelle Forward Regeln“
echo „###################“
iptables -P FORWARD DROP
iptables -A FORWARD -i ens6 -o wg0 -p tcp -m multiport --dport 30013 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

192.168.178.29 = NAS
172.31.0.1 = VPS (Wireguard)

Der Fehler liegt doch mit hoher Wahrscheinlichkeit an meinen Änderungen beim PRE- und POSTROUTING, oder?

Das Skript kann ich mir demnächst mal anschauen. Bei tcpdump solltest du das Interface mitgeben auf dem du lauschen willst.

tcpdump -i wg0 port 1234
tcpdump -i eth0 port 1234

EDIT: Ich kann einen kleinen Erfolg melden! Zum Testen habe ich mal das olle Chat-GPT angeschmissen und nach Skript-Änderungen gefragt, und siehe da, es klappt! Ich werde jetzt noch etwas am Skript feilen und meinen Lösungsweg dann posten!

Ah, okay. Den zusätzlichen Wert des Interface werde ich mal mit einbauen beim tcpdump. Ich werd’s morgen mal testen.

Und danke dir nochmal, dass du mir hier versuchst zu helfen! Tut mir leid, dass sich das hier so in die Länge zu ziehen scheint :sweat_smile:

1 „Gefällt mir“

Jetzt klappt alles! Um mein NAS nun von außerhalb erreichbar zu machen, habe ich folgendes gemacht:

Schritt 1:
Es musste ein Wireguard-Tunnel zwischen VPS und meiner Fritzbox erstellt werden, dafür habe ich folgende Konfigurationen erstellt:

Fritzbox: fritz_wg0.conf
[Interface]
PrivateKey = <Zufällig generierter Key>
ListenPort = 51820
Address = 192.168.178.1/24
DNS = 192.168.178.1
DNS = fritz.box

[Peer]
PublicKey = <Zufällig generierter Key>
PresharedKey = <Zufällig generierter Key (muss identisch mit vps_wg0.conf sein)>
AllowedIPs = 172.31.0.0/24
Endpoint = <öffentliche IP(v4 oder v6) des VPS>:51820
PersistentKeepalive = 25
VPS: vps_wg0.conf
[Interface]
PrivateKey = <Zufällig generierter Key>
Address = 172.31.0.1/24
ListenPort = 51820

[Peer]
PublicKey = <Zufällig generierter Key>
PresharedKey = <Zufällig generierter Key (muss identisch mit fritz_wg0.conf sein)>
AllowedIPs = 192.168.178.0/24, 172.31.0.0/24
PersistentKeepalive = 25

Beim Einrichten des Tunnels hat mir dieses Tutorial als kleine Orientierung geholfen: https://www.youtube.com/watch?v=StTTfP9aB6Q


Schritt 2:
Skript auf dem VPS erstellen, um Anfragen, die auf der öffentlichen IP des VPS eingehen, durch den VPN-Tunnel ins Heimnetzwerk zum gewünschten Zielgerät zu leiten.

Skript
#!/bin/bash

# Variablen
NAS_IP="192.168.178.63"
VPS_WIREGUARD_IP="172.31.0.1"
INTERFACE="ens6"
WIREGUARD_INTERFACE="wg0"
TCP_PORTS="5555 6666 4444"
UDP_PORTS="3333 8888 7777"

# Erlaube IPv4 Forwards
sed -i 's/#net\.ipv4\.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf && sysctl -p

# IPTables bereinigen
iptables -t nat -F
iptables -F

# Erstelle IPTables INPUT Regeln
iptables -A INPUT -i $INTERFACE -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i $INTERFACE -p udp --dport 51820 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
iptables -P INPUT DROP

# Erstelle IPTables NAT Regeln für TCP und UDP
for PORT in $TCP_PORTS $UDP_PORTS; do
    PROTOCOL="tcp"
    if [[ $UDP_PORTS =~ (^| )$PORT($| ) ]]; then
        PROTOCOL="udp"
    fi
    iptables -t nat -A PREROUTING -i $INTERFACE -p $PROTOCOL --dport $PORT -j DNAT --to-destination $NAS_IP:$PORT
    iptables -t nat -A POSTROUTING -o $WIREGUARD_INTERFACE -d $NAS_IP -p $PROTOCOL --dport $PORT -j SNAT --to-source $V>
done

# Erstelle Forward Regeln für TCP und UDP
iptables -P FORWARD DROP
for PORT in $TCP_PORTS $UDP_PORTS; do
    iptables -A FORWARD -i $INTERFACE -o $WIREGUARD_INTERFACE -p tcp --dport $PORT -j ACCEPT
    iptables -A FORWARD -i $INTERFACE -o $WIREGUARD_INTERFACE -p udp --dport $PORT -j ACCEPT
done

# Bereits laufende Verbindungen werden nicht von Firewall blockiert
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Zu beachten war hierbei noch (für mich), dass über die Web-GUI des Anbieters die Ports aus dem Skript in der Firewall geöffnet werden.

Und auch hier hat mir wieder ein Tutorial-Vorschlag aus dem Thread als Anhaltspunkt weitergeholfen: https://www.youtube.com/watch?v=ZDWhFmMLSMM

1 „Gefällt mir“

Danke für die ausführliche Erklärung und deiner benutzten / erstellen Skripte!