Discussion:
[Dnsmasq-discuss] [Feature Request] Tagged server and address configuration
M. Buecher
2018-11-19 21:07:50 UTC
Permalink
Hello Simon and dnsmasq fellows,

I blacklist several domains via host files and wanted to skip the
blacklist for my testing client.
Unfortunately I couldn't find a solution for this in the man page, or
maybe I just didn't see the correct config combination.
Or did I miss a way to configure this with the existing features?


So I came up with the idea of tag-matching server and address
configuration, like...
--server=[tag:<tag>[,tag:<tag>],][/[<domain>]/[domain/]][<ipaddr>[#<port>][@<source-ip>|<interface>[#<port>]]
--address=[tag:<tag>[,tag:<tag>],]/<domain>[/<domain>...]/[<ipaddr>]

This would provide a highly flexible way to blacklist/whitelist domains
for specific clients.
But I assume it may be an ugly coding hell to implement.


Kind regards
Maddes
Simon Kelley
2018-11-22 20:24:56 UTC
Permalink
Post by M. Buecher
Hello Simon and dnsmasq fellows,
I blacklist several domains via host files and wanted to skip the
blacklist for my testing client.
Unfortunately I couldn't find a solution for this in the man page, or
maybe I just didn't see the correct config combination.
Or did I miss a way to configure this with the existing features?
So I came up with the idea of tag-matching server and address
configuration, like...
--address=[tag:<tag>[,tag:<tag>],]/<domain>[/<domain>...]/[<ipaddr>]
This would provide a highly flexible way to blacklist/whitelist  domains
for specific clients.
But I assume it may be an ugly coding hell to implement.
The problem lies in the fact that there's nothing in the DNS part of
dnsmasq to determine the tags - the taq-set that's used in the DHCP part
of dnsmasq is determined dynamically during each DHCP transaction:
there's no way to make it long-lived and associate it with DNS request
that arrives later.


Cheers,

Simon.
Post by M. Buecher
Kind regards
Maddes
_______________________________________________
Dnsmasq-discuss mailing list
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
M. Buecher
2018-11-22 21:06:44 UTC
Permalink
Post by Simon Kelley
Post by M. Buecher
Hello Simon and dnsmasq fellows,
I blacklist several domains via host files and wanted to skip the
blacklist for my testing client.
Unfortunately I couldn't find a solution for this in the man page, or
maybe I just didn't see the correct config combination.
Or did I miss a way to configure this with the existing features?
So I came up with the idea of tag-matching server and address
configuration, like...
--address=[tag:<tag>[,tag:<tag>],]/<domain>[/<domain>...]/[<ipaddr>]
This would provide a highly flexible way to blacklist/whitelist  domains
for specific clients.
But I assume it may be an ugly coding hell to implement.
The problem lies in the fact that there's nothing in the DNS part of
dnsmasq to determine the tags - the taq-set that's used in the DHCP part
there's no way to make it long-lived and associate it with DNS request
that arrives later.
Cheers,
Simon.
Thanks for the info.

Right now I'm trying to find out how to run multiple dnsmasq instances
for different interfaces on Debian with systemd.
The second interface shall be a virtual one on the real one with a
different ip address, so that I can distribute "a different DNS server"
to my test client.

Thanks for your time
Maddes
M. Buecher
2018-12-01 12:20:58 UTC
Permalink
Hello Simon,

on my first tries to start multiple dnsmasq instances on Debian 9
"Stretch" with systemd I faced several issues and created Debian bug
report #914305 [1].
Yesterday I finally managed to spend several hours on the issue and
found a clean solution for it.
While preparing the text for the bug report I recognized that you're the
maintainer of the Debian packages, so I decided to write to the dnsmasq
mailing list first.

[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=914305



systemd unit files [2] allow to be used for multiple instances when the
service unit file name ends with the at symbol (@).
Then the service can be enabled with an instance name following the at
symbol, e.g. `systemctl enable ***@main.service`.
The instance name is available in an escaped format in variable %i
(lower case) when the unit file is processed.
The attached unit file ***@.service passes the escaped instance name
to the init.d script (minor changes to the code plus `mv -v
/lib/systemd/system/dnsmasq.service
/lib/systemd/system/***@.service`).

The 2nd attached file is the updated init.d script for dnsmasq.
It now recognizes the instance name via the second script paramater and
uses it wherever needed or possible (default file, pid file, resolvconf
protocol, log entries).

Additionally three special cases had to be handled when running multiple
instances of dnsmasq:
a) The original systemd unit file wants to check the configuration
before starting the service but does not honor the settings from the
default file (conf file and dir).
Therefore the option checkconfig was added to the init.d script.
I don't know if there's a common SysInit V standard name for such a
function [3].
b) `mkdir /run/dnsmasq` in the init.d script can fail as unit files are
run in parallel, so the directory has to be checked again if mkdir
failed.
c) Only one dnsmasq instance should be the dns resolver for the local
system and should bind to localhost.
Therefore revived DNSMASQ_EXCEPT="lo" in the default file (3rd
attached file).

