Blocking websites on your router

I found a tutorial online about how to block websites on your router using ipsets - the guide can be found here (in Polish!) but I'll outline the here too:

1. Install packages

# opkg update
# opkg remove dnsmasq
# opkg install dnsmasq-full ipset

2. Define your ipset in your firewall
In your /etc/config/firewall file, create an ipset along the lines of the example below:

config ipset
        option enabled '1'
        option name 'block_youtube'
        option family 'ipv4'
        option storage 'hash'
        option match 'dest_ip'
        option maxelem '256'
        option timeout '7200'
  • The name attribute is obvious enough.
  • This ipset is specifically for ipv4 and if we also wanted to block at the ipv6 level, we'd need a second ipset where the family is set to ipv6
  • The maxelem attribute defines the size of the ipset (i.e. number of IP addresses that correspond to our domain blacklist that we'll define later). 256 should suffice?
  • The timeout attribute defines how long an entry should remain in the ipset. Larger websites which use CDNs will have a larger pool of IP addresses and will likely rotate addresses often so we don't want the ipset list to accumulate with outdated entries.

3. Define the rule for the ipset in your firewall
In your /etc/config/firewall file, also add a rule along the lines of the example below:

config rule
        option name 'block_youtube'
        option src 'lan'
        option proto 'all'
        option ipset 'block_youtube'
        option family 'ipv4'
        option target 'REJECT'
        option dest 'wan'
        option enabled '1'

For extra configuration, you could adjust the rule so that it only applies for certain MAC addresses/IP addresses (e.g. option src_ip '192.168.1.111') or even on a timer (e.g. option start_time '19:50:00' and option stop_time '23:59:59')

4. Set up the list of domains to block using dnsmasq
In your /etc/dnsmasq.conf file, add the following:

cache-size=10000
min-cache-ttl=3600
max-cache-ttl=7200

In your /etc/config/dhcp file, you can now add the list of domains to blacklist under the config dnsmasq section:

config dnsmasq
        list ipset '/youtube.com/block_youtube'
        list ipset '/googlevideo.com/block_youtube'
        list ipset '/ytimg.com/block_youtube'

Note how multiple domains are being blocked as part of the block_youtube ipset that we defined earlier in our firewall config.


Thoughts on how to improve this:

Multiple devices under one rule
Is it possible to create a firewall rule that can accept multiple source MAC addresses/multiple source IP addresses?
For instance, can I create ONE rule that applies to 192.168.1.3, 192.168.1.14 and 192.168.1.34? Right now, it seems the only way to do this is to create three separate rules which is rather tedious as it's a lot of repetition.

Improving the web interface/Luci experience
Right now, it's not possible to create an ipset in the firewall section of Luci. Nor is it possible to create a firewall rule that references an ipset via Luci. It has to be done by editing the underlying UCI file.

I'd be really interested in contributing to OpenWrt to add in this functionality - any pointers on where one should begin?

4 Likes

Have you looked at Adblock and Simple Adblock?

A big issue with this is when multiple sites are hosted on one machine. Like with cloudflare or akamai. You go to blockeddomain.com and it adds the IP to the set, then you go to gooddomain.com and it turns out DNS returns the same IP as blockeddomain.com... and you're stuck.

Squid proxy can handle this at the right level, namely http domain level.

You're making simple things complicated
All you have to do is to block the DNS requests for certain websites

config dnsmasq
        list server '/example.com/'

Can also be done in LuCI
image

root@OpenWrt:~# nslookup www.example.com
Server:         127.0.0.1
Address:        127.0.0.1#53

** server can't find www.example.com: NXDOMAIN
** server can't find www.example.com: NXDOMAIN
3 Likes

yes but if you do that then its blocked for every device on the network. what if you want to block youtube for a couple devices (kids) but not everyone. now of course you can block per device if you know the external ip but thats not always possible with content delivery networks. i think this is a great idea and ive been tearing my hair out trying to figure out how to do this exact thing on openwrt when my old cheap tplink that i upgraded with openwrt would do it quite easily.

this looks a bit intimidating but i will try it. but it would be so nice if there were a luci app. so many threads about this and still no real practical answer. blocking a domain for every single user is not an answer. and blocking access per device based on external sites ip is not practical either

1 Like

How about running another dnsmasq instance for your kids that will block those sites?
Alternatively you could assign another resolver for your own hosts that will resolve those sites.

Let me know how it goes! :smiley:

Interesting point @trendy - didn't know it was possible to have multiple dnsmasq instances running and then selectively point certain client devices to a particular resolver.

@trendy @thencein I'm a nube with OpenWRT do you have the steps on how to have multiple dnsmasq instances to block kids while allowing adults to certain sites?
With covid my kids are at online school but i catch them playing games during school or other sites. I'd like to whitelist the school sites/classes but allow for adults. Please point me to easy simple instructions, I'd really appreciate it. Thanks.
John

https://openwrt.org/docs/guide-user/base-system/dhcp_configuration?s[]=dnsmasq#multiple_dhcpdns_serverforwarder_instances

1 Like