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