From mboxrd@z Thu Jan  1 00:00:00 1970
From: Bernhard Bitsch <bbitsch@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH] (V4) Forcing DNS/NTP
Date: Thu, 10 Jun 2021 13:01:26 +0200
Message-ID: <9461bdc8-7620-d550-98de-744af41edf13@ipfire.org>
In-Reply-To: <BB27C33F-D2E2-4BF1-9341-8900A5EDBFD5@ipfire.org>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="===============4879560201745018057=="
List-Id: <development.lists.ipfire.org>

--===============4879560201745018057==
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable

Hello,

agreed ;).
My thoughts were somehow to theoretical.

Am 10.06.2021 um 11:21 schrieb Michael Tremer:
> Hello,
>=20
> I understand the thought, but I consider this a different problem.
>=20
> There are two scenarios:
>=20
> A) IPFire is the DNS server for the network. The new rules can then be enab=
led and will force any DNS query being responded to by IPFire.
>=20
> B) The user is using different DNS servers in their DHCP configuration. In =
that case, we cannot redirect at all, because that only works for one destina=
tion and not multiple (at least not with iptables rules).
>=20
> But in B), you can create simple firewall rules and block DNS with an excep=
tion of those DNS servers that you want to allow.
>=20

Thanks for clarifying this.
I suppose to state this in the announcement of the first core update=20
containing the forcing functionality:
The 'Forcing DNS/NTP' rules can only handle scenario A. ( Are the=20
default entries in DHCP config the IPFire address? )
Scenario B must be handled by extra rules.
This should be found in wiki also, I'm willing to support this.

> I suppose this is always the problem by having these =E2=80=9Cshortcuts=E2=
=80=9D that make things easy for the user. They do, but only in a very specif=
ic scenario. If we would extend this now, it would get more and more complica=
ted and then the whole simplicity of the feature would be thrown out of the w=
indow.
>=20

Wise words. ;)

-Bernhard

> Also, please don=E2=80=99t use 8.8.8.8 :)
>=20
> -Michael
>=20
>> On 7 Jun 2021, at 16:31, Bernhard Bitsch <bbitsch(a)ipfire.org> wrote:
>>
>> Hi,
>>
>> sorry if I made you going crazy. ;)
>>
>> My comment aimed to discuss the selection of the correct redirect address.=
 See my further comments below(;)).
>> I fear forcing requests to the right address is a bit more complex than it=
 looked at the first approach.
>>
>> Am 06.06.2021 um 19:35 schrieb Matthias Fischer:
>>> Hi,
>>> On 06.06.2021 10:59, Bernhard Bitsch wrote:
>>>> Hi,
>>>>
>>>> thanks for implementing this idea.
>>> I tried my best, but when reading further I realized that I've missed
>>> something... See below.
>>> [Sorry for the noise, but I thought it would be the best to keep this
>>> unshortened.]
>>>>> Am 04.06.2021 um 14:17 schrieb Matthias Fischer:
>>>>> There was not much feedback on the list, so I send this now. This is V4=
 - open for
