Access a public website from VLAN to LAN

Hi everyone, I recently setup a Raspberry Pi 4B with OpenWrt as my main router.

I have a LAN configured with 192.168.1.0/24 and a VLAN (for IOT devices) with ip range 10.10.10.0/24. On LAN I have a server that servers a website that is publicly accessible (via forwarding 80/443 ports to nginx running on the server). The website is accessible from the internet and LAN but when I try and connect to it from the IOT VLAN I get ERR_CONNECTION_RESET.

Here are some details:

  • Curl to the website from the IOT VLAN:
curl -v https://{MY_WEBSITE_DOMAIN}/
*   Trying {MY_PUBLIC_IP}:443...
* getpeername() failed with errno 22: Invalid argument
* Connected to lebaguette.eu () port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* Send failure: Broken pipe
* LibreSSL/3.3.6: error:02FFF020:system library:func(4095):Broken pipe
* Closing connection 0
* Send failure: Broken pipe
curl: (35) getpeername() failed with errno 22: Invalid argument
  • The router's WAN port has a public IP address from the ISP.
  • I run a Wireguard server but I hope that it's not relevant to the problem.
  • Here is /etc/config/network:
root@RPI_OpenWrt:~# cat /etc/config/network

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

config globals 'globals'
	option ula_prefix 'fde0:8487:b021::/48'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'eth0'
	option ipv6 '0'

config interface 'lan'
	option device 'br-lan'
	option proto 'static'
	option ipaddr '192.168.1.1'
	option netmask '255.255.255.0'

config interface 'WAN'
	option proto 'dhcp'
	option device 'eth1'

config device
	option name 'eth1'
	option ipv6 '0'

config device
	option name 'eth0'

config interface 'IOT'
	option proto 'static'
	option netmask '255.255.255.0'
	list dns '1.1.1.1'
	option type 'bridge'
	option device 'eth0.10'
	option ipaddr '10.10.10.1'

config device
	option type '8021q'
	option ifname 'eth0'
	option vid '10'
	option name 'eth0.10'

config interface 'WIREGUARD'
	option proto 'wireguard'
	option private_key '***'
	option listen_port '51820'
	list addresses '172.21.12.1/24'
  • Here is /etc/config/firewall:
root@RPI_OpenWrt:~# cat /etc/config/firewall

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

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

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wan'
	list network 'wan6'
	list network 'WAN'

config forwarding
	option src 'lan'
	option dest 'wan'

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

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 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 rule
	option name 'Support-UDP-Traceroute'
	option src 'wan'
	option dest_port '33434:33689'
	option proto 'udp'
	option family 'ipv4'
	option target 'REJECT'
	option enabled '0'

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

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'HTTP'
	list proto 'tcp'
	option src 'wan'
	option src_dport '80'
	option dest_port '80'
	option dest_ip '192.168.1.177'

config redirect
	option dest 'lan'
	option target 'DNAT'
	option name 'HTTPS'
	list proto 'tcp'
	option src 'wan'
	option src_dport '443'
	option dest_port '443'
	option dest_ip '192.168.1.177'

config zone
	option output 'ACCEPT'
	option name 'IOT'
	option forward 'REJECT'
	option input 'REJECT'
	list network 'IOT'

config forwarding
	option src 'IOT'
	option dest 'wan'

config rule
	option src 'IOT'
	option target 'ACCEPT'
	option family 'ipv4'
	list proto 'tcp'
	list proto 'udp'
	option dest_port '53 67 68'
	option name 'IOT DHCP & DNS'

config rule
	option name 'Wireguard'
	option family 'ipv4'
	list proto 'udp'
	option src 'wan'
	option dest_port '51820'
	option target 'ACCEPT'

I suppose there is something misconfigured on the router. Can you help?
PS: Please let me know if more info would be useful.

Be sure to specify reflection_zone if you want to use NAT loopback.

Thank you very much for the hint! I did not know what NAT loopback is but I read a bit and figured out a solution:

Since reflection_zone does not seem to be available in Luci for port forwarding I decided to try with a specific port forwarding rule from the IOT zone to lan. Here is what worked for me:

config redirect
	option dest 'lan'
	option target 'DNAT'
	list proto 'tcp'
	option src 'IOT'
	option dest_ip '{MY_SERVER_LAN_IP}'
	option dest_port '80'
	option src_dport '80'
	option name 'IOT HTTP'
	option src_dip '{MY_PUBLIC_IP}'

config redirect
	option dest 'lan'
	option target 'DNAT'
	list proto 'tcp'
	option src 'IOT'
	option src_dport '443'
	option dest_ip '{MY_SERVER_LAN_IP}'
	option dest_port '443'
	option name 'IOT HTTPS'
	option src_dip '{MY_PUBLIC_IP}'

I want to stress on src_dip (in Luci "Advanced Settings"->"External IP address") which is important so that the rule only applies to requests targeted at the public IP address of the server/router.

PS: Just adding option reflection_zone 'IOT' to the existing forwards works with a side effect. The result was that the access from LAN to the website fails but this time with invalid certificate error.

1 Like

(I only experience this behavior here if the subject is incorrectly issued to an [RFC1918] IP.)

You firewall method is similar to another one that only requires one rule. A third method merely makes a DNS entry - but only works if all clients use your DNS. It seems here your cert may be IP-based anyway. Just making a note for others. Feel free to search the threads or ask if you need direct links.

Glad you got it working.

1 Like

Actually the problem with the invalid certificate was because for some reason OpenWrt was presenting its self signed certificate for https (instead of the one issued by letsencrypt and served by my nginx webserver).

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