On setup with WAN and VPN cannot access local machines in DMZ

I have set up three firewall zones. One routes traffic via VPN and two others route traffic unencrypted via WAN. All of this works fine (after some struggle).

I have a server in front of the router that I cannot access from the VPN network. I can access them when connected to the WAN networks.

I've tried setting up static routing rules, firewall rules, and policy routing. But so far nothing works.

Physical setup:

wrtrouter   <--|
               |--> layer 2 switch <------> internet
dmz-server  <--|

Network setup and firewall zones:

The LAN, GUEST and APL networks are isolated from each other using a VLAN config, and firewall configuration.

The routing is controlled via the VPN policy routing plugin.

The dmz-server is outside the wrtrouter - that it is in front of the WAN interface. I can connect to it from networks inside the wrtrouter when connected to GUEST and APL networks. But I cannot connect to it when I'm on the LAN network.

dmz-server is visible on the public internet. I can connect to from any unrelated outside network. So somehow instead of routing to this public server via the VPN tunnel, it is trying to route internally and getting blocked.

I would rather connect locally anyway than have to access a local server via higher latency VPN routing. The ideal solution would be to route correctly locally. But I can't figure out why it is getting blocked.

What am I doing wrong? Or even how can I diagnose this?

The relevant parts of the configs follow:

/etc/config/network:

config globals 'globals'
	option ula_prefix 'aaaa:1111:2222::/48'

config switch
	option name 'switch0'
	option reset '1'
	option enable_vlan '1'

config switch_vlan
	option device 'switch0'
	option vlan '1'
	option ports '2 5t'

config switch_vlan
	option device 'switch0'
	option vlan '2'
	option ports '4 6t'

config switch_vlan
	option device 'switch0'
	option vlan '3'
	option ports '0 5t'

config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config interface 'wan'
	option proto 'static'
	option ipaddr '33.44.55.60'
	option netmask '255.255.255.0'
	option gateway '33.44.55.1'
	option broadcast '255.255.255.255'
	option ifname 'eth1.2'

config interface 'wan6'
	option proto 'dhcpv6'
	option ifname 'eth1.2'

config interface 'vpn'
	option proto 'none'
	option auto '1'
	option ifname 'tun0'

config interface 'lan'
	option type 'bridge'
	option proto 'static'
	option ipaddr '192.168.1.1'
	option netmask '255.255.0.0'
	option dns '10.8.8.1'
	option ifname 'eth0.1'
	option ip6assign '60'

config interface 'guest'
	option proto 'static'
	option ipaddr '192.168.2.1'
	option netmask '255.255.255.0'
	option dns '8.8.8.8 8.8.4.4'

config interface 'apl'
	option type 'bridge'
	option proto 'static'
	option ipaddr '192.168.3.1'
	option dns '8.8.8.8 8.8.4.4'
	option netmask '255.255.255.0'
	option ifname 'eth0.3'
	option ip6assign '60'



/etc/config/firewall:

config defaults
	option syn_flood '1'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'

config zone
	option name 'wan'
	option network 'wan wan6'
	option output 'ACCEPT'
	option input 'DROP'
	option masq '1'
	option mtu_fix '1'
	option forward 'DROP'

config zone
	option name 'vpn'
	option network 'vpn'
	option output 'ACCEPT'
	option input 'DROP'
	option forward 'DROP'
	option mtu_fix '1'
	option masq '1'

config zone
	option name 'lan'
	option network 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'

config zone
	option name 'apl'
	option network 'apl'
	option output 'ACCEPT'
	option input 'REJECT'
	option forward 'ACCEPT'

config zone
	option name 'guest'
	option network 'guest'
	option output 'ACCEPT'
	option input 'REJECT'
	option forward 'ACCEPT'

config forwarding
	option src 'lan'
	option dest 'vpn'

config forwarding
	option src 'apl'
	option dest 'wan'

config forwarding
	option src 'guest'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option src_ip 'fc00::/6'
	option dest_ip 'fc00::/6'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config include
	option path '/etc/firewall.user'

config rule
	option name 'Guest DNS'
	option src 'guest'
	option proto 'tcp udp'
	option dest_port '53'
	option target 'ACCEPT'

config rule
	option name 'Guest DHCP'
	option src 'guest'
	option proto 'tcp udp'
	option dest_port '67-68'
	option target 'ACCEPT'

config rule
	option name 'Appliance DNS'
	option src 'apl'
	option proto 'tcp udp'
	option dest_port '53'
	option target 'ACCEPT'

config rule
	option name 'Appliance DHCP'
	option src 'apl'
	option proto 'tcp udp'
	option dest_port '67-68'
	option target 'ACCEPT'