>>>>> discussion, opinions or (perhaps ;-) ) changes:
>>>>>
>>>>> Originally triggered by:
>>>>> https://community.ipfire.org/t/forcing-all-dns-traffic-from-the-lan-to-=
the-firewall/3512
>>>>>
>>>>> Discussion:
>>>>> https://community.ipfire.org/t/testing-dns-redirect-code-snippet/3888
>>>>>
>>>>> Could fix(?):
>>>>> https://bugzilla.ipfire.org/show_bug.cgi?id=3D11168
>>>>>
>>>>> Changelog since V3:
>>>>>
>>>>> - Replaced 'green0'/'blue0' with '${GREEN_DEV}' / '${BLUE_DEV}' - these
>>>>>     values are read from '/var/ipfire/ethernet/settings', thanks
>>>>>     to "someone" for the hint (sorry, I didn't find the author)! ;-)
>>>>>
>>>>> - Replaced port numbers '123' / '53' with service names 'domain' / 'ntp=
' (dto.).
>>>>>
>>>>> - As mentioned on the list (05.03.2021, BB), 'well-behaving' requests a=
re now
>>>>>     handled through RETURN rules, others through REDIRECT.
>>>>>
>>>>> Background (cited from BB, 06.03.2021):
>>>>> "Concerning performance, we want to minimize the rule set to the amount
>>>>> really necessary. On the other hand, it may be quicker to do just
>>>>> a RETURN than a REDIRECT. The cases for the RETURN (DNS requests direct
>>>>> to IPFire) should be nearly 100%. DNS and NTP servers are published
>>>>> by DHCP or should be configured in the static case."
>>>>>
>>>>
>>>> Sorry, I did not realize that this 'well-behaving' must be defined more
>>>> exactly. See beyond.
>>> Yep. No problem. Now I know what you meant.
>>> And again, "see beyond"... ;-)
>> Further comments follow below ;-)
>>>>> I made it that way. Statistics during the last 62 days show that this
>>>>> worked as intended. IMHO. I've sent a screenshot to the list (the other=
 day) so
>>>>> everyone could take a look.
>>>>>
>>>>
>>>> That's my experience with the rules located in firewall.local, too.
>>>>
>>>>> - Removed GUI links to DNS and NTP options in 'optionsfw.cgi'.
>>>>>
>>>>> - Moved creation of the iptable rules in '/etc/init.d/firewall' behind
>>>>> '# WIRELESS chains'
>>>>>
>>>>> Summary and functionality:
>>>>>     These patches are controlled through "Firewall Options". They add n=
ew
>>>>>     firewall-[DNS/NTP]_FORCED_ON_[INTERFACE]-options to '/var/ipfire/op=
tionsfw/settings'.
>>>>>     They activate/deactivate appropriate RETURN and REDIRECT rules thro=
ugh
>>>>>     a new ctrl file ('/usr/local/bin/dnsntpctrl') and a new init file
>>>>>     ('/etc/rc.d/init.d/dnsntp').
>>>>>
>>>>>     Default of all new rules is OFF (set in 'lfs/configroot').
>>>>>     If set to ON, they REDIRECT all DNS and NTP requests (TCP/UDP) to t=
he DNS and NTP
>>>>>     servers specified in IPFire.
>>>>>
>>>>>     Flaw/ToDo:
>>>>>     To make things work as I wanted I had to add a 'dnsntpctrl' file wh=
ich calls the actual
>>>>>     init file, 'dnsntp'. As I see it, this is actually an unnecessary d=
etour.
>>>>>     In fact I wanted to merge these two files in *one* C file, but this=
 was beyond my