Additional changes to the files are typo corrections.

[2] https://www.freedesktop.org/software/systemd/man/systemd.unit.html
[3]
https://www.debian.org/doc/debian-policy/ch-opersys.html#writing-the-scripts



For testing I installed openresolv and dnsmasq on latest Debian 9
"Stretch" and created some virtual network interfaces via systemd [4].
The main dnsmasq instance shall run on the real NIC while special
instances shall run on the extra virtual NICs (dnsextra*).

Stopped and disabled the original service from the Debian dnsmasq
package:
`systemctl stop dnsmasq.service`
`systemctl disable dnsmasq.service`
`systemctl status dnsmasq.service`

Prepared dnsmasq systemd unit file for instances by renaming and
updating it:
`mv -v /lib/systemd/system/dnsmasq.service
/lib/systemd/system/***@.service`

As instance enabled systemd unit files have to be used with an instance
name I decided to name the default dnsmasq instance simply "main".
Not to break SysInit V compatibility a symbol link was used for the
"renaming" of the default file.
`ln -s -T dnsmasq /etc/default/dnsmasq.main`
(P.S. Other idea would be to default INSTANCE in init.d to 'main' when
instance name not given.)

Updated also init.d script and normal default file.

Then prepared two dnsmasq instances:
1. Default file for main instance (/etc/default/dnsmasq.main)
Changed to DNSMASQ_OPTS="--bind-dynamic --except-interface=dnsextra*"
This way it will avoid binding to the extra virtual NICs while still
recognizing new addresses and other new NICs, and it will also be the
DNS resolver for the local system.

2. New default file for first extra instance
(/etc/default/dnsmasq.extra01)
Copied from default file of main instance via `cp /etc/default/dnsmasq
/etc/default/dnsmasq.extra01`
Changed the following settings for this extra instance:
* DNSMASQ_OPTS="--bind-dynamic --interface=dnsextra01
--address=/heise.de/192.168.0.250"
Binds to one explicit interface while still recognizing new addresses.
One modified address resolution for testing with dig.
* IGNORE_RESOLVCONF=yes
Always using /etc/resolv.conf therefore either using the dnsmasq main
instance (if it is started) as upstream dns server or the upstream
server from resolvconf (e.g. via DHCP).
* DNSMASQ_EXCEPT="lo"
Avoid binding to localhost and also not being used as the DNS resolver
for the local system.

With this setup I could start/stop any dnsmasq instance while keeping a
working DNS setup.
Additionally I could assign an explicit dnsmasq instance to any dhcp
client.

[4] https://gist.github.com/maddes-b/e487d1f95f73f5d40805315f0232d5d9



I hope that I explained everything understandably, completely and in
correct English.
Any feedback is welcome and it would be great to see this in Debian 10
:)

Kind regards
Maddes
Geert Stappers
2018-12-01 15:19:37 UTC
Permalink
[Unit]
Description=dnsmasq (%i) - A lightweight DHCP and caching DNS server
Requires=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
The "Wants" and the "Before" have the same targets.
That feels odd to me.



Groeten
Geert Stappers
--
Leven en laten leven
M. Buecher
2018-12-01 22:24:00 UTC
Permalink
Post by Geert Stappers
[Unit]
Description=dnsmasq (%i) - A lightweight DHCP and caching DNS server
Requires=network.target
Wants=nss-lookup.target
Before=nss-lookup.target
The "Wants" and the "Before" have the same targets.
That feels odd to me.
Wants= is a weaker version of Requires=, which tries to start those
additional services but a failure of them doesn't stop the dnsmasq
service from starting.

Before= just manages the start order of the services.

My changes only added support for instances and didn't change the
dependencies.

Thanks for checking
Maddes
M. Buecher
2018-12-03 19:27:34 UTC
Permalink
I spent some time on how to keep backward compatibility for current
configurations.
1. An updated dnsmasq.service file for the main/default/standard
"instance", that reflects the fix for checking the configuration (see
attached file).
instances.
This way nothing would change for people running just a single dnsmasq
instance. No need to rename or sym-link /etc/default/dnsmasq to
dnsmasq.main (or similar).
Still people could easily create extra instances with the new
/etc/default/dnsmasq.<instance> file.
Got some time to look at the upstream repo.
Updated init.d script to current state plus renamed files for upstream
repo.

Continue reading on narkive:
Loading...