config redirect
	option name 'odroid'
	option src 'wan'
	option dest 'lan'
	option target 'DNAT'
	option proto 'tcp udp'
	option src_dport '2260'
	option dest_ip '192.168.1.60'
	option dest_port '22'

config redirect
	option name 'apt'
	option src 'wan'
	option dest 'lan'
	option target 'DNAT'
	option proto 'tcp udp'
	option src_dport '2261'
	option dest_ip '192.168.1.61'
	option dest_port '22'

config redirect
	option name 'code'
	option src 'wan'
	option dest 'lan'
	option target 'DNAT'
	option proto 'tcp udp'
	option src_dport '2262'
	option dest_ip '192.168.1.62'
	option dest_port '22'

config redirect
	option name 'svn'
	option src 'wan'
	option dest 'lan'
	option target 'DNAT'
	option proto 'tcp'
	option dest_ip '192.168.1.62'
	option src_dport '3690'
	option dest_port '3690'

/etc/config/dhcp:

config dnsmasq
	option domainneeded '1'
	option localise_queries '1'
	option rebind_protection '1'
	option rebind_localhost '1'
	option local '/lan/'
	option expandhosts '1'
	option authoritative '1'
	option readethers '1'
	option leasefile '/tmp/dhcp.leases'
	option resolvfile '/tmp/resolv.conf.auto'
	option nonwildcard '1'
	option localservice '1'
	option domain 'oroboro.com'
        option boguspriv '1'
        option filterwin2k '0'  # enable for dial on demand
        option nonegcache '0'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '4'

config dhcp 'wan'
	option interface 'wan'
	option ignore '1'

config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option dhcpv6 'server'
	option ra 'server'
	option ra_management '1'
	option netmask '255.255.255.0'

config dhcp 'guest'
	option interface 'guest'
	option start '100'
	option limit '150'
	option dhcpv6 'server'
	option ra 'server'
	option ra_management '1'
	option leasetime '12h'

config dhcp 'apl'
	option interface 'apl'
	option start '100'
	option limit '150'
	option dhcpv6 'server'
	option ra 'server'
	option ra_management '1'
	option leasetime '12h'

/etc/config/vpn-policy-routing:


config vpn-policy-routing 'config'
	option verbosity '2'
	option ipv6_enabled '0'
	option ipset_enabled '1'
	option dnsmasq_enabled '0'
	option strict_enforcement '1'
	option boot_timeout '30'
	option enabled '1'

config policy
	option name 'guest'
	option interface 'wan'
	option chain 'PREROUTING'
	option local_address '192.168.2.0/24'
	option proto 'tcp udp'

config policy
	option name 'apl'
	option interface 'wan'
	option chain 'PREROUTING'
	option local_address '192.168.3.0/24'
	option proto 'tcp udp'

Firewall zones don't route traffic.

You say that your server is outside the routers WAN interface, yet you have no firewall rule to permit access LAN > WAN.

Break it down into small pieces... test each piece at a time... While I get that you've focussed on the policy routing... you have to be able to "see" and test your network without it...

Especially when you want to do fancy things.

Yes, that did it. I added WAN as one of the forwards from LAN and it works now.

But does this mean all traffic is forwarded to both the WAN and VPN interfaces? When I check for VPN security on ipleak.net I see that I'm still on VPN when accessing the internet. But are my network packets also being redundantly echoed out of my WAN interface? Should I add routing rules to insist that some traffic is routed only via VPN and other traffic via WAN only?

I'm aware. I was loose with terms to save typing. I suppose I could have said:

"I have three networks and two external interfaces with matching firewall zones. The networks are configured to route traffic..."

No, it describes what traffic is permitted to pass, but not where that traffic goes.

Firewall: what traffic is allowed, and what traffic is denied
Routing: where to send the traffic

Those forwarding options may be considered defaults for all traffic, in the absence of specific rules. If you have forwarding enabled from LAN to WAN, then all traffic originating in LAN and destined for WAN will pass. If you don't have forwarding enabled from LAN to WAN then you will need to create specific firewall traffic rules to allow traffic to pass. It's a trade-off between security and convenience.

You can disable LAN->WAN forwarding if you wish, but you would then need to create a rule permitting traffic from LAN to your target server.

A while back I ran an OpenWRT box which deliberately had forwarding disabled for all zones. I configured a few explicit rules for specific traffic I wanted to permit; everything else got dropped, no matter where it originated or where it was destined.

Don't. Precision and verbosity are important. If you're "loose", or vague with your descriptions, it's reasonable for everyone else to assume that you're equally "loose" with your configuration. Network equipment doesn't guess, or work on a "do what I mean" basis; it only knows exactly what you've told it to do. As a result, anyone trying to help needs to see your exact configuration rather than a "loose" description of what you think it should be.