>>>>>     capabilities, perhaps "someone" else knows how to program this.
>>>>>
>>>>> Changed visibility (GUI, 'optionsfw.cgi') and some cosmetics:
>>>>>     The corresponding interface options - including 'Masquerade ...' - =
are only visible if
>>>>>     the respective interface actually exists.
>>>>>     E.g.: if BLUE interface doesn't exist, there are no ON/OFF switches
>>>>>     for 'DNS/NTP on BLUE' or logging options for BLUE available.
>>>>>     Added text colors for better readability.
>>>>>     Separated logging options per interface.
>>>>>
>>>>> No reboot required:
>>>>>     Rules can be switched ON/OFF without rebooting IPFire.
>>>>>     Changes immedediately take effect after clicking 'Save'.
>>>>>
>>>>> Changes to '/etc/rc.d/init.d/firewall' and '/etc/rc.d/init.d/dnsntpctrl=
':
>>>>>     Fixed a 'trafic' typo.
>>>>>     To avoid collisions with existing CUSTOM rules, I added a new PRERO=
UTING
>>>>>     chain: 'DNS_NTP_REDIRECT'.
>>>>>     This chain is flushed by 'dnsntpctrl' prior applying the choosen se=
ttings.
>>>>>
>> [cutting off parts of the main patch for discussion]
>>>>> diff --git a/src/initscripts/system/dnsntp b/src/initscripts/system/dns=
ntp
>>>>> new file mode 100644
>>>>> index 000000000..54fdfc685
>>>>> --- /dev/null
>>>>> +++ b/src/initscripts/system/dnsntp
>>>>> @@ -0,0 +1,43 @@
>>>>> +#!/bin/sh
>>>>> +######################################################################=
##
>>>>> +# Begin $rc_base/init.d/dnsntp
>>>>> +#
>>>>> +# Description : dnsntp init script for DNS/NTP rules only
>>>>> +#
>>>>> +######################################################################=
##
>>>>> +
>>>>> +# flush chain
>>>>> +iptables -t nat -F DNS_NTP_REDIRECT
>>>>> +
>>>>> +eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
>>>>> +eval $(/usr/local/bin/readhash /var/ipfire/optionsfw/settings)
>>>>> +
>>>>
>>>> The 'well-behaving' request destinations should be DNS1_GREEN,
>>>> DNS2_GREEN, DNS1_BLUE, DNS2_BLUE ( stored in /var/ipfire/dhcp/settings
>>>> and set in the dhcp.cgi ).
>>>> If they are defined and distrubited by DHCP or set by other mechanism.
>>> Ok, here we are.
>>> Ups!
>>> "DNS1_..." and "DNS2_..." entries. What/where are these? You've got me!
>>
>> I think we have two kinds of DNS/NTP servers to be forced.
>> - IPFire includes these servers, which should be used.
>> - The DHCP server can ( should? ) distribute these addresses. The WUI allo=
ws on the other hand the specification of some other addresses, which should =
be located in the local networks. That is my interpretation of these fields.
>>
>>> But now I'm a bit puzzled. Perhaps I need some hints again.
>>> Because until now I completely ignored DNS1_GREEN, DNS2_... etc. from
>>> DHCP. They existed in my installation(s) - but DHCP didn't play a role
>>> in my considerations. Never. I always used the local IPFire addresses
>>> (GREEN/BLUE). Nothing else. The addresses for "GREEN_ADDRESS" (Ethernet
>>> settings), "DNS1_GREEN" and "NTP1_GREEN" (dhcp settings) were always the
>>> same. Of course, this also applied to BLUE.
>>
>> That's also my config. Therefore I didn't think about this before. ;)
>>
>>> BTW, what would be the sense of distributing different DNS1/DNS2 entries
>>> through DHCP vs. the DOT entries under "domain name system" (e.g.)?
>>
>> DOT under 'domain name system' is a definition for the sources of name inf=
ormation of unbound.
>>
>>> What I don't understand - call it "I'm thick at the moment...":
>>> Through the current GUIs it would be possible to choose and distribute
>>> (e.g.) 8.8.8.8 as "DNS1" or "DNS2" through DHCP, while the "Domain Name
>>> System" page contains totally different (or ISP servers). Are there any
>>> circumstances where this would be useful or needed? And which could
>>> these be?
>>
>> I don't think it is useful/legal to define DNS servers outside the local n=
etworks. Defining DNS servers in DHCP other than IPFire makes only sense when=
 these use IPFire.
