Forcing all DNS traffic from the LAN to the firewall

The rules like

iptables -t nat -A CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p udp -m udp --dport 53 -j RETURN

accept all DNS requests addressed to the DNS server on IPFire ( this is the behaviour demanded by DHCP options ). All other request, and only these, are redirected to the DNS server ( IPFire blue0 or green0 IP ).

BTW, the REDIRECT target replaces the ‘illegal’ DNS server address by the local address. Thus the destination is transformed <externalIP:53 —> :53, if I haven’t misunderstood the iptables man page.
As you can see above, I have activated all loggings. Catching the ‘good boys’ at first reduces the amount of messages. And only the real redirects are logged, thus make it much easier to search for the ‘bad boys’ in the system.

1 Like

Hello Pierre - I plan to do that once the above thread settles. And I sent a note to the IPFire devs to make sure all is OK.

2 Likes

Hi Michael - Port 853 is not forgotten! I just set it aside to get port 53 done first. I also plan to do port 123 (NTP).

I think the structure is effective for every (service, protocol, port) relation, that should be handled by IPFire. Therefore we can use it for NTP also. Probably even for the forced web proxy usage. Latter I haven’t tried, yet.

Ok - here is my latest version with DNS port 853 added and NTP port 123 added. I’m in the process of testing this code. Make sure you look it over before using. Use this at your OWN RISK.

#!/bin/sh
# Used for private firewall rules
#
# Use this at your OWN RISK.  It is not fully tested and not fully supported.
#	https://community.ipfire.org/t/forcing-all-dns-traffic-from-the-lan-to-the-firewall/3512
#
# See how we were called.
case "$1" in
  start)
        ## add your 'start' rules here
        #
        # Force DNS for green to query the firewall, and not an outside DNS server
        # REDIRECT DNS port 53 to FW (and not an outside DNS server)
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 53
        # REDIRECT DoT port 853 to FW (and not an outside DNS server)
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -j REDIRECT --to-ports 853
        # REDIRECT NTP port 123 to FW (and not an outside NTP server)
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "NTPREDIRECT "
        iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -j REDIRECT --to-ports 123
        ;;
  stop)
        ## add your 'stop' rules here
        #
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 53
        #
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -j REDIRECT --to-ports 853
        #
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "NTPREDIRECT "
        iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -j REDIRECT --to-ports 123
        ;;
  reload)
        $0 stop
        $0 start
        ## add your 'reload' rules here
        ;;
  flush)
        iptables -t nat -F CUSTOMPREROUTING
        ;;
  *)
        echo "Usage: $0 {start|stop|reload}"
        ;;
esac

I think you should replace the DoT rules by reject rules. DoT use TLS so the client could not establish a connection to a redirected server because the TLS validation fail.

1 Like

@arne_f has a technically point, and an outright reject for tcp/853 would resolve it.

Or alternatively skip having a DNS over TLS rule as it would be similar to redirecting, or proxying HTTPS, or any other deemed “secure” connections for that matter. Whilst technically not impossible, the question is rather a “should one do this”. It would be an ethically questionable practise at best, and depending on where in the world you find yourself a possible legal hornets nest at a worst case scenario.

REJECT isn’t allowed in PREROUTING.

