DNS-based firewall rules on OpenWrt 22.03 using IP sets and fw4

I wanted to be able to use DNS-based firewall rules like on pfsense, opnsense and Sophos UTM for certain use cases. OpenWRT does not have this functionality built in. I came up with the following solution.

This allows you to list DNS names, for example in /etc/ipset-dns/dst_host_search_engines.list:

google.com
www.google.com
yahoo.com
www.yahoo.com
bing.com
www.bing.com

With a corresponding IP set entry in /etc/system/firewall:

config ipset
        option name 'dst_host_search_engines'
        option match 'dst_ip'
        option enabled '1'
        option timeout '0'

And an example firewall rule you could use with OpenWRT in /etc/config/firewall:

config rule
        option name 'Allow-Search-Engines'
        option family 'ipv4'
        list proto 'all'
        option ipset 'dst_host_search_engines'
        option family 'ipv4'
        option target 'ACCEPT'
        option src 'lan'

And the entirety of the script, which will query the hosts listed based on their IP address family, and set a timeout based on the TTL of the DNS entries.

/etc/ipset-dns.sh (don't forget to set executable bit):

#!/bin/sh

for filename in /etc/ipset-dns/*.list; do
        ipset=$(basename $filename | cut -d '.' -f1)
        stdout=$(nft list set inet fw4 $ipset 2>&1)
        if [ $? -gt 0 ]; then
                echo $stdout | sed 's/^Error/Warning/'
                continue
        fi

        nft_type=$(echo $stdout | grep -oE 'type \w+' | awk '{ print $2 }')
        type=
        if [[ "$nft_type" == "ipv4_addr" ]]; then
                type=A
        elif [[ "$nft_type" == "ipv6_addr" ]]; then
                type=AAAA
        else
                echo "Warning: invalid type $nft_type for $ipset"
                continue
        fi


        dig $type -f $filename +noall +answer | while read _ ttl _ _ ip; do
                ttl=$(( ttl + 500 ))
                nft add element inet fw4 $ipset { ${ip} timeout ${ttl}s };
        done
done

And the following crontab entry for the root user, in /etc/crontabs/root so that the script runs at boot and every 5 minutes (modify to suit, but make sure to update the 500 second addition on the TTL):

@reboot /etc/ipset-dns.sh
5 * * * * /etc/ipset-dns.sh

What Linux/*BSD distributions have Syncookies enabled by default?

In light of the recently published article on Quick Blind TCP Connection Spoofing with SYN Cookies, I wanted to see what operating systems and distributions have Syncookies enabled by default.

Distribution Sysctl Default
Ubuntu Linux 12.04 net.ipv4.tcp_syncookies On
Debian Linux 6 Off
Debian Linux 7 On
CentOS 5 On
CentOS 6 On
FreeBSD 8 net.ipv4.tcp_syncookies On
Solaris 10 Not Implemented Off
OpenBSD 5.3 Not Implemented Off

I'm not sure that turning off Syncookies is the best idea, due to the potential DoS effects from disabling them – applications should use something besides IP addresses for authentication.