firewall rules via user scripts (services-start, nat-start) not working

peiskos

New Around Here
Hi all,

Apologies if this is straight-forward; I'm not very technically savvy in this area, but this forum seemed like the right place to post a question about it.

I use a DNS filter on my home network router (Asus RT-N66U, running Merlin 380.70). I'm want to prevent users from using 3rd party DNS servers (like Google's), so I'm trying to follow this article:

I've tried implementing this via the services-start user script and the nat-start user script, but neither seem to work (if I set my DNS to Google's I can still bypass the DNS filter).
Here's what I've got in each script, both of which are stored in /jffs/scripts.
services-start
Bash:
#!/bin/sh
touch /tmp/000services-start
iptables -t nat -A PREROUTING -i br0 -p udp --dport 53 -j DNAT --to 103.247.36.36
iptables -t nat -A PREROUTING -i br0 -p tcp --dport 53 -j DNAT --to 103.247.36.36

nat-start
Bash:
#!/bin/sh
touch /tmp/000nat-start
iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to 103.247.36.36:53
    iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to 103.247.37.37:53
touch /tmp/000nat-stop

The touch commands run, but the iptables commands don't seem to do what I'd like them to (force all users to use DNS filter DNS servers).
I've enabled JFFS custom scripts and configs on my router's page, and I've given rights to my scripts via
Bash:
chmod a+rx /jffs/scripts/*

Thanks in advance for any help or suggestions!
 

ColinTaylor

Part of the Furniture
Why aren't you using just the router's built-in DNSFilter function? It creates exactly the same iptables rules that you are trying to do.
 

peiskos

New Around Here
I don't believe my router has that option. Here's a screenshot of the LAN page (notice there's no DNSFilter tab):
Screen Shot 2021-11-23 at 3.10.57 PM.png
 

ColinTaylor

Part of the Furniture
I believe it's under Parental Controls (it was moved in later firmware versions).
 

L&LD

Part of the Furniture
No, your router doesn't have that option with that wildly out-of-date firmware.

You should consider using your RT-N66U with @john9527's firmware. I can't remember if it has DNSFilter in it, but it will be vastly more secure.
 

peiskos

New Around Here
Apparently it does have the option, thanks for pointing out its location Colin.
@L&LD it's the latest compatible firmware for my router according to the asus merlin page.

So I've been twiddling with the DNSFilter options, but I can't get it to work or do anything. Am I missing something here? (attached screenshots of my configuration) Sorry again if I'm missing something obvious. My DNS Filter (the service, not the router setting) works fine if my router's users don't specify their own DNS, but as soon as I set my macbook to use Google's public DNS I can bypass the filter.
 

Attachments

  • Screen Shot 2021-11-23 at 3.37.20 PM.png
    Screen Shot 2021-11-23 at 3.37.20 PM.png
    450 KB · Views: 24
  • Screen Shot 2021-11-23 at 3.38.32 PM.png
    Screen Shot 2021-11-23 at 3.38.32 PM.png
    167.4 KB · Views: 25
  • Screen Shot 2021-11-23 at 3.40.31 PM.png
    Screen Shot 2021-11-23 at 3.40.31 PM.png
    302 KB · Views: 25

ColinTaylor

Part of the Furniture
This DNSFilter technique only works with standard DNS requests (port 53). If your macbook is using DoH or DoT it will bypass this type of filtering.


P.S. On LAN - DHCP Server the DNS Server 1 & 2 fields should be blank.
 
Last edited:

L&LD

Part of the Furniture

peiskos

New Around Here
Thanks @ColinTaylor; you were right. Disabling "Use secure DNS" on Chrome made the router's DNSFilter settings work.

Now I'd like to block as many DoH providers as I can. I found this useful publicly-maintained list:
However, doing this using the "Route" option on my router is not feasible because it only accepts a limited number of IP addresses (attached an example screenshot).

Are there any other ways to get my firewall to block the IP addresses listed at the page above?
 

Attachments

  • Screen Shot 2021-11-23 at 4.18.24 PM.png
    Screen Shot 2021-11-23 at 4.18.24 PM.png
    417.5 KB · Views: 22

peiskos

New Around Here
Figured out how to block a large list of DOH providers using a firewall-start script (without diversion or an ipset script). The template of the script is:
Bash:
#!/bin/sh
touch /tmp/000firewall-start
# Repeat for each DOH provider
iptables -I FORWARD -s x.x.x.x -j DROP
iptables -I FORWARD -d x.x.x.x -j DROP
touch /tmp/000firewall-stop

I downloaded this list of DOH providers:
And had a python script generate the firewall-start script, where 'iplist.txt' is the downloaded text list:
Python:
to_write = ['#!/bin/sh', '\n',
            'touch /tmp/000firewall-start', '\n']

with open('iplist.txt', 'r') as iplist:
    for line in iplist:
        if line[0] not in ['#', '\n', ' ']:
            str = line.replace('\n', '')
            command_1 = f'iptables -I FORWARD -s {str} -j DROP'
            command_2 = f'iptables -I FORWARD -d {str} -j DROP'
            to_write.extend([command_1, '\n', command_2, '\n'])
to_write.append('touch /tmp/000firewall-stop')

with open('firewall-start', 'w') as script:
    script.writelines(to_write)

Then copied the firewall-start script to my router via scp and rebooted.
Bash:
scp /local/path/to/firewall/script/firewall-start [email protected]:/jffs/scripts/firewall-start
It's working with no issues now. Hope this helps anyone else trying to do the same.
 

eibgrad

Part of the Furniture
@peiskos

FYI. That list of DOH providers doesn't make for a very efficient firewall. For example, it enumerates every IP from 45.90.28.1 thru 45.90.28.254, and 45.90.30.1 thru 45.90.30.254, for NextDNS, when it would be far more efficient to simply specify 45.90.28.0/24 and 45.90.30.0/24, respectively. IOW, convert them to class C networks.

Also, there's no need to be checking all those IPs for each and every packet. Once a NEW connection is established (which means it passed muster), there's no further need to check it. It would be far better to place the list of IPs in their own user-defined chain, then only check the chain on new TCP connections.

Code:
iptables -N block_doh
iptables -A block_doh -d 168.235.81.167 -j REJECT
iptables -A block_doh -d 176.56.236.175 -j REJECT
...
iptables -A block_doh -j RETURN
iptables -I FORWARD -p tcp -m state --state NEW -j block_doh
 

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top