GNU bug report logs - #72083
[PATCH] Add resolvconf service

Previous Next

Package: guix-patches;

Reported by: "B. Wilson" <elaexuotee <at> wilsonb.com>

Date: Fri, 12 Jul 2024 21:40:02 UTC

Severity: normal

To reply to this bug, email your comments to 72083 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to guix-patches <at> gnu.org:
bug#72083; Package guix-patches. (Fri, 12 Jul 2024 21:40:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to "B. Wilson" <elaexuotee <at> wilsonb.com>:
New bug report received and forwarded. Copy sent to guix-patches <at> gnu.org. (Fri, 12 Jul 2024 21:40:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: "B. Wilson" <elaexuotee <at> wilsonb.com>
To: guix-patches <at> gnu.org
Subject: j
Date: Sat, 13 Jul 2024 06:39:26 +0900
* gnu/services/admin.scm (resolvconf-service-type,
resolvconf-configuration): New variables.
* doc/guix.texi (DNS Services): Document resolvconf-service-type.
---
 doc/guix.texi          | 138 +++++++++++++++++++++++++++++++
 gnu/services/admin.scm | 179 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 317 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index 5b77c84b4a..926c9e7bb9 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -33838,6 +33838,144 @@ command-line arguments to @command{dnsmasq} as a list of strings.
 @end table
 @end deftp
 
+@subsubheading Resolvconf
+
+Resolvconf acts as a mediary between supplying and consuming programs of name
+server information, allowing the contents of @code{/etc/resolv.conf} to be
+multiplexed between supporting programs.
+
+A typical use case is running a local DNS server such as @code{dnsmasq} on a
+laptop.  In this case, both the DNS server and the DHCP client content for
+control of @code{/etc/resolv.conf}.  Resolvconf allows these programs to
+cooperate together.
+
+In the parlance of resolvconf, programs which write resolver information are
+clients and programs which read said information are subscribers.  Resolvconf
+has built-in support for auto-configuring a handful of subscribers, including
+@code{dnsmasq}, @code{named}, @code{pdnsd}, and @code{unbound}.
+
+@defvar resolvconf-service-type
+
+The @code{resolvconf-service-type} can be configured via the
+@code{resolvconf-configuration} record, documented below.
+@end defvar
+
+@deftp {Data Type} resolvconf-configuration
+Available @code{resolvconf-configuration} fields are:
+
+@table @asis
+@item @code{display-number} (default: @code{0}) (type: number)
+The display number used by Xvnc.  You should set this to a number not
+already used a Xorg server.
+
+@item @code{package} (default: @code{openresolv}) (type: file-like)
+The implementing package.
+
+@item @code{resolvconf?} (default: @code{#t}) (type: boolean)
+Wether to run subscribers or not.
+
+@item @code{allow-interfaces} (default: @code{'()}) (type: list)
+Whitelist of configurable interfaces.
+
+@item @code{deny-interfaces} (default: @code{'()}) (type: list)
+Blacklist of non-configurable interfaces.
+
+@item @code{interface-order} (default: @code{'()}) (type: list)
+Interfaces to process first, in th prescribed order.  When unset, the loopback
+interfaces are assumed.
+
+@item @code{dynamic-order} (default: @code{'()}) (type: list)
+These interfaces are processed after those of @code{interface-order}, unless
+they possess a metric.
+
+@item @code{inclusive-interfaces} (default: @code{'()}) (type: list)
+Ignore any exclusive marking on these interfaces.  This can be useful when
+third-party client integrations force the exclusive option on interfaces.
+
+@item @code{local-nameservers} (default: @code{'()}) (type: list)
+Explicitly configured nameservers for this machine.
+
+@item @code{search-domains} (default: @code{'()}) (type: list)
+Search domains to prepend to the dynamically generated list.
+
+@item @code{search-domains-append} (default: @code{'()}) (type: list)
+Search domains to append to the dynamically generated list.
+
+@item @code{domain-blacklist} (default: @code{'()}) (type: list)
+Domains to completely ignore.  Accepts wildcards, e.g. @code{foo.*} blacklists
+a domain and @code{*.bar} subdomains.
+
+@item @code{name-servers} (default: @code{'()}) (type: list)
+Nameservers to prepend to the dynamically generated list.  This should be set
+to something like @code{'("::1" "127.0.0.1")} when running a local nameserver.
+
+@item @code{name-servers-append} (default: @code{'()}) (type: list)
+Nameservers to append to the dynamically generated list.
+
+@item @code{name-server-blacklist} (default: @code{'()}) (type: list)
+Nameservers to completely remove from consideration. Accepts wildcards.
+
+@item @code{private-interfaces} (default: @code{'()}) (type: list)
+These name servers will only be queried for the domains listed in the
+resolv.conf of their corresponding interface.  This is useful for VPN devices
+and domains.
+
+@item @code{public-interfaces} (default: @code{'()}) (type: list)
+Override the private designation.  This is useful in cases where third-party
+client integrations force the private option.
+
+@item @code{replace} (default: @code{'()}) (type: list)
+This is a space-separated list of replacement keywords. The syntax is
+@code{<keyword>/<match>/<replacement>}, where @code{<match>} may contain
+wildcards.
+
+@item @code{replace-sub} (default: @code{'()}) (type: list)
+This functions the same as @code{replace}, except it operates over individual
+values instead of the entire field.
+
+@item @code{enabled-subscribers} (default: @code{'()}) (type: list)
+The subscribers which should be configured.
+
+@item @code{resolv-conf} (default: @code{"/etc/resolv.conf"}) (type: string)
+Location of @code{resolv.conf}.
+
+@item @code{dnsmasq-conf} (default: @code{"/run/resolvconf/dnsmasq/dnsmasq.conf"}) (type: string)
+Location of configuration for @code{dnsmasq}'s domain-specific nameservers.
+
+@item @code{dnsmasq-resolv} (default: @code{"/run/resolvconf/dnsmasq/resolv.conf"}) (type: string)
+Global nameserver configuration for @code{dnsmasq}.
+
+@item @code{dnsmasq-pid} (default: @code{"/run/dnsmasq.pid"}) (type: string)
+Location of @code{dnsmasq} process PID file.
+
+@item @code{named-options} (default: @code{"/run/resolvconf/named/options.conf"}) (type: string)
+Location of @code{named} configuration file for global lookups.
+
+@item @code{named-zones} (default: @code{"/run/resolvconf/named/zones.conf"}) (type: string)
+Location of @code{named} configuration file for domain-specific lookups.
+
+@item @code{pdnsd-conf} (default: @code{"/run/resolvconf/pdnsd/pdnsd.conf"}) (type: string)
+Location of @code{pdnsd} configuration for adding forward domanis.
+
+@item @code{pdnsd-resolv} (default: @code{"/run/resolvconf/pdnsd/resolv.conf"}) (type: string)
+Location of @code{pdnsd} configuration for global name lookups.
+
+@item @code{pdnsd-zones} (default: @code{"/run/resolvconf/pdnsd/zones.conf"}) (type: string)
+Location of @code{pdnsd} configuration for specific and global name servers.
+
+@item @code{unbound-conf} (default: @code{"/run/resolvconf/unbound/unbound.conf"}) (type: string)
+Location of @code{unbound} nameserver configuration.
+
+@item @code{unbound-pid} (default: @code{"/run/unbound.pid"}) (type: string)
+PID file location for @code{unbound}.
+
+@item @code{extra-options} (default: @code{'()}) (type: list)
+Escape hatch for any other options.
+
+@end table
+@end deftp
+
+
 @node VNC Services
 @subsection VNC Services
 @cindex VNC (virtual network computing)
diff --git a/gnu/services/admin.scm b/gnu/services/admin.scm
index 0b325fddb1..b3db44ee02 100644
--- a/gnu/services/admin.scm
+++ b/gnu/services/admin.scm
@@ -24,6 +24,7 @@ (define-module (gnu services admin)
   #:use-module ((gnu packages base)
                 #:select (canonical-package findutils coreutils sed))
   #:use-module (gnu packages certs)
+  #:use-module (gnu packages dns)
   #:use-module (gnu packages package-management)
   #:use-module (gnu services)
   #:use-module (gnu services configuration)
@@ -38,6 +39,7 @@ (define-module (gnu services admin)
   #:use-module (guix records)
   #:use-module (srfi srfi-1)
   #:use-module (ice-9 match)
+  #:use-module (ice-9 receive)
   #:use-module (ice-9 vlist)
   #:export (%default-rotations
             %rotated-files
@@ -537,4 +539,181 @@ (define unattended-upgrade-service-type
     "Periodically upgrade the system from the current configuration.")
    (default-value (unattended-upgrade-configuration))))
 
+
+;;;
+;;; Managing /etc/resolv.conf
+;;;
+
+(define-record-type* <resolvconf-configuration>
+  resolvconf-configuration make-resolvconf-configuration
+  resolvconf-configuration?
+  (package               resolvconf-configuration-package
+                         (default openresolv))
+  (resolvconf?           resolvconf-configuration-resolvconf?
+                         (default #t))
+  (allow-interfaces      resolvconf-configuration-allow-interfaces
+                         (default '()))
+  (deny-interfaces       resolvconf-configuration-deny-interfaces
+                         (default '()))
+  (interface-order       resolvconf-configuration-interface-order
+                         (default '()))
+  (dynamic-order         resolvconf-configuration-dynamic-order
+                         (default '()))
+  (inclusive-interfaces  resolvconf-configuration-inclusive-interfaces
+                         (default '()))
+  (local-nameservers     resolvconf-configuration-local-nameservers
+                         (default '()))
+  (search-domains        resolvconf-configuration-search-domains
+                         (default '()))
+  (search-domains-append resolvconf-configuration-search-domains-append
+                         (default '()))
+  (domain-blacklist      resolvconf-configuration-domain-blacklist
+                         (default '()))
+  (name-servers          resolvconf-configuration-name-servers
+                         (default '()))
+  (name-servers-append   resolvconf-configuration-name-servers-append
+                         (default '()))
+  (name-server-blacklist resolvconf-configuration-name-server-blacklist
+                         (default '()))
+  (private-interfaces    resolvconf-configuration-private-interfaces
+                         (default '()))
+  (public-interfaces     resolvconf-configuration-public-interfaces
+                         (default '()))
+  (replace               resolvconf-configuration-replace
+                         (default '()))
+  (replace-sub           resolvconf-configuration-replace-sub
+                         (default '()))
+  (enabled-subscribers   resolvconf-configuration-enabled-subscribers
+                         (default '()))
+  (resolv-conf           resolvconf-configuration-resolv-conf
+                         (default "/etc/resolv.conf"))
+  (dnsmasq-conf          resolvconf-configuration-dnsmasq-conf
+                         (default "/run/resolvconf/dnsmasq/dnsmasq.conf"))
+  (dnsmasq-resolv        resolvconf-configuration-dnsmasq-resolv
+                         (default "/run/resolvconf/dnsmasq/resolv.conf"))
+  (dnsmasq-pid           resolvconf-configuration-dnsmasq-pid
+                         (default "/run/dnsmasq.pid"))
+  (named-options         resolvconf-configuration-named-options
+                         (default "/run/resolvconf/named/options.conf"))
+  (named-zones           resolvconf-configuration-named-zones
+                         (default "/run/resolvconf/named/zones.conf"))
+  (pdnsd-conf            resolvconf-configuration-pdnsd-conf
+                         (default "/run/resolvconf/pdnsd/pdnsd.conf"))
+  (pdnsd-resolv          resolvconf-configuration-pdnsd-resolv
+                         (default "/run/resolvconf/pdnsd/resolv.conf"))
+  (pdnsd-zones           resolvconf-configuration-pdnsd-zones
+                         (default "/run/resolvconf/pdnsd/zones.conf"))
+  (unbound-conf          resolvconf-configuration-unbound-conf
+                         (default "/run/resolvconf/unbound/unbound.conf"))
+  (unbound-pid           resolvconf-configuration-unbound-pid
+                         (default "/run/unbound.pid"))
+  (extra-options         resolvconf-configuration-extra-options
+                         (default '())))
+
+(define (resolvconf-conf-service config)
+  (match-record config <resolvconf-configuration>
+    (package resolvconf?
+     allow-interfaces deny-interfaces
+     interface-order dynamic-order
+     inclusive-interfaces
+     local-nameservers search-domains search-domains-append
+     domain-blacklist
+     name-servers name-servers-append
+     name-server-blacklist
+     private-interfaces public-interfaces
+     replace replace-sub
+     enabled-subscribers
+     resolv-conf
+     dnsmasq-conf dnsmasq-resolv dnsmasq-pid
+     named-options named-zones
+     pdnsd-conf pdnsd-resolv pdnsd-zones
+     unbound-conf unbound-pid
+     extra-options)
+    `(("resolvconf.conf"
+       ,(plain-file "resolvconf.conf"
+           (string-join
+             (filter identity
+               (append
+                 (list
+                   (if resolvconf? #f "resolvconf=NO")
+                   (format #f "resolv_conf=~s" resolv-conf))
+                 (if (memq 'dnsmasq enabled-subscribers)
+                   (list
+                     (format #f "dnsmasq_conf=~s" dnsmasq-conf)
+                     (format #f "dnsmasq_resolv=~s" dnsmasq-resolv)
+                     (format #f "dnsmasq_pid=~s" dnsmasq-pid))
+                   '())
+                 (if (memq 'named enabled-subscribers)
+                   (list
+                     (format #f "named_options=~s" named-options)
+                     (format #f "named_zones=~s" named-zones))
+                   '())
+                 (if (memq 'pdnsd enabled-subscribers)
+                   (list
+                     (format #f "pdnsd_conf=~s" pdnsd-conf)
+                     (format #f "pdnsd_resolv=~s" pdnsd-resolv)
+                     (format #f "pdnsd_zones=~s" pdnsd-zones))
+                   '())
+                 (if (memq 'unbound enabled-subscribers)
+                   (list
+                     (format #f "unbound_conf=~s" unbound-conf)
+                     (format #f "unbound_pid=~s" unbound-pid))
+                   '())
+                 (receive (vars vals)
+                   (unzip2
+                     (list
+                      `("allow_interfaces" ,allow-interfaces)
+                      `("deny_interfaces" ,deny-interfaces)
+                      `("interface_order" ,interface-order)
+                      `("dynamic_order" ,dynamic-order)
+                      `("inclusive_interfaces" ,inclusive-interfaces)
+                      `("local_nameservers" ,local-nameservers)
+                      `("search_domains" ,search-domains)
+                      `("search_domains_append" ,search-domains-append)
+                      `("domain_blacklist" ,domain-blacklist)
+                      `("name_servers" ,name-servers)
+                      `("name_servers_append" ,name-servers-append)
+                      `("name_server_blacklist" ,name-server-blacklist)
+                      `("private_interfaces" ,private-interfaces)
+                      `("public_interfaces" ,public-interfaces)
+                      `("replace" ,replace)
+                      `("replace_sub" ,replace-sub)))
+                   (map
+                     (lambda (var val)
+                       (if (nil? val) #f
+                         (format #f "~a=~s" var (string-join val))))
+                     vars vals))
+                 extra-options))
+             "\n" 'suffix))))))
+
+(define (resolvconf-subscriber-setup package)
+  #~(lambda _
+      (let ((resolvconf #$(file-append package "/sbin/resolvconf")))
+        (case (status:exit-val (system* resolvconf "-u"))
+          ((0) #t)
+          (else #f)))))
+
+(define (resolvconf-subscriber-service conf)
+  (let ((package (resolvconf-configuration-package conf))
+        (subscribers (resolvconf-configuration-enabled-subscribers conf)))
+    (shepherd-service
+      (provision '(resolvconf))
+      (documentation "Setup resolvconf subscribers.")
+      (start (resolvconf-subscriber-setup package))
+      (stop #~(const #f))
+      (respawn? #f))))
+
+(define resolvconf-service-type
+  (service-type
+    (name 'resolvconf)
+    (extensions
+      (list (service-extension etc-service-type
+                               resolvconf-conf-service)
+            (service-extension shepherd-root-service-type
+                               (compose list resolvconf-subscriber-service))))
+    (default-value (resolvconf-configuration))
+    (compose concatenate)
+    (description "Setup resolvconf.")))
+
+
 ;;; admin.scm ends here
-- 
2.45.2





Changed bug title to '[PATCH] Add resolvconf service' from 'j' Request was from Ludovic Courtès <ludo <at> gnu.org> to control <at> debbugs.gnu.org. (Sat, 20 Jul 2024 09:59:01 GMT) Full text and rfc822 format available.

This bug report was last modified 329 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.