Discussion:
[Dnsmasq-discuss] DNS TTL for responses based on DHCP leases
Lorin Weilenmann
2016-02-11 07:54:45 UTC
Permalink
Hi list,

Currently, dnsmasq sets the DNS TTL for queries which it answers from local
sources to 0 (or the value of --local-ttl). While this may be okay for
entries out of /etc/hosts and addn-host files, it seems at least
questionable for DHCP leases.

IMHO, a good DNS TTL for a DHCP lease would be the remaining duration of
the lease (or half of that, since most DHCP clients renew their leases when
half the lease time expired). Because many DHCP clients don't send a
DHCPRELEASE when they disconnect from the network (either because they
can't in case of wifi, or because they just don't), the DHCP server usually
has no way invalidating a lease before it expires anyway.

I'd also love to have an option to set a DNS TTL per host-file entry, i.e.
with a format like this:
1.2.3.4 host.domain.tld #3600
which would mean if the host line is followed by a comment which is a
number, use that number in seconds as TTL for DNS responses.

The reason behind my request is the following: I have significant LAN
traffic based on DNS, which results in unnecessary load on dnsmasq as it
always responds with TTL 0 and thus prevents local caching. This also means
that the entire LAN immediately "dies" if I the dnsmasq box isn't available
even for a very short period (reboot). Setting --local-ttl is also not a
feasible in my case because I have a backup internet connection, and one of
my /etc/hosts entries points to the current external IP. This DNS response
should go out with TTL 0. This way, the LAN clients can receive the new
external IP immediately. By increasing --local-ttl, they'd get the "news"
only after local-ttl seconds.

Any thoughts on my suggestions?

Thanks,
Lorin
Simon Kelley
2016-02-12 16:03:59 UTC
Permalink
This post might be inappropriate. Click to display it.
Lorin Weilenmann
2016-02-12 21:56:47 UTC
Permalink
Hi Simon,

Thanks for taking the time and for your reply!
Post by Simon Kelley
You've almost answered your own question: the reason that the TTL is
zero unless over-ridden is that a client can send a DHCP-RELEASE at
any time: just because a DHCP lease of length n seconds currently
exists, that doesn't guarantee that the lease will not be terminated
long before, and the associated name and/or address re-used.
This is a possible scenario, but a DNS TTL doesn't guarantee that the
record won't change for TTL seconds (otherwise, you could never change a
DNS record with TTL > 0 :-) ). But even if a client sends a DHCP-RELEASE
it's unlikely for the IP to be assigned to another client until the dns ttl
expires - at least in environments where the dhcp pool is sufficiently
large. A dns client with a cached entry that has been released would try to
connect to a non-responsive IP, rather than getting nxdomain from dnsmasq,
which usually results in the same behavior. Nevertheless, I agree that my
argument is far perfect.
Post by Simon Kelley
There's
another case where this can happen, which is if a new DHCP lease
arrives, declaring that the client has a name which is already in use
with another DHCP lease. In that case the new lease "steals" the name
from the existing lease, and an IP-name association is abruptly ended
with no warning.
This might lead to a delta between the cache on the client and dnsmasq, but
the client's record is still valid (as in: a host with the given fqdn
responds to the IP in the cache). Its the nature of caches to produce
results which may differ from the actual "source of truth".

However, your proposal to my next point got me thinking: What would you say
about extending the --dhcp-range option to the following:

--dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease
time>[,<dns ttl>]]

(note that <dns ttl> could only be specified if <lease time> was given
because otherwise it would not be possible to differentiate between the two)

Alternatively, there could be an new option:

--dhcp-dns-ttl=[tag:<tag>,[tag:<tag>,]]<dns ttl>

The actual TTL in DNS answers would be calculated as:
max(<--local-ttl>, <dns ttl> + <time lease was handed out> - <now>).
Alternatively (if that's easier), you could just put the DHCP fqdn into the
DNS cache with TTL <dns ttl>. Once once the cache entry expires, dnsmasq
would return to resolve the name from "local sources" and use a TTL
speficied in --local-ttl. (This would only work if dnsmasq first looks in
the cache for a dns result, which I don't know).
Post by Simon Kelley
Rather than re-purpose comments in /etc/hosts files, how about
extending the dnsmasq host-record config option? [...]
--host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>],[TTL]
would be easy, since distinguishing an IPv4 pr IPv6 address from a TTL
is deterministic.
I like this proposal very much. It's much better than parsing comments of a
hosts file.

Cheers,
Lorin
Simon Kelley
2016-02-15 20:10:24 UTC
Permalink
Post by Lorin Weilenmann
Hi Simon,
Thanks for taking the time and for your reply!
Post by Simon Kelley
You've almost answered your own question: the reason that the TTL is
zero unless over-ridden is that a client can send a DHCP-RELEASE at
any time: just because a DHCP lease of length n seconds currently
exists, that doesn't guarantee that the lease will not be terminated
long before, and the associated name and/or address re-used.
This is a possible scenario, but a DNS TTL doesn't guarantee that the
record won't change for TTL seconds (otherwise, you could never change a
DNS record with TTL > 0 :-) ). But even if a client sends a DHCP-RELEASE
it's unlikely for the IP to be assigned to another client until the dns ttl
expires - at least in environments where the dhcp pool is sufficiently
large. A dns client with a cached entry that has been released would try to
connect to a non-responsive IP, rather than getting nxdomain from dnsmasq,
which usually results in the same behavior. Nevertheless, I agree that my
argument is far perfect.
For static DNS entries, it's usual to reduce the TTL before making
changes so thatchanges propagate rapidly. The case where a name is
transferred to a new DHCP lease could certainly leave clients in an
inconsistent state for some time.
Post by Lorin Weilenmann
Post by Simon Kelley
There's
another case where this can happen, which is if a new DHCP lease
arrives, declaring that the client has a name which is already in use
with another DHCP lease. In that case the new lease "steals" the name
from the existing lease, and an IP-name association is abruptly ended
with no warning.
This might lead to a delta between the cache on the client and dnsmasq, but
the client's record is still valid (as in: a host with the given fqdn
responds to the IP in the cache). Its the nature of caches to produce
results which may differ from the actual "source of truth".
However, your proposal to my next point got me thinking: What would you say
--dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease
time>[,<dns ttl>]]
(note that <dns ttl> could only be specified if <lease time> was given
because otherwise it would not be possible to differentiate between the two)
--dhcp-dns-ttl=[tag:<tag>,[tag:<tag>,]]<dns ttl>
max(<--local-ttl>, <dns ttl> + <time lease was handed out> - <now>).
Alternatively (if that's easier), you could just put the DHCP fqdn into the
DNS cache with TTL <dns ttl>. Once once the cache entry expires, dnsmasq
would return to resolve the name from "local sources" and use a TTL
speficied in --local-ttl. (This would only work if dnsmasq first looks in
the cache for a dns result, which I don't know).
Post by Simon Kelley
Rather than re-purpose comments in /etc/hosts files, how about
extending the dnsmasq host-record config option? [...]
--host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>],[TTL]
would be easy, since distinguishing an IPv4 pr IPv6 address from a TTL
is deterministic.
I like this proposal very much. It's much better than parsing comments of a
hosts file.
I'll have a go at implementing it ASAP


Cheers,

Simon.
Simon Kelley
2016-02-24 21:30:30 UTC
Permalink
I just pushed changes to git which

1) Support the TTL parameter in --host-record and --cname

2) Add --dhcp-ttl, which overrides --local-ttl but only for DHCP-derived
information.

Between those, I think you should be able configure something suitable.


Cheers,

Simon.
Post by Lorin Weilenmann
Hi Simon,
Thanks for taking the time and for your reply!
Post by Simon Kelley
You've almost answered your own question: the reason that the TTL is
zero unless over-ridden is that a client can send a DHCP-RELEASE at
any time: just because a DHCP lease of length n seconds currently
exists, that doesn't guarantee that the lease will not be terminated
long before, and the associated name and/or address re-used.
This is a possible scenario, but a DNS TTL doesn't guarantee that the
record won't change for TTL seconds (otherwise, you could never change a
DNS record with TTL > 0 :-) ). But even if a client sends a DHCP-RELEASE
it's unlikely for the IP to be assigned to another client until the dns ttl
expires - at least in environments where the dhcp pool is sufficiently
large. A dns client with a cached entry that has been released would try to
connect to a non-responsive IP, rather than getting nxdomain from dnsmasq,
which usually results in the same behavior. Nevertheless, I agree that my
argument is far perfect.
Post by Simon Kelley
There's
another case where this can happen, which is if a new DHCP lease
arrives, declaring that the client has a name which is already in use
with another DHCP lease. In that case the new lease "steals" the name
from the existing lease, and an IP-name association is abruptly ended
with no warning.
This might lead to a delta between the cache on the client and dnsmasq, but
the client's record is still valid (as in: a host with the given fqdn
responds to the IP in the cache). Its the nature of caches to produce
results which may differ from the actual "source of truth".
However, your proposal to my next point got me thinking: What would you say
--dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease
time>[,<dns ttl>]]
(note that <dns ttl> could only be specified if <lease time> was given
because otherwise it would not be possible to differentiate between the two)
--dhcp-dns-ttl=[tag:<tag>,[tag:<tag>,]]<dns ttl>
max(<--local-ttl>, <dns ttl> + <time lease was handed out> - <now>).
Alternatively (if that's easier), you could just put the DHCP fqdn into the
DNS cache with TTL <dns ttl>. Once once the cache entry expires, dnsmasq
would return to resolve the name from "local sources" and use a TTL
speficied in --local-ttl. (This would only work if dnsmasq first looks in
the cache for a dns result, which I don't know).
Post by Simon Kelley
Rather than re-purpose comments in /etc/hosts files, how about
extending the dnsmasq host-record config option? [...]
--host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>],[TTL]
would be easy, since distinguishing an IPv4 pr IPv6 address from a TTL
is deterministic.
I like this proposal very much. It's much better than parsing comments of a
hosts file.
Cheers,
Lorin
_______________________________________________
Dnsmasq-discuss mailing list
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Lorin Weilenmann
2016-02-25 11:13:13 UTC
Permalink
Hi Simon,

Thanks a lot for your effort! I've just built the latest source from git
and I'm quite happy with the changes, i.e. I can confirm that --dhcp-ttl
and the new host-record additions work well for me.

I've noticed that replies which get their TTL from the dhcp-ttl option
always get the TTL specified in dhcp-ttl. I'd prefer something like max(0,
min(<dhcp-ttl>, <lease-expire-time> - <now>)). Otherwise, dns might hand
out a high TTL for a dhcp-lease which expires one second later.

Do you think that's feasible?

Cheers,
Lorin
Post by Simon Kelley
I just pushed changes to git which
1) Support the TTL parameter in --host-record and --cname
2) Add --dhcp-ttl, which overrides --local-ttl but only for DHCP-derived
information.
Between those, I think you should be able configure something suitable.
Cheers,
Simon.
Post by Lorin Weilenmann
Hi Simon,
Thanks for taking the time and for your reply!
Post by Simon Kelley
You've almost answered your own question: the reason that the TTL is
zero unless over-ridden is that a client can send a DHCP-RELEASE at
any time: just because a DHCP lease of length n seconds currently
exists, that doesn't guarantee that the lease will not be terminated
long before, and the associated name and/or address re-used.
This is a possible scenario, but a DNS TTL doesn't guarantee that the
record won't change for TTL seconds (otherwise, you could never change a
DNS record with TTL > 0 :-) ). But even if a client sends a DHCP-RELEASE
it's unlikely for the IP to be assigned to another client until the dns
ttl
Post by Lorin Weilenmann
expires - at least in environments where the dhcp pool is sufficiently
large. A dns client with a cached entry that has been released would try
to
Post by Lorin Weilenmann
connect to a non-responsive IP, rather than getting nxdomain from
dnsmasq,
Post by Lorin Weilenmann
which usually results in the same behavior. Nevertheless, I agree that my
argument is far perfect.
Post by Simon Kelley
There's
another case where this can happen, which is if a new DHCP lease
arrives, declaring that the client has a name which is already in use
with another DHCP lease. In that case the new lease "steals" the name
from the existing lease, and an IP-name association is abruptly ended
with no warning.
This might lead to a delta between the cache on the client and dnsmasq,
but
Post by Lorin Weilenmann
the client's record is still valid (as in: a host with the given fqdn
responds to the IP in the cache). Its the nature of caches to produce
results which may differ from the actual "source of truth".
However, your proposal to my next point got me thinking: What would you
say
--dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease
Post by Lorin Weilenmann
time>[,<dns ttl>]]
(note that <dns ttl> could only be specified if <lease time> was given
because otherwise it would not be possible to differentiate between the
two)
Post by Lorin Weilenmann
--dhcp-dns-ttl=[tag:<tag>,[tag:<tag>,]]<dns ttl>
max(<--local-ttl>, <dns ttl> + <time lease was handed out> - <now>).
Alternatively (if that's easier), you could just put the DHCP fqdn into
the
Post by Lorin Weilenmann
DNS cache with TTL <dns ttl>. Once once the cache entry expires, dnsmasq
would return to resolve the name from "local sources" and use a TTL
speficied in --local-ttl. (This would only work if dnsmasq first looks in
the cache for a dns result, which I don't know).
Post by Simon Kelley
Rather than re-purpose comments in /etc/hosts files, how about
extending the dnsmasq host-record config option? [...]
--host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>],[TTL]
Post by Lorin Weilenmann
Post by Simon Kelley
would be easy, since distinguishing an IPv4 pr IPv6 address from a TTL
is deterministic.
I like this proposal very much. It's much better than parsing comments
of a
Post by Lorin Weilenmann
hosts file.
Cheers,
Lorin
_______________________________________________
Dnsmasq-discuss mailing list
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
_______________________________________________
Dnsmasq-discuss mailing list
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Simon Kelley
2016-02-26 21:59:50 UTC
Permalink
Post by Lorin Weilenmann
Hi Simon,
Thanks a lot for your effort! I've just built the latest source
from git and I'm quite happy with the changes, i.e. I can confirm
that --dhcp-ttl and the new host-record additions work well for
me.
I've noticed that replies which get their TTL from the dhcp-ttl
option always get the TTL specified in dhcp-ttl. I'd prefer
something like max(0, min(<dhcp-ttl>, <lease-expire-time> -
<now>)). Otherwise, dns might hand out a high TTL for a dhcp-lease
which expires one second later.
Do you think that's feasible?
No sooner said, than done. Seems a sensible addition.

Cheers,

Simon.
Post by Lorin Weilenmann
Cheers, Lorin
Post by Simon Kelley
I just pushed changes to git which
1) Support the TTL parameter in --host-record and --cname
2) Add --dhcp-ttl, which overrides --local-ttl but only for
DHCP-derived information.
Between those, I think you should be able configure something
suitable.
Cheers, crecp->ttd - now
Simon.
Post by Lorin Weilenmann
Hi Simon,
Thanks for taking the time and for your reply!
Post by Simon Kelley
You've almost answered your own question: the reason that
the TTL is zero unless over-ridden is that a client can
send a DHCP-RELEASE at any time: just because a DHCP lease
of length n seconds currently exists, that doesn't
guarantee that the lease will not be terminated long
before, and the associated name and/or address re-used.
This is a possible scenario, but a DNS TTL doesn't guarantee
that the record won't change for TTL seconds (otherwise, you
could never change a DNS record with TTL > 0 :-) ). But even if
a client sends a DHCP-RELEASE it's unlikely for the IP to be
assigned to another client until the dns
ttl
Post by Lorin Weilenmann
expires - at least in environments where the dhcp pool is
sufficiently large. A dns client with a cached entry that has
been released would try
to
Post by Lorin Weilenmann
connect to a non-responsive IP, rather than getting nxdomain
from
dnsmasq,
Post by Lorin Weilenmann
which usually results in the same behavior. Nevertheless, I
agree that my argument is far perfect.
Post by Simon Kelley
There's another case where this can happen, which is if a
new DHCP lease arrives, declaring that the client has a
name which is already in use with another DHCP lease. In
that case the new lease "steals" the name from the existing
lease, and an IP-name association is abruptly ended with no
warning.
This might lead to a delta between the cache on the client and dnsmasq,
but
Post by Lorin Weilenmann
the client's record is still valid (as in: a host with the
given fqdn responds to the IP in the cache). Its the nature of
caches to produce results which may differ from the actual
"source of truth".
However, your proposal to my next point got me thinking: What would you
say
--dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-a
ddr>][,<mode>][,<netmask>[,<broadcast>]][,<lease
time>[,<dns ttl>]]
Post by Lorin Weilenmann
Post by Simon Kelley
Post by Lorin Weilenmann
(note that <dns ttl> could only be specified if <lease time>
was given because otherwise it would not be possible to
differentiate between the
two)
Post by Lorin Weilenmann
--dhcp-dns-ttl=[tag:<tag>,[tag:<tag>,]]<dns ttl>
max(<--local-ttl>, <dns ttl> + <time lease was handed out> -
<now>). Alternatively (if that's easier), you could just put
the DHCP fqdn into
the
Post by Lorin Weilenmann
DNS cache with TTL <dns ttl>. Once once the cache entry
expires, dnsmasq would return to resolve the name from "local
sources" and use a TTL speficied in --local-ttl. (This would
only work if dnsmasq first looks in the cache for a dns result,
which I don't know).
Post by Simon Kelley
Rather than re-purpose comments in /etc/hosts files, how
about extending the dnsmasq host-record config option?
[...]
--host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>],[
TTL]
would be easy, since distinguishing an IPv4 pr IPv6 address from a TTL
Post by Lorin Weilenmann
Post by Simon Kelley
Post by Lorin Weilenmann
Post by Simon Kelley
is deterministic.
I like this proposal very much. It's much better than parsing comments
of a
Post by Lorin Weilenmann
hosts file.
Cheers, Lorin
_______________________________________________ Dnsmasq-discuss
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
_______________________________________________
Post by Lorin Weilenmann
Post by Simon Kelley
Dnsmasq-discuss mailing list
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
_______________________________________________ Dnsmasq-discuss
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Continue reading on narkive:
Loading...