Forcing all DNS traffic from the LAN to the firewall

Thinking about the problem ( no output interface in prerouting, destination of request isn’t ipfire ) revealed the following command
iptables -t nat -A CUSTOMPREROUTING -i blue0 ! -d 192.168.20.1 -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
with 192.168.20.1 == blue IP of my IPFire.
The other commands can be given accordingly.

1 Like

Alternatively, to shorten the analysis of the DNS packets, we can accept ‘well-behaved’ requests first.
So, my firewall.local reads

#!/bin/sh
# Used for private firewall rules

# See how we were called.
case "$1" in
  start)
        ## add your 'start' rules here
        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 -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
        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
        iptables -t nat -A CUSTOMPREROUTING -i blue0  -d 192.168.20.1 -p tcp -m tcp --dport 53 -j RETURN
        iptables -t nat -A CUSTOMPREROUTING -i blue0  -d 192.168.20.1 -p udp -m udp --dport 53 -j RETURN
        iptables -t nat -A CUSTOMPREROUTING -i blue0  -d 192.168.20.1 -p tcp -m tcp --dport 853 -j RETURN
        iptables -t nat -A CUSTOMPREROUTING -i blue0  -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 blue0  -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
        iptables -t nat -A CUSTOMPREROUTING -i blue0  -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 blue0  -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 53
        iptables -t nat -A CUSTOMPREROUTING -i blue0  -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 blue0  -p tcp -m tcp --dport 853 -j REDIRECT --to-ports 853
        ;;
  stop)
        ## add your 'stop' rules here
        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 -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 blue0  -d 192.168.20.1 -p tcp -m tcp --dport 53 -j RETURN
        iptables -t nat -D CUSTOMPREROUTING -i blue0  -d 192.168.20.1 -p udp -m udp --dport 53 -j RETURN
        iptables -t nat -D CUSTOMPREROUTING -i blue0  -d 192.168.20.1 -p tcp -m tcp --dport 853 -j RETURN
        iptables -t nat -D CUSTOMPREROUTING -i blue0  -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 blue0  -p udp -m udp --dport 53 -j REDIRECT --to-ports 53
        iptables -t nat -D CUSTOMPREROUTING -i blue0  -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 blue0  -p tcp -m tcp --dport 53 -j REDIRECT --to-ports 53
        iptables -t nat -D CUSTOMPREROUTING -i blue0  -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 blue0  -p tcp -m tcp --dport 853 -j REDIRECT --to-ports 853
        ;;
  reload)
        $0 stop
        $0 start
        ## add your 'reload' rules here
        ;;
  flush)
        iptables -t nat -F CUSTOMPREROUTING
        ;;        
  *)
        echo "Usage: $0 {start|stop|reload}"
        ;;
esac
1 Like

@hellfire
I think you are looking at the wrong part of the thread, have another look here

From what I see your lines are for orange0 and not green0 and you are still using the ! -o which as @arne_f correctly pointed out was incorrect, and does not apply to PREROUTING, and therefore also not to CUSTOMPREROUTING.

For example your line
iptables -t nat -A CUSTOMPREROUTING ! -o orange0 -p udp --destination-port 53 -j REDIRECT --to-ports 53
should read
iptables -t nat -A CUSTOMPREROUTING -i green0 -p udp --destination-port 53 -j REDIRECT --to-ports 53

The reason I have the ACCEPT CUSTOMPREROUTING rule before the above mentioned REDIRECT CUSTOMPREROUTING was to show what is needed if you have a specific machine that should have access to whatever DNS server it wants to use and not force it to REDIRECT to the one used by the FW.
In my example 192.168.114.6/32 is the single IP machine, and as you can see from the conntrack output it chats to 1.1.1.1 via dst=4*.***.***.**0 which is red0
The second conntrack shows that the machine 192.168.114.1 which does not have an ACCEPT entry is REDIRECT to 192.168.114.254 which is green0 and it does the DNS queries.
In the end 192.168.114.1 believes it spoke to 1.1.1.1, but actually 192.168.114.254 did the resolve with whichever DNS server was assigned in Network > Domain Name System via the Web GUI.

@bbitsch
Do I understand you correctly? I should add a destination, -d 192.168.114.254 (in my example) to shorten the query times and streamline everything, and that the FW is also the DNS Proxy Server is irrelevant?

PS I tend to write explanations about why I say something not because I think you have no clue, but more so that newer users who don’t know can understand why. Please do not take office… :nerd_face:
I treat everyone like a special mushroom :kissing_heart:

1 Like

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: