Acknowledgement to @arinc9. For others wanting this setup, see below.
- RPi4 primary router/firewall using VLANs (my setup has WiFi provided by a dumb AP and uses these VLANs to maintain isolation between three networks but that is outside the scope of this) via subinterfaces
- LXC running pi-hole in my case but can be anything obviously (great post on LXC setup)
- Dumb AP (VLAN-aware) connected for WiFi (outside of scope of this but mentioned for clarity
/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 'fd1a:184b:b879::/48'
option packet_steering '1'
config device
option name 'eth0'
option ipv6 '0'
config device
option name 'eth1'
option ipv6 '0'
config device
option name 'wg0'
option ipv6 '0'
config device
option type 'bridge'
option name 'lxcbr0'
option ipv6 '0'
option bridge_empty '1'
config device
option name 'eth0.1'
option type '8021q'
option ifname 'eth0'
option vid '1'
option ipv6 '0'
config device
option name 'eth0.3'
option type '8021q'
option ifname 'eth0'
option vid '3'
option ipv6 '0'
config device
option name 'eth0.5'
option type '8021q'
option ifname 'eth0'
option vid '5'
option ipv6 '0'
config interface 'wan'
option device 'eth1'
option proto 'dhcp'
option peerdns '0'
option delegate '0'
list dns '1.1.1.1'
list dns '1.0.0.1'
config interface 'lxc'
option device 'lxcbr0'
option proto 'static'
option ipaddr '10.0.4.1'
option netmask '255.255.255.0'
config interface 'lan'
option device 'eth0.1'
option proto 'static'
option ipaddr '10.9.8.1'
option netmask '255.255.255.0'
config interface 'guest'
option device 'eth0.3'
option proto 'static'
option ipaddr '10.9.7.1'
option netmask '255.255.255.0'
config interface 'iot'
option device 'eth0.5'
option proto 'static'
option ipaddr '10.9.5.1'
option netmask '255.255.255.0'
config interface 'wg0'
option proto 'wireguard'
...
# wireguard specifics omitted for privacy
/etc/config/firewall
# standard firewall rules omitted
config rule 'wg'
option name 'Allow-WireGuard'
option proto 'udp'
option target 'ACCEPT'
option src 'wan'
option dest_port '4500'
config include
option path '/etc/firewall.user'
config zone 'lan'
option name 'lan'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'lan'
config zone
option name 'guest'
option output 'ACCEPT'
option forward 'REJECT'
list network 'guest'
list network 'wg0'
option input 'REJECT'
config zone
option name 'lxc'
option output 'ACCEPT'
list network 'lxc'
option forward 'ACCEPT'
option input 'REJECT'
config zone
option name 'iot'
option output 'ACCEPT'
option forward 'REJECT'
option input 'REJECT'
list network 'iot'
config zone 'wan'
option name 'wan'
option output 'ACCEPT'
option masq '1'
option mtu_fix '1'
option input 'DROP'
option forward 'DROP'
list network 'wan'
config rule
option src 'guest'
option target 'ACCEPT'
option name 'guest dhcp and dns'
list proto 'tcp'
list proto 'udp'
option dest_port '53 67 68'
config forwarding 'lan_wan'
option src 'lan'
option dest 'wan'
config forwarding
option src 'guest'
option dest 'wan'
config rule
option src 'iot'
option target 'ACCEPT'
list proto 'tcp'
list proto 'udp'
option dest_port '53 67 68'
option name 'iot dhcp and dns'
config rule
list proto 'udp'
option src 'lxc'
option dest_port '53'
option target 'ACCEPT'
option name 'pi-hole-dns lxc to input'
config rule
list proto 'udp'
option src 'guest'
option dest 'lxc'
option dest_port '53'
option target 'ACCEPT'
option name 'pi-hole-dns guest to lxc'
config forwarding
option src 'lan'
option dest 'guest'
config forwarding
option src 'lan'
option dest 'iot'
config forwarding
option src 'lan'
option dest 'lxc'
config forwarding
option src 'lxc'
option dest 'wan'
/srv/lxc/pihole/config
# Template used to create this container: /usr/share/lxc/templates/lxc-download
# Parameters passed to the template: --dist archlinux --release current
# Template script checksum (SHA-1): 8dff53d9a72ba3c071585c5762e2d14c57943cfa
# For additional config options, please look at lxc.container.conf(5)
# Uncomment the following line to support nesting containers:
#lxc.include = /usr/share/lxc/config/nesting.conf
# (Be aware this has security implications)
# Distribution configuration
lxc.include = /usr/share/lxc/config/common.conf
lxc.arch = aarch64
# Container specific configuration
lxc.rootfs.path = dir:/srv/lxc/pihole/rootfs
lxc.uts.name = pihole
# Network configuration
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.ipv4.address = 10.0.4.250/24
lxc.net.0.ipv4.gateway = 10.0.4.1
Networks a.k.a. Interfaces and Interfaces a.k.a. Devices:
Firewall zones and manually added traffic rules