The goal is to set up OpenWRT router with AdGuardHome on a separate device (as AdGuardHome requires more resources than the decent router can afford, also for the purposes of statistics).
I couldn't find a comprehensive manual, and would be happy to write one as soon as I make it work. I followed this wiki (slightly altered and fixed a pair of issues in https://openwrt.org/docs/guide-user/network/wifi/guestwifi/configuration_command_line_interface) to set up networks and firewall for IoT network isolation (it should have the DNS-filtered access to the internet, but not to the other local networks, the other local networks should have access to the devices on this network).
Then I followed this post to set up OpenWRT to work with AdGuardHome [How-To-Updated 2021] Installing AdGuardHome on OpenWrt [Manual and opkg method], but changed it as if my DNS is upstream (pointed DHCP option 6 to the static ip of RaspberryPi).
I tried directions for the upstream DNS from this recommended comment Correct Way to Set DNS Server - #24 by willowen100.
My problem is: there is no way I could make DNS work in IoT network.
I had to run dnsmasq
with noresolv='1'
, but ideally I would like it to work either as a failover or at least for the local discover. Because AdGuardHome being a single DNS for all purposes seems like a central point of failure. It's set up on RaspberryPi 3B+ which is powerful enough, but SD card is not designed for this kind of usage. AdGuardHome is set up to listen on a static 192.168.2.3 port 53
Following the guest-wlan wiki I created a network which is built on a software bridge, which doesn't have a device underneath. This is the difference from the LAN network, which is built on br-lan
that bridges lan1
and lan2
physical ports. I tried to mess with devices but it brings even more unpredictable variables. Sometimes I get locked out for no reason I understand, sometimes the connection is silently list I have to deduct to restart the wan or any other interface which I never touched, or the full router. The most annoying thing is that if I include IoT network in the LAN firewall zone, it will get DNS and work effortlessly, but that's not the goal. It's a pointer that the problem might be in firewall, but I couldn't find where exactly. Please help me good sirs.
# ubus call system board
{
"kernel": "5.15.137",
"hostname": "OpenWrt",
"system": "ARMv7 Processor rev 5 (v7l)",
"model": "GL.iNet GL-B1300",
"board_name": "glinet,gl-b1300",
"rootfs_type": "squashfs",
"release": {
"distribution": "OpenWrt",
"version": "23.05.2",
"revision": "r23630-842932a63d",
"target": "ipq40xx/generic",
"description": "OpenWrt 23.05.2 r23630-842932a63d"
# cat /etc/config/dhcp
config dnsmasq
option domainneeded '1'
option localise_queries '1'
option rebind_protection '0'
option local '/lan/'
option domain 'lan'
option expandhosts '1'
option cachesize '1000'
option authoritative '1'
option readethers '1'
option leasefile '/tmp/dhcp.leases'
option localservice '1'
option ednspacket_max '1232'
option port '54'
list server '192.168.2.3'
option noresolv '1'
config dhcp 'lan'
option interface 'lan'
option start '100'
option limit '150'
option leasetime '24h'
option dhcpv4 'server'
option dhcpv6 'server'
option ra 'server'
list ra_flags 'managed-config'
list ra_flags 'other-config'
list dhcp_option '6,192.168.2.3'
list dns '::ffff:192.168.2.3'
config dhcp 'wan'
option interface 'wan'
option ignore '1'
option start '100'
option limit '150'
option leasetime '12h'
config odhcpd 'odhcpd'
option maindhcp '0'
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'
option loglevel '4'
config dhcp 'IoT'
option interface 'IoT'
option start '100'
option limit '150'
option leasetime '12h'
list dhcp_option '6,192.168.2.3'
config host
option name 'raspberrypi'
option mac 'B8:27:EB:61:55:76'
option ip '192.168.2.3'
option leasetime 'infinite'
option duid '000100012be4692cb827eb615576'
list match_tag 'known'
option instance '0'
option dns '1'
# 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 'fde1:4999:41ef::/48'
config device
option name 'br-lan'
option type 'bridge'
list ports 'lan1'
list ports 'lan2'
option acceptlocal '1'
option igmp_snooping '1'
config interface 'lan'
option device 'br-lan'
option proto 'static'
option ipaddr '192.168.2.1'
option netmask '255.255.255.0'
option ip6assign '60'
config interface 'wan'
option device 'wan'
option proto 'static'
option ipaddr '192.168.1.2'
option netmask '255.255.255.0'
option gateway '192.168.1.1'
option peerdns '0'
list dns '1.1.1.1'
list dns '1.0.0.1'
config device 'IoT_dev'
option type 'bridge'
option name 'br-IoT'
option igmp_snooping '1'
option acceptlocal '1'
config interface 'IoT'
option proto 'static'
option device 'br-IoT'
list ipaddr '192.168.13.1/24'
option gateway '192.168.2.1'
# cat /etc/config/firewall
config defaults
option input 'REJECT'
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'
config zone
option name 'wan'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
option masq '1'
option mtu_fix '1'
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 zone 'iot'
option name 'iot'
option input 'REJECT'
option output 'ACCEPT'
option forward 'REJECT'
list network 'iot'
list network 'IoT'
config forwarding 'iot_wan'
option src 'iot'
option dest 'wan'
config forwarding 'lan_iot'
option src 'lan'
option dest 'iot'
config rule 'iot_dns'
option name 'Allow-DNS-iot'
option src 'iot'
option dest_port '53'
list proto 'tcp'
list proto 'udp'
option target 'ACCEPT'
list dest_ip '192.168.2.3'
config rule 'iot_dhcp'
option name 'Allow-DHCP-iot'
option src 'iot'
option dest_port '67'
option proto 'udp'
option family 'ipv4'
option target 'ACCEPT'
$ cat /opt/AdGuardHome.yaml
http:
pprof:
port: 6060
enabled: false
address: 192.168.2.3:80
session_ttl: 720h
users:
- name: [xxx]
password: [xxx]
auth_attempts: 5
block_auth_min: 15
http_proxy: ""
language: en
theme: auto
dns:
bind_hosts:
- 127.0.0.1
- 192.168.2.3
- ::1
- ::ffff:192.168.2.3
port: 53
anonymize_client_ip: false
ratelimit: 20
ratelimit_subnet_len_ipv4: 24
ratelimit_subnet_len_ipv6: 56
ratelimit_whitelist: []
refuse_any: true
upstream_dns:
- https://dns.cloudflare.com/dns-query
- https://dns10.quad9.net/dns-query
- https://unfiltered.adguard-dns.com/dns-query
- h3://unfiltered.adguard-dns.com/dns-query
- '[/pool.ntp.org/]1.1.1.1'
- '[/pool.ntp.org/]1.0.0.1'
- '[/lan/]127.0.0.1'
- '[//]127.0.0.1'
upstream_dns_file: ""
bootstrap_dns:
- 9.9.9.10
- 149.112.112.10
- 2620:fe::10
- 2620:fe::fe:10
- 1.1.1.1
- 1.0.0.1
fallback_dns:
- 1.1.1.1
- 1.0.0.1
- 9.9.9.9
all_servers: false
fastest_addr: false
fastest_timeout: 1s
allowed_clients: []
disallowed_clients: []
blocked_hosts:
- version.bind
- id.server
- hostname.bind
trusted_proxies:
- 127.0.0.0/8
- ::1/128
cache_size: 4194304
cache_ttl_min: 0
cache_ttl_max: 0
cache_optimistic: true
bogus_nxdomain: []
aaaa_disabled: false
enable_dnssec: false
edns_client_subnet:
custom_ip: ""
enabled: false
use_custom: false
max_goroutines: 300
handle_ddr: true
ipset: []
ipset_file: ""
bootstrap_prefer_ipv6: false
upstream_timeout: 10s
private_networks: []
use_private_ptr_resolvers: true
local_ptr_upstreams:
- 192.168.2.3:53
- 127.0.0.1
use_dns64: false
dns64_prefixes: []
serve_http3: false
use_http3_upstreams: false
serve_plain_dns: true
tls:
enabled: false
[xxx]
querylog:
ignored: []
interval: 2160h
size_memory: 1000
enabled: true
file_enabled: true
statistics:
ignored: []
interval: 24h
enabled: true
filters:
- [xxx]
whitelist_filters: []
user_rules:
- [xxx]
dhcp:
enabled: false
[xxx]
filtering:
blocking_ipv4: ""
blocking_ipv6: ""
blocked_services:
[xxx]
protection_disabled_until: null
safe_search:
enabled: false
[xxx]
blocking_mode: default
parental_block_host: family-block.dns.adguard.com
safebrowsing_block_host: standard-block.dns.adguard.com
rewrites: []
safebrowsing_cache_size: 1048576
safesearch_cache_size: 1048576
parental_cache_size: 1048576
cache_time: 30
filters_update_interval: 24
blocked_response_ttl: 10
filtering_enabled: true
parental_enabled: false
safebrowsing_enabled: false
protection_enabled: true
clients:
runtime_sources:
whois: true
arp: true
rdns: true
dhcp: true
hosts: true
persistent: []
log:
file: ""
max_backups: 0
max_size: 100
max_age: 3
compress: false
local_time: false
verbose: false
os:
group: ""
user: ""
rlimit_nofile: 0
schema_version: 27