Cannot reach internal servers (in br-lan) from network guest

I am not sure how to describe it... I struggle with one behaviour.
I already tried a lot but now I have no clue anymore.

I have a couple of servers running (nas, voice, ...). The overview is:
DNS -> OpenWrt (port forwarding) -> Nginx (lan) -> Servers (lan/guest)

Clients in "lan" can reach everything.
But Clients in "guest" cannot reach the servers. Doesnt matter whether the server is in "lan" or "guest"

Of course "guest" should not reach "lan" directly. But it should go over the internet, so it should not matter (I thought about DNS rebind protection but disableing didnt help).
Also firewall zone forwarding guest==>lan didnt help.
Just for testing I put "guest" and "lan" in the same firewall zone. Then it worked.

I created for both static routes:

cat /etc/config/network

config route
	option target '192.168.12.0/24'
	option netmask '255.255.255.0'
	option interface 'lan'

config route
	option target '192.168.3.0/24'
	option interface 'guest'
	option netmask '255.255.255.0'

My question is, what is my mistake?
Is OpwnWrt so clever to route traffics internally if it know the dns points to itself (and then guest cannot reach lan direclty)?

Yes, you should try it from "real" outside (cell phone connection sharing/hotspot. or something), and it's a general *nix behavior, not Openwrt.

How can I avoid it?

My guest network should be able to reach my internal servers in lan network over the internet.

Rebind your domain using its private IP address, or create additional redirect from guest to LAN.

"Rebind your domain using its private IP address"
How?

make sure the DNS name you use return a different (local) IP while on the LAN, vs when resolving it on internet.

1 Like

How should it be possible?

Under "DHCP and DNS"
I tried with "DNS forwardings":
/mydns.dns.net/192.168.12.77

I also tried with "Domain whitelist" under rebind protection:
mydns.dns.net

I allowed in firewall that guest can reach lan (192.168.12.77).
Now it can reach it if I use the internal IP but not over dns mydns.dns.net...

But to be honest, for me it would be fine, if it just goes over the internet. Outside of my network it is reachable...

Isnt it possible to do it via "NAT Rules"? I already tried but no success yet :smiley:

Make sure you actually use your own DNS.

1 Like

mydns.dns.net is just a placeholder. The real one points to my public IP (nslookup).

Just a short status.

I guess the topic is "nat loopback" related.

So it seems there is a bug with nat loopback with different VLANs/Zones...

I try to implement their workaround.

Okay, the workaround works. Since I spend more than 1 day to figure it out, I would like to share the solution here (of course I just collected it from different sources). Hopefully it helps someone.

Actually the title should be "zone-to-zone nat loopback"
It seems pretty common if someone hosts something on own servers (e.g. webserver) at home.

Nat loopback ~= if a server (reachable on the internet) runs in own private network, then the traffic is not routed though the internet but only internally.

Everything starts with "port forwarding".
→ Network → Firewall → Port Forwards → ... → Advanced settings → check: Enable NAT Loopback + Loopback source IP: use internel IP address (both are defaults)
via ssh it would be:

cat /etc/config/firewall
config redirect                                 
        option dest 'lan' #"option dest" is required for "reflection"
        option reflection '1'    
        option reflection_src 'internal'

but those entries are not visable because they are default. Official doc can be found here: https://openwrt.org/docs/guide-user/firewall/firewall_configuration#redirects

This nat loopback (reflection) creates automatically the correct redirect iptables rules for all zones where the actual server (e.g. webserver) is located (in my case lan).
But guest is not part of the zones that's why no redirect iptables rules are created for.
Examples for the automated redirect iptables rules can be found here:

iptables-save -c | grep reflection

[39:2849] -A zone_lan_postrouting -s 192.168.12.0/24 -d 192.168.12.77/32 -p tcp -m tcp --dport 443 -m comment --comment "!fw3: https (reflection)" -j SNAT --to-source 192.168.12.1
[39:2849] -A zone_lan_prerouting -s 192.168.12.0/24 -d xx.xx.xx.xx/32 -p tcp -m tcp --dport 443 -m comment --comment "!fw3: https (reflection)" -j DNAT --to-destination 192.168.12.77:443

So we have to implement similar rules for the zone guest manually (based on https://bugs.openwrt.org/index.php?do=details&task_id=1645&dev=4):
→ Network → Firewall → Custom Rules
alternatively: vi /etc/firewall.user

. /lib/functions.sh
. /lib/functions/network.sh

network_get_subnet guest guest
network_get_ipaddr wan wan
network_get_ipaddr lan lan

webserverip=192.168.12.77
webserverport=443
iptables -t nat -A postrouting_guest_rule -s $guest -d $webserverip/32 -p tcp -m tcp --dport $webserverport -j SNAT --to-source $lan -m comment --comment "firewall.user: webserver https guest to lan rule (reflection)"
iptables -t nat -A prerouting_guest_rule -s $guest -d $wan -p tcp -m tcp --dport $webserverport -j DNAT --to-destination $webserverip:$webserverport -m comment --comment "firewall.user: webserver https guest to lan rule (reflection)"

btw: wan ip is dynamic. so even after getting a new ip it is correct.
btw: "postrouting_guest_rule" ==> "guest" matters!!!
→ Save

restart firewall (reload is not enough yet!)

/etc/init.d/firewall restart
#be sure there are no errors

in order to make it safe for OpenWrt reboots:
based on: https://dev.archive.openwrt.org/ticket/20249.html

vi /etc/config/firewall
config include
	option path '/etc/firewall.user'
	option reload '1'

/etc/init.d/firewall reload

now reload is enough and a restart is not needed anymore.

The results can be checked via:

iptables-save -c | grep reflection | grep firewall.user

[0:0] -A postrouting_guest_rule -s 192.168.3.0/24 -d 192.168.12.77/32 -p tcp -m tcp --dport 443 -m comment --comment "firewall.user: webserver https guest to lan rule (reflection)" -j SNAT --to-source 192.168.12.1
[17:1020] -A prerouting_guest_rule -s 192.168.3.0/24 -d xx.xx.xx.xx/32 -p tcp -m tcp --dport 443 -m comment --comment "firewall.user: webserver https guest to lan rule (reflection)" -j DNAT --to-destination 192.168.12.77:443

PS: officially its not a bug but more a new feature request in order to support it without the manual workaround.

For everyone who is interested in the feature, feel free to leave a comment/vote: https://bugs.openwrt.org/index.php?do=details&task_id=3875

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.