My firewall.local with Jon’s suggestions

  • green only,

  • DoT commented out ( DoT to external servers is rejected by FW rule )

  • ACCEPT rules for request to local server

    #!/bin/sh
    #Used for private firewall rules
    #
    # Use this at your OWN RISK.  It is not fully tested and not fully supported.
    #	https://community.ipfire.org/t/forcing-all-dns-traffic-from-the-lan-to-the-firewall/3512
    #
    # See how we were called.
    case "$1" in
        start)
               ## add your 'start' rules here
               #
               # Force DNS for green to query the firewall, and not an outside DNS server
               # accept all connections obeying the rules
               iptables -t nat -A CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p udp -m udp --dport 53 -j RETURN
               iptables -t nat -A CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p tcp -m tcp --dport 53 -j RETURN
               iptables -t nat -A CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p tcp -m tcp --dport 853 -j RETURN
               iptables -t nat -A CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p udp -m udp --dport 123 -j RETURN
               # REDIRECT DNS port 53 to FW (and not an outside DNS server)
               iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
               iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
               iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
               iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 53
               # REDIRECT DoT port 853 to FW (and not an outside DNS server)
               #iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
               #iptables -t nat -A CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -j REJECT
               # REDIRECT NTP port 123 to FW (and not an outside NTP server)
               iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "NTPREDIRECT "
               iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -j REDIRECT --to-ports 123
               ;;
        stop)
               ## add your 'stop' rules here
               # green0
               iptables -t nat -D CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p udp -m udp --dport 53 -j RETURN
               iptables -t nat -D CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p tcp -m tcp --dport 53 -j RETURN
               iptables -t nat -D CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p tcp -m tcp --dport 853 -j RETURN
               iptables -t nat -D CUSTOMPREROUTING -i green0 -d 192.168.10.254 -p udp -m udp --dport 123 -j RETURN
               #
               iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
               iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
               iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
               iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 53
               #
               #iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "DNSREDIRECT "
               #iptables -t nat -D CUSTOMPREROUTING -i green0 -p tcp -m tcp --dport 853 -j REJECT
               #
               iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -m limit --limit 10/sec --limit-burst 20 -j LOG --log-prefix "NTPREDIRECT "
               iptables -t nat -D CUSTOMPREROUTING -i green0 -p udp -m udp --dport 123 -j REDIRECT --to-ports 123
                ;;
        reload)
              $0 stop
              $0 start
              ## add your 'reload' rules here
              ;;
        flush)
              iptables -t nat -F CUSTOMPREROUTING
              ;;
        *)
             echo "Usage: $0 {start|stop|reload}"
             ;;
    esac

May I ask why you commented out those lines with port 853?

See Arne’s post above.

Correct. Add a normal reject rule for port 853 in the CUSTOMFORWARD chain (without the -t nat?) or create a usual Firewall rule that blocks the port from green/blue to any in the gui. (don’t block in the output chain for red)

2 Likes

Done. :wink: ( see my edited post )

Just to make sure I am tracking…

  • Is the DoT (port 853) rule only needed for localdomain devices that send DoT requests (port 853)? I don’t have any of those but maybe other do.

  • And a new rule (not PREROUTING/CUSTOMPREROUTING) is needed for DoT?

The above mentioned rules in firewall.local do

  • allow DNS/NTP requests to the local DNS/NTP server on IPFire system
  • DNS/NTP requests to external servers are redirected to the servers in IPFire system.

This is done as soon as possible ( in iptables chain PREROUTING ).
Thus all (normal) DNS and NTP request are forced to use the local server.

For DNSoverTLS ( DoT ) this isn’t possible, because of not matching certificates.
To deny those requests to external servers one must define a firewall rule which rejects those packets. You can do this from the WUI.

3 Likes

So this is the reason why you commented out those lines with port 853, right?

Yes.
But I left them in the file. Maybe there is some solution for the redirected DoT, nobody knows :sunglasses:

…and in the end, at least as I understand, if clients like Firefox use DoT, I cannot redirect it, but block the requests, correct?

Does this work if you block port 853 on green? FW rule
And ipfire DNS is set to use DoT?
Clients using port 54
Can’t Test DoT at my location

You may want to try Option 2 but substitute port 853 for port 53. And use protocol tcp only (udp isn’t used for DoT),

https://wiki.ipfire.org/configuration/firewall/dns#2-block-all-dns-traffic-except-through-ipfires-dns-proxy

I don’t have anything on my LAN that uses DoT so I’m not sure how to test without doing a little research.

1 Like