dnsmasq: how to increase TTL?

Is there a way to override & increase the received TTL from an upstream DNS server?

Is there a configuration parameter in dnsmasq for this?


Basing my answer on your comments to Gareth (which really should be incorporated into your question), I would say that the most likely causes of your problem are:

  1. You're not actually using the cache you think you are, or
  2. The TTLs for the site you're visiting are set quite low, normally for a reason, and there's nothing reasonable you can do about it (except perhaps identify the root cause of the frequent DNS lookup failures and fix them yourself (if, for example, the cause was a congested local Internet connection) or petition the entity responsible to have them fixed (if, for example, the problem was that the zone is delegated to a flaky authoritative DNS server))

Dnsmasq has a --min-cache-ttl=[seconds] parameter, where seconds ≤ 3600 (1 hour).


You can actually bypass the 3600 second --min-cache-ttl check by exploiting an integer overflow bug in the dnsmasq C source code, without any need for recompiling. Here is a value which works:

Via CLI: --min-cache-ttl=6442450943

Via dnsmasq.conf: min-cache-ttl=6442450943

Why does this work? Well, the dnsmasq C code specifies a signed integer value constant of 3600 seconds, which is compared and checked versus what the user specifies as an override value. If the value is greater than 3600, then the user input will be disregarded and the constant 3600 will be used instead. This override value is also a signed int, but a few lines later in the code the input ttl value is cast to an unsigned long int when initializing the daemon.

At first glance, you might wonder whe we don't just set the value to be -2 billion in the input or config file. Well, there is an initial dnsmasq input check that will abort early and terminate. However, if we wrap the integer over +4 billion, we will start back at zero. Add another +2 billion + 1 to that and we can wrap back to an effective negative number while still bypassing the initial check.

So, why does this work? Because signed integer ranges go from roughly -2 billion to +2 billion, while unsigned integers range from 0 to +4 billion. We need to get the value to wrap around at the roughly +2 billion mark to be interpreted as a negative value by the dnsmasq check following input parsing. In essence, the check for ttl > 3600 will pass because the value is interpreted negatively as -2 billion. -2 billion is certainly < 3600. But when the second part of the code goes to convert the -2 billion, it will end up converting our input ttl into the equivalent of roughly 2^31 + 1 (unsigned), instead of -2^31 + 1 (signed).

Of course, you can only specify really large ttl values this way, and this may not be useful to anyone because such ttl values are not very reasonable at all. But it is a neat trick (dnsmasq bug). Hope this helps someone even if it is only useful for debugging or messing around as a temporary solution. Feel free to comment if this does or doesn't work for your situation. Enjoy! :)


Do you mean the TTL for a negative response from an upstream server ? That's controlled by the --neg-ttl parameter:

--neg-ttl= Negative replies from upstream servers normally contain time-to-live information in SOA records which dnsmasq uses for caching. If the replies from upstream servers omit this information, dnsmasq does not cache the reply. This option gives a default value for time-to-live (in seconds) which dnsmasq uses to cache negative replies even in the absence of an SOA record.