>>
>>>> Is GREEN_ADDRESS / BLUE_ADDRESS the desired destination otherwise?
>>> Yes. That was my only intention in the first place.
>>> I wanted to keep it simple.
>>> I wanted to make sure that my clients only use the specific *local* DNS
>>> servers running on GREEN / BLUE. And I didn't realize the possibility to
>>> enter completely different servers (through DHCP).
>>> That's why I ignored DHCP and chose the GREEN and BLUE interface
>>> (ethernet) addresses. I never thought of writing other addresses than
>>> the local IPFire GREEN/BLUE addresses in the first required DHCP fields
>>> for GREEN / BLUE. My fault(?). Hm.
>>
>> This was my first thought also.
>>
>>> Regarding 'forcing dns':
>>> You can of course always turn these OFF if they don't correspond with
>>> your wanted installation and use other DNS1 / DNS2 entries. ;-)
>>> Last question(s):
>>> If I got you right it would make more sense or be better to change the
>>> RETURN rules to use the DHCP values from "$DNS1/2_GREEN/BLUE"!?
>>> And what would be the best way to integrate *both* possible DNS entries
>>> in the initscript? Regarding DoT, are these two really needed anymore?
>>> At the moment, I'm using nine through DoT...
>>> First needed change in 'dnsntpctrl' =3D> evaluate DHCP settings. Add:
>>> ...
>>> eval $(/usr/local/bin/readhash /var/ipfire/dhcp/settings)
>>> ...
>>> New:
>>> iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${DNS1_GREEN} -p
>>> udp -m udp --dport domain -j RETURN
>>> And then?
>>> I must think this over...its been a long week... ;-)
>>> Regards,
>>> Matthias
>>
>> I must think this over, also.
>> Especially about DNS traffic.
>> If I define a configuration with a dedicated DNS server A in my GREEN net,=
 which itself questions the IPFire DNS server, and informing all 'normal' cli=
ents in GREEN to use A via DHCP, are these DNS request received by IPFire? If=
 this isn't possible by design, our first simple implementation of 'forcing' =
( redirecting to GREEN_ADDRESS/BLUE_ADDESS ) is right.
>>
>> Could someone other look at this?
>>
>> Regard,
>> Bernhard
>>
>> [ rest of patch ]
>>>>> +# Force DNS REDIRECTs on GREEN (udp, tcp, 53)
>>>>> +if [ "$DNS_FORCE_ON_GREEN" =3D=3D "on" ]; then
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${GREEN_ADDRES=
S} -p udp -m udp --dport domain -j RETURN
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -p udp -m udp --d=
port domain -j REDIRECT
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${GREEN_ADDRES=
S} -p tcp -m tcp --dport domain -j RETURN
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -p tcp -m tcp --d=
port domain -j REDIRECT
>>>>> +fi
>>>>> +
>>>>> +# Force DNS REDIRECTs on BLUE (udp, tcp, 53)
>>>>> +if [ "$DNS_FORCE_ON_BLUE" =3D=3D "on" ]; then
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -d ${BLUE_ADDRESS}=
 -p udp -m udp --dport domain -j RETURN
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -p udp -m udp --dp=
ort domain -j REDIRECT
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -d ${BLUE_ADDRESS}=
 -p tcp -m tcp --dport domain -j RETURN
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -p tcp -m tcp --dp=
ort domain -j REDIRECT
>>>>> +fi
>>>>> +
>>>>
>>>> See above.
>>>>
>>>> Regards,
>>>> Bernhard
>>>>
>>>>> +# Force NTP REDIRECTs on GREEN (udp, 123)
>>>>> +if [ "$NTP_FORCE_ON_GREEN" =3D=3D "on" ]; then
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -d ${GREEN_ADDRES=
S} -p udp -m udp --dport ntp -j RETURN
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${GREEN_DEV} -p udp -m udp --d=
port ntp -j REDIRECT
>>>>> +fi
>>>>> +
>>>>> +# Force DNS REDIRECTs on BLUE (udp, 123)
>>>>> +if [ "$NTP_FORCE_ON_BLUE" =3D=3D "on" ]; then
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -d ${BLUE_ADDRESS}=
 -p udp -m udp --dport ntp -j RETURN
>>>>> +	iptables -t nat -A DNS_NTP_REDIRECT -i ${BLUE_DEV} -p udp -m udp --dp=
ort ntp -j REDIRECT
>>>>> +fi
>>>>> +
>>>>> +# End $rc_base/init.d/dnsntp
>>>>> diff --git a/src/initscripts/system/firewall b/src/initscripts/system/f=
irewall
>>>>> index 1e558ee86..047946a86 100644
>>>>> --- a/src/initscripts/system/firewall
>>>>> +++ b/src/initscripts/system/firewall
>>>>> @@ -218,7 +218,7 @@ iptables_init() {
>>>>>    	iptables -A INPUT -j LOCATIONBLOCK
>>>>>    	iptables -A FORWARD -j LOCATIONBLOCK
>>>>>    -	# trafic from ipsecX/TUN/TAP interfaces, before "-i GREEN_DEV" acc=
ept everything
>>>>> +	# traffic from ipsecX/TUN/TAP interfaces, before "-i GREEN_DEV" accep=
t everything
>>>>>    	iptables -N IPSECINPUT
>>>>>    	iptables -N IPSECFORWARD
>>>>>    	iptables -N IPSECOUTPUT
>>>>> @@ -242,6 +242,10 @@ iptables_init() {
>>>>>    	iptables -N WIRELESSFORWARD
>>>>>    	iptables -A FORWARD -m conntrack --ctstate NEW -j WIRELESSFORWARD
>>>>>    +	# Redirecting DNS and NTP requests
>>>>> +	iptables -t nat -N DNS_NTP_REDIRECT
>>>>> +	iptables -t nat -A PREROUTING -j DNS_NTP_REDIRECT
>>>>> +
>>>>>    	# OpenVPN
>>>>>    	iptables -N OVPNINPUT
>>>>>    	iptables -A INPUT -j OVPNINPUT
>>>>> @@ -320,6 +324,9 @@ iptables_init() {
>>>>>    	# run captivectrl
>>>>>    	/usr/local/bin/captivectrl
>>>>>    +	# run dnsntpctrl
>>>>> +	/usr/local/bin/dnsntpctrl
>>>>> +
>>>>>    	# POLICY CHAIN
>>>>>    	iptables -N POLICYIN
>>>>>    	iptables -A INPUT -j POLICYIN
>>>>> diff --git a/src/misc-progs/Makefile b/src/misc-progs/Makefile
>>>>> index 7c3ef7529..229d122d6 100644
>>>>> --- a/src/misc-progs/Makefile
>>>>> +++ b/src/misc-progs/Makefile
>>>>> @@ -30,7 +30,7 @@ SUID_PROGS =3D squidctrl sshctrl ipfirereboot \
>>>>>    	wirelessctrl getipstat qosctrl \
>>>>>    	redctrl syslogdctrl extrahdctrl sambactrl \
>>>>>    	smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
>>>>> -	setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \
>>>>> +	setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes dn=
sntpctrl \
>>>>>    	getconntracktable wirelessclient torctrl ddnsctrl unboundctrl \
>>>>>    	captivectrl
>>>>>    diff --git a/src/misc-progs/dnsntpctrl.c b/src/misc-progs/dnsntpctrl=
.c
>>>>> new file mode 100644
>>>>> index 000000000..f2a3b89e3
>>>>> --- /dev/null
>>>>> +++ b/src/misc-progs/dnsntpctrl.c
>>>>> @@ -0,0 +1,19 @@
>>>>> +/* This file is part of the IPFire Firewall.
>>>>> + *
>>>>> + * This program is distributed under the terms of the GNU General Publ=
ic
>>>>> + * Licence.  See the file COPYING for details.
>>>>> + *
>>>>> + */
>>>>> +
>>>>> +#include <stdlib.h>
>>>>> +#include "setuid.h"
>>>>> +
>>>>> +int main(void)
>>>>> +{
>>>>> +	if (!(initsetuid()))
>>>>> +		exit(1);
>>>>> +
>>>>> +	safe_system("/etc/rc.d/init.d/dnsntp >/dev/null 2>&1");
>>>>> +
>>>>> +	return 0;
>>>>> +}
>=20

--===============4879560201745018057==--