blog.bartlweb - a technologist's external brain

NAT Reflection in einer Double-NAT Konfiguration mit OpenWrt

Wenn das vom Internetservice-Provider bereitgestellte Modem keinen Bridge-Modus unterstützt, lässt sich ein eigener Router nur im DMZ betreiben. Dabei erfolgt allerdings bereits ein NAT und der dahinterliegende Router bekommt keine öffentliche IP-Adresse mehr zugewiesen. Damit NAT Reflection im internen Netzwerk funktioniert, d.h. die externe IP-Adresse des eigenen WAN-Anschlusses auch aus dem eigenen Netzwerk erreichbar ist, muss der interne Router die öffentliche IP kennen, um entsprechende Port-Forwarding-Regeln anlegen zu können.

Lösung 1

OpenWrt erstellt zu allen angelegten Portforwarding-Regeln für jedes WAN-Interface automatisch die notwendigen Firewall-Regeln für NAT Reflection. Eine Lösung NAT Reflection für die öffentliche IP-Adresse bei einer doppelten NAT-Konfiguration zu ermöglichen ist daher am zweiten Router ein virtuelles Interface anzulegen, dem die öffentliche IP-Adresse zugewiesen wird.

Um dem Interface die öffentliche IP-Adresse zuzuweisen, hilft ein kleines Script, dass regelmäßig per Cronjob ausgeführt wird.

*/5 * * * * /etc/update_dynip_interfaces.sh > /dev/null

Das Skript fragt über das öffentliche Interface (kann bei MultiWan-Konfigurationen auch explizit angegeben werden) bei einem externen Service die IP-Adresse ab und weißt diese dem virtuellen Interface zu.

WANIP=`curl -s https://tools.bartlweb.net/myip/ip.txt --interface eth0.2`
 
uci set network.wan2_publicip.ipaddr=$WANIP
uci commit network
 
/etc/init.d/network reload

Damit curl unter OpenWrt genutzt werden kann und die HTTPS-Zertifikate akzeptiert werden, installieren Sie die folgenden beiden Pakete nach:

opkg install curl
opkg install ca-certificates

Lösung 2

NAT Reflection wird durch die entsprechenden Firewall-Regeln ermöglicht. Diese lauten z.B. für ein Port-Forwarding auf den internen Server 192.168.0.1 und Port 80 für die öffentliche IP-Adresse 1.2.3.4 wie folgt:

iptables -t nat -A zone_lan_prerouting -s 192.168.0.0/24 -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to 192.168.0.1:80
iptables -t nat -A zone_lan_postrouting -s 192.168.0.0/24 -d 192.168.0.1 -p tcp --dport 80 -j SNAT --to-source 192.168.0.1:80
iptables -t filter -A zone_lan_forward -s 192.168.0.0/24 -d 1.2.3.4 -p tcp --dport 80 -j ACCEPT

Um bereits in der Konfiguration von OpenWrt bestehende Regeln noch einmal für eine weitere externe IP-Adresse zu erstellen, liest das folgende Skript die bestehenden Regeln ein und erstellt diese für die abgefragte externe IP-Adresse erneut.

# ############################
# wait after boot until everything is loaded
# ############################
 
sleep 60
 
# ############################
# flush and relaod firewall - dont know why, but necessary for the rules to work
# ############################

fw3 flush
fw3 reload
 
# ############################
# nat reflection for own public ip
# needed if modem does not support bridge mode and dmz is used
# ############################
 
LAN=192.168.0.0/24
WAN=`curl -s https://tools.bartlweb.net/myip/ip.txt`
 
set_natReflection(){
    local config="$1"
    local lanip="$2"
    local wanip="$3"
 
    local proto
    config_get proto "$config" proto
    local src_dport
    config_get src_dport "$config" src_dport
    local dest_port
    config_get dest_port "$config" dest_port
    local dest_ip
    config_get dest_ip "$config" dest_ip
    
    if ! `iptables -t nat -C zone_lan_prerouting -s $lanip -d $wanip -p $proto --dport $src_dport -j DNAT --to $dest_ip:$dest_port`; then
        iptables -t nat -A zone_lan_prerouting -s $lanip -d $wanip -p $proto --dport $src_dport -j DNAT --to $dest_ip:$dest_port
    fi
    
    if ! `iptables -t nat -C zone_lan_postrouting -s $lanip -d $dest_ip -p $proto --dport $src_dport -j SNAT --to-source $dest_ip:$dest_port`; then
        iptables -t nat -A zone_lan_postrouting -s $lanip -d $dest_ip -p $proto --dport $src_dport -j SNAT --to-source $dest_ip:$dest_port
    fi
    
    if `! iptables -t filter -C zone_lan_forward -s $lanip -d $wanip -p $proto --dport $src_dport -j ACCEPT`;    then
        iptables -t filter -A zone_lan_forward -s $lanip -d $wanip -p $proto --dport $src_dport -j ACCEPT
    fi
}
 
. /lib/functions.sh
config_load firewall
config_foreach set_natReflection redirect $LAN $WAN

Dieser Artikel hat Dir deinen Tag gerettet?

... und mühevolles Probieren, Recherchieren und damit Stunden an Zeit gespart? Oder einfach nur Dein Problem gelöst?

Dann würde ich mich freuen, wenn Du meine Zeit für die Erstellung dieses Blogartikels mit einer kleinen Anerkennung honorierst:

Zahlung mit PayPal oder Kreditkarte.

Hinweis zur Verwendung

Die Übermittlung einer Zahlung ist eine persönliche Anerkennung Ihrerseits an den Entwickler (Christian Bartl, Privatperson). Eine Zahlung ist nicht zweckgebunden und es ist keine Gegenleistung zu erwarten. Bitte beachten Sie, dass für eine übermittelte Zahlung keine Quittung ausgestellt werden kann.

Über den Autor

Christian Bartl

Christian Bartl Requirements Engineer
& Solution Architect für Online und Mobile

Als Technologie-Enthusiast und begeisterter Programmierer entwickle ich in meiner Freizeit Websites, Software und IT-Lösungen, die mir selbst und anderen den Alltag vereinfachen.

mehr auf christian.bartl.me

Kommentare

Noch kein Kommentar vorhanden.
Sei der Erste! - Ich freue mich über deine Anmerkung, Kritik oder Frage.

Kommentar schreiben

Der hier angegebene Name wird gemeinsam mit deinem Kommentar auf der Website veröffentlicht.

Deine E-Mail-Adresse wird zur einmaligen Benachrichtigung bei Veröffentlichung des Kommentars genutzt.

Benachrichtigung per E-Mail über Antworten auf meinen Kommentar erhalten.

Bitte tippe die Zahlenkombination "9350" ein, nur dann kann ich deinen Kommentar entgegennehmen.

Bitte fülle dieses Feld nicht aus, nur dann kann ich deinen Kommentar entgegennehmen.