zone-file
zone-entry
+ knot-resolver-service-type
+ knot-resolver-configuration
+
dnsmasq-service-type
dnsmasq-configuration
(define-record-type* <knot-zone-configuration>
knot-zone-configuration make-knot-zone-configuration
knot-zone-configuration?
- (domain knot-zone-configuration-domain
- (default ""))
- (file knot-zone-configuration-file
- (default "")) ; the file where this zone is saved.
- (zone knot-zone-configuration-zone
- (default (zone-file))) ; initial content of the zone file
- (master knot-zone-configuration-master
- (default '()))
- (ddns-master knot-zone-configuration-ddns-master
- (default #f))
- (notify knot-zone-configuration-notify
- (default '()))
- (acl knot-zone-configuration-acl
- (default '()))
- (semantic-checks? knot-zone-configuration-semantic-checks?
- (default #f))
- (disable-any? knot-zone-configuration-disable-any?
- (default #f))
- (zonefile-sync knot-zone-configuration-zonefile-sync
- (default 0))
- (dnssec-policy knot-zone-configuration-dnssec-policy
- (default #f))
- (serial-policy knot-zone-configuration-serial-policy
- (default 'increment)))
+ (domain knot-zone-configuration-domain
+ (default ""))
+ (file knot-zone-configuration-file
+ (default "")) ; the file where this zone is saved.
+ (zone knot-zone-configuration-zone
+ (default (zone-file))) ; initial content of the zone file
+ (master knot-zone-configuration-master
+ (default '()))
+ (ddns-master knot-zone-configuration-ddns-master
+ (default #f))
+ (notify knot-zone-configuration-notify
+ (default '()))
+ (acl knot-zone-configuration-acl
+ (default '()))
+ (semantic-checks? knot-zone-configuration-semantic-checks?
+ (default #f))
+ (disable-any? knot-zone-configuration-disable-any?
+ (default #f))
+ (zonefile-sync knot-zone-configuration-zonefile-sync
+ (default 0))
+ (zonefile-load knot-zone-configuration-zonefile-load
+ (default #f))
+ (journal-content knot-zone-configuration-journal-content
+ (default #f))
+ (max-journal-usage knot-zone-configuration-max-journal-usage
+ (default #f))
+ (max-journal-depth knot-zone-configuration-max-journal-depth
+ (default #f))
+ (max-zone-size knot-zone-configuration-max-zone-size
+ (default #f))
+ (dnssec-policy knot-zone-configuration-dnssec-policy
+ (default #f))
+ (serial-policy knot-zone-configuration-serial-policy
+ (default 'increment)))
(define-record-type* <knot-remote-configuration>
knot-remote-configuration make-knot-remote-configuration
(default knot))
(run-directory knot-configuration-run-directory
(default "/var/run/knot"))
+ (includes knot-configuration-includes
+ (default '()))
(listen-v4 knot-configuration-listen-v4
(default "0.0.0.0"))
(listen-v6 knot-configuration-listen-v6
(error-out "knot configuration field must be a package."))
(unless (string? (knot-configuration-run-directory config))
(error-out "run-directory must be a string."))
+ (unless (list? (knot-configuration-includes config))
+ (error-out "includes must be a list of strings or file-like objects."))
(unless (list? (knot-configuration-keys config))
(error-out "keys must be a list of knot-key-configuration."))
(for-each (lambda (key) (verify-knot-key-configuration key))
(fold (lambda (x1 x2)
(string-append (if (symbol? x1) (symbol->string x1) x1) ", "
(if (symbol? x2) (symbol->string x2) x2)))
- (car l) (cdr l))
+ (if (symbol? (car l)) (symbol->string (car l)) (car l)) (cdr l))
"]"))))
(define (knot-acl-config acls)
(acl (list #$@(knot-zone-configuration-acl zone)))
(semantic-checks? #$(knot-zone-configuration-semantic-checks? zone))
(disable-any? #$(knot-zone-configuration-disable-any? zone))
+ (zonefile-sync #$(knot-zone-configuration-zonefile-sync zone))
+ (zonefile-load '#$(knot-zone-configuration-zonefile-load zone))
+ (journal-content #$(knot-zone-configuration-journal-content zone))
+ (max-journal-usage #$(knot-zone-configuration-max-journal-usage zone))
+ (max-journal-depth #$(knot-zone-configuration-max-journal-depth zone))
+ (max-zone-size #$(knot-zone-configuration-max-zone-size zone))
(dnssec-policy #$(knot-zone-configuration-dnssec-policy zone))
(serial-policy '#$(knot-zone-configuration-serial-policy zone)))
(format #t " - domain: ~a\n" domain)
(knot-zone-configuration-acl zone))))
(format #t " semantic-checks: ~a\n" (if semantic-checks? "on" "off"))
(format #t " disable-any: ~a\n" (if disable-any? "on" "off"))
+ (if zonefile-sync
+ (format #t " zonefile-sync: ~a\n" zonefile-sync))
+ (if zonefile-load
+ (format #t " zonefile-load: ~a\n"
+ (symbol->string zonefile-load)))
+ (if journal-content
+ (format #t " journal-content: ~a\n"
+ (symbol->string journal-content)))
+ (if max-journal-usage
+ (format #t " max-journal-usage: ~a\n" max-journal-usage))
+ (if max-journal-depth
+ (format #t " max-journal-depth: ~a\n" max-journal-depth))
+ (if max-zone-size
+ (format #t " max-zone-size: ~a\n" max-zone-size))
(if dnssec-policy
(begin
(format #t " dnssec-signing: on\n")
#~(begin
(call-with-output-file #$output
(lambda (port)
+ (for-each (lambda (inc)
+ (format port "include: ~a\n" inc))
+ '#$(knot-configuration-includes config))
(format port "server:\n")
(format port " rundir: ~a\n" #$(knot-configuration-run-directory config))
(format port " user: knot\n")
(const %knot-accounts))))))
\f
+;;;
+;;; Knot Resolver.
+;;;
+
+(define-record-type* <knot-resolver-configuration>
+ knot-resolver-configuration
+ make-knot-resolver-configuration
+ knot-resolver-configuration?
+ (package knot-resolver-configuration-package
+ (default knot-resolver))
+ (kresd-config-file knot-resolver-kresd-config-file
+ (default %kresd.conf))
+ (garbage-collection-interval knot-resolver-garbage-collection-interval
+ (default 1000)))
+
+(define %kresd.conf
+ (plain-file "kresd.conf" "-- -*- mode: lua -*-
+net = { '127.0.0.1', '::1' }
+user('knot-resolver', 'knot-resolver')
+modules = { 'hints > iterate', 'stats', 'predict' }
+cache.size = 100 * MB
+"))
+
+(define %knot-resolver-accounts
+ (list (user-group
+ (name "knot-resolver")
+ (system? #t))
+ (user-account
+ (name "knot-resolver")
+ (group "knot-resolver")
+ (system? #t)
+ (home-directory "/var/cache/knot-resolver")
+ (shell (file-append shadow "/sbin/nologin")))))
+
+(define (knot-resolver-activation config)
+ #~(begin
+ (use-modules (guix build utils))
+ (let ((rundir "/var/cache/knot-resolver")
+ (owner (getpwnam "knot-resolver")))
+ (mkdir-p rundir)
+ (chown rundir (passwd:uid owner) (passwd:gid owner)))))
+
+(define knot-resolver-shepherd-services
+ (match-lambda
+ (($ <knot-resolver-configuration> package
+ kresd-config-file
+ garbage-collection-interval)
+ (list
+ (shepherd-service
+ (provision '(kresd))
+ (requirement '(networking))
+ (documentation "Run the Knot Resolver daemon.")
+ (start #~(make-forkexec-constructor
+ '(#$(file-append package "/sbin/kresd")
+ "-c" #$kresd-config-file "-f" "1"
+ "/var/cache/knot-resolver")))
+ (stop #~(make-kill-destructor)))
+ (shepherd-service
+ (provision '(kres-cache-gc))
+ (requirement '(user-processes))
+ (documentation "Run the Knot Resolver Garbage Collector daemon.")
+ (start #~(make-forkexec-constructor
+ '(#$(file-append package "/sbin/kres-cache-gc")
+ "-d" #$(number->string garbage-collection-interval)
+ "-c" "/var/cache/knot-resolver")
+ #:user "knot-resolver"
+ #:group "knot-resolver"))
+ (stop #~(make-kill-destructor)))))))
+
+(define knot-resolver-service-type
+ (service-type
+ (name 'knot-resolver)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ knot-resolver-shepherd-services)
+ (service-extension activation-service-type
+ knot-resolver-activation)
+ (service-extension account-service-type
+ (const %knot-resolver-accounts))))
+ (default-value (knot-resolver-configuration))
+ (description "Run the Knot DNS Resolver.")))
+
+\f
;;;
;;; Dnsmasq.
;;;
(string-delete #\? (symbol->string field-name)))
(define (serialize-field field-name val)
- (format #t "~a=~a\n" (uglify-field-name field-name) val))
+ (when (not (member field-name '(group secret-file user)))
+ (format #t "~a=~a\n" (uglify-field-name field-name) val)))
(define (serialize-boolean field-name val)
(serialize-field field-name (if val "yes" "no")))