GranularServeExpired

From kitz wiki
Jump to: navigation, search

Since pfSense 2.8.1. The unbound DNS resolver that is distributed in the firewall has a new default behaviour for the serve expired feature, this is because a new RFC 8767 was drawn up which now has reccomended practice of using the feature for serving stale queries only, so the default value now makes the feature only serve expired queries from the cache if a upstream DNS lookup fails to respond within 1800ms.

If you wish to only utilise the new default behaviour, then there is no need for this patch, if you wish to preserve the old behaviour to maximise DNS query performance, then this patch will alow you to choose between the two behaviours, as well as keeping serve expired disabled.

This patch wont allow you to configure a custom timeout, to do that, select the new behaviour which wont set the variable, just relying on the default, and then can set it in the custom box on advanced settings as an override, I deliberatly designed the patch this way in case there is a desire to set a custom timeout value.

---

Paste the below code into the Patch Contents box.

Add a description such as 'Unbound new serve expired toggle' in the Description box.

Set Path Strip Count to '0'.

Base Directory to '/'

--- /etc/inc/unbound.inc        2025-09-21 19:05:38.753690000 +0100
+++ /etc/inc/unbound.inc   2025-09-21 20:35:22.638223000 +0100
@@ -376,7 +376,14 @@
        $harden_dnssec_stripped = isset($unboundcfg['dnssecstripped']) ? "yes" : "no";
        $prefetch = isset($unboundcfg['prefetch']) ? "yes" : "no";
        $prefetch_key = isset($unboundcfg['prefetchkey']) ? "yes" : "no";
-       $dns_record_cache = isset($unboundcfg['dnsrecordcache']) ? "yes" : "no";
+        if (is_null($unboundcfg['dnsrecordcache']) || ($unboundcfg['dnsrecordcache'] == '0')) {
+                $dns_record_cache = "no";
+        } else {
+                $dns_record_cache = "yes";
+        }
+        if ($unboundcfg['dnsrecordcache'] == '1') {
+                $dns_record_cache_ttl = "serve-expired-client-timeout: 0";
+        }
        $sock_queue_timeout = empty($unboundcfg['sock_queue_timeout']) ? '0' : $unboundcfg['sock_queue_timeout'];
        $aggressivensec = isset($unboundcfg['aggressivensec']) ? "yes" : "no";
        $outgoing_num_tcp = isset($unboundcfg['outgoing_num_tcp']) ? $unboundcfg['outgoing_num_tcp'] : "10";
@@ -531,6 +538,7 @@
 prefetch-key: {$prefetch_key}
 use-caps-for-id: {$use_caps}
 serve-expired: {$dns_record_cache}
+{$dns_record_cache_ttl}
 sock-queue-timeout: {$sock_queue_timeout}
 aggressive-nsec: {$aggressivensec}

--- /usr/local/www/services_unbound_advanced.php       2025-09-21 19:05:38.754169000 +0100
+++ /usr/local/www/services_unbound_advanced.php 2025-09-21 20:43:39.841217000 +0100
@@ -49,7 +49,7 @@
 $pconfig['prefetch'] = config_path_enabled('unbound', 'prefetch');
 $pconfig['prefetchkey'] = config_path_enabled('unbound', 'prefetchkey');
 $pconfig['dnssecstripped'] = config_path_enabled('unbound', 'dnssecstripped');
-$pconfig['dnsrecordcache'] = config_path_enabled('unbound', 'dnsrecordcache');
+$pconfig['dnsrecordcache'] = config_get_path('unbound/dnsrecordcache', 0);
 $pconfig['sock_queue_timeout'] = config_get_path('unbound/sock_queue_timeout', 0);
 $pconfig['aggressivensec'] = config_path_enabled('unbound', 'aggressivensec');
 
@@ -173,11 +173,7 @@
                        } else {
                                config_del_path('unbound/dnssecstripped');
                        }
-                       if (isset($_POST['dnsrecordcache'])) {
-                               config_set_path('unbound/dnsrecordcache', true);
-                       } else {
-                               config_del_path('unbound/dnsrecordcache');
-                       }
+                       config_set_path('unbound/dnsrecordcache', $_POST['dnsrecordcache']);
                        config_set_path('unbound/sock_queue_timeout', $_POST['sock_queue_timeout']);
                        if (isset($_POST['aggressivensec'])) {
                                config_set_path('unbound/aggressivensec', true);
@@ -315,12 +311,12 @@
        $pconfig['dnssecstripped']
 ))->setHelp('If such data is absent, the zone becomes bogus. If Disabled and no DNSSEC data is received, then the zone is made insecure. Requires DNSSEC enabled. ');
 
-$section->addInput(new Form_Checkbox(
+$section->addInput(new Form_Select(
        'dnsrecordcache',
        'Serve Expired',
-       'Serve cache records even with TTL of 0',
-       $pconfig['dnsrecordcache']
-))->setHelp('When enabled, allows unbound to serve one query even with a TTL of 0, if TTL is 0 then new record will be requested in the background when the cache is served to ensure cache is updated without latency on service of the DNS request.');
+       $pconfig['dnsrecordcache'],
+       array_combine(array("0", "1", "2"), array("Off: Unbound Default", "Serve Expired/Stale - Old behaviour", "Serve Stale - RFC8767"))
+))->setHelp('When enabled, allows unbound cache to serve one query even with a TTL of 0, if TTL is 0 then new record will be requested in the background when the cache is served to ensure cache is updated without latency on service of the DNS request.');
 
 $section->addInput(new Form_Input(
         'sock_queue_timeout',