1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
4 ;;; Copyright © 2016, 2018, 2020 Efraim Flashner <efraim@flashner.co.il>
5 ;;; Copyright © 2016 John Darrington <jmd@gnu.org>
6 ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
7 ;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be>
8 ;;; Copyright © 2017, 2018 Marius Bakke <mbakke@fastmail.com>
9 ;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
10 ;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
11 ;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
12 ;;; Copyright © 2019 Florian Pelz <pelzflorian@pelzflorian.de>
13 ;;; Copyright © 2019 Maxim Cournoyer <maxim.cournoyer@gmail.com>
14 ;;; Copyright © 2019 Sou Bunnbu <iyzsong@member.fsf.org>
15 ;;; Copyright © 2019 Alex Griffin <a@ajgrf.com>
16 ;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
17 ;;; Copyright © 2021 Oleg Pykhalov <go.wigust@gmail.com>
19 ;;; This file is part of GNU Guix.
21 ;;; GNU Guix is free software; you can redistribute it and/or modify it
22 ;;; under the terms of the GNU General Public License as published by
23 ;;; the Free Software Foundation; either version 3 of the License, or (at
24 ;;; your option) any later version.
26 ;;; GNU Guix is distributed in the hope that it will be useful, but
27 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
28 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 ;;; GNU General Public License for more details.
31 ;;; You should have received a copy of the GNU General Public License
32 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
34 (define-module (gnu services networking)
35 #:use-module (gnu services)
36 #:use-module (gnu services base)
37 #:use-module (gnu services configuration)
38 #:use-module (gnu services linux)
39 #:use-module (gnu services shepherd)
40 #:use-module (gnu services dbus)
41 #:use-module (gnu system shadow)
42 #:use-module (gnu system pam)
43 #:use-module (gnu packages admin)
44 #:use-module (gnu packages base)
45 #:use-module (gnu packages bash)
46 #:use-module (gnu packages cluster)
47 #:use-module (gnu packages connman)
48 #:use-module (gnu packages freedesktop)
49 #:use-module (gnu packages linux)
50 #:use-module (gnu packages tor)
51 #:use-module (gnu packages usb-modeswitch)
52 #:use-module (gnu packages messaging)
53 #:use-module (gnu packages networking)
54 #:use-module (gnu packages ntp)
55 #:use-module (gnu packages wicd)
56 #:use-module (gnu packages gnome)
57 #:use-module (guix gexp)
58 #:use-module (guix records)
59 #:use-module (guix modules)
60 #:use-module (guix packages)
61 #:use-module (guix deprecation)
62 #:use-module (rnrs enums)
63 #:use-module (srfi srfi-1)
64 #:use-module (srfi srfi-9)
65 #:use-module (srfi srfi-26)
66 #:use-module (srfi srfi-43)
67 #:use-module (ice-9 match)
69 #:re-export (static-networking-service
70 static-networking-service-type)
71 #:export (%facebook-host-aliases
73 dhcp-client-service-type
78 dhcpd-configuration-package
79 dhcpd-configuration-config-file
80 dhcpd-configuration-version
81 dhcpd-configuration-run-directory
82 dhcpd-configuration-lease-file
83 dhcpd-configuration-pid-file
84 dhcpd-configuration-interfaces
89 ntp-configuration-servers
90 ntp-allow-large-adjustment?
102 openntpd-configuration
103 openntpd-configuration?
104 openntpd-service-type
119 network-manager-configuration
120 network-manager-configuration?
121 network-manager-configuration-dns
122 network-manager-configuration-vpn-plugins
123 network-manager-service-type
125 connman-configuration
126 connman-configuration?
129 modem-manager-configuration
130 modem-manager-configuration?
131 modem-manager-service-type
133 usb-modeswitch-configuration
134 usb-modeswitch-configuration?
135 usb-modeswitch-configuration-usb-modeswitch
136 usb-modeswitch-configuration-usb-modeswitch-data
137 usb-modeswitch-service-type
139 wpa-supplicant-configuration
140 wpa-supplicant-configuration?
141 wpa-supplicant-configuration-wpa-supplicant
142 wpa-supplicant-configuration-requirement
143 wpa-supplicant-configuration-pid-file
144 wpa-supplicant-configuration-dbus?
145 wpa-supplicant-configuration-interface
146 wpa-supplicant-configuration-config-file
147 wpa-supplicant-configuration-extra-options
148 wpa-supplicant-service-type
150 hostapd-configuration
151 hostapd-configuration?
152 hostapd-configuration-package
153 hostapd-configuration-interface
154 hostapd-configuration-ssid
155 hostapd-configuration-broadcast-ssid?
156 hostapd-configuration-channel
157 hostapd-configuration-driver
160 simulated-wifi-service-type
162 openvswitch-service-type
163 openvswitch-configuration
165 iptables-configuration
166 iptables-configuration?
167 iptables-configuration-iptables
168 iptables-configuration-ipv4-rules
169 iptables-configuration-ipv6-rules
170 iptables-service-type
172 nftables-service-type
173 nftables-configuration
174 nftables-configuration?
175 nftables-configuration-package
176 nftables-configuration-ruleset
177 %default-nftables-ruleset
179 pagekite-service-type
180 pagekite-configuration
181 pagekite-configuration?
182 pagekite-configuration-package
183 pagekite-configuration-kitename
184 pagekite-configuration-kitesecret
185 pagekite-configuration-frontend
186 pagekite-configuration-kites
187 pagekite-configuration-extra-file
189 yggdrasil-service-type
190 yggdrasil-configuration
191 yggdrasil-configuration?
192 yggdrasil-configuration-autoconf?
193 yggdrasil-configuration-config-file
194 yggdrasil-configuration-log-level
195 yggdrasil-configuration-log-to
196 yggdrasil-configuration-json-config
197 yggdrasil-configuration-package
199 keepalived-configuration
200 keepalived-configuration?
201 keepalived-service-type))
205 ;;; Networking services.
209 (define %facebook-host-aliases
210 ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
213 # Block Facebook IPv4.
214 127.0.0.1 www.facebook.com
215 127.0.0.1 facebook.com
216 127.0.0.1 login.facebook.com
217 127.0.0.1 www.login.facebook.com
219 127.0.0.1 www.fbcdn.net
221 127.0.0.1 www.fbcdn.com
222 127.0.0.1 static.ak.fbcdn.net
223 127.0.0.1 static.ak.connect.facebook.com
224 127.0.0.1 connect.facebook.net
225 127.0.0.1 www.connect.facebook.net
226 127.0.0.1 apps.facebook.com
228 # Block Facebook IPv6.
229 fe80::1%lo0 facebook.com
230 fe80::1%lo0 login.facebook.com
231 fe80::1%lo0 www.login.facebook.com
232 fe80::1%lo0 fbcdn.net
233 fe80::1%lo0 www.fbcdn.net
234 fe80::1%lo0 fbcdn.com
235 fe80::1%lo0 www.fbcdn.com
236 fe80::1%lo0 static.ak.fbcdn.net
237 fe80::1%lo0 static.ak.connect.facebook.com
238 fe80::1%lo0 connect.facebook.net
239 fe80::1%lo0 www.connect.facebook.net
240 fe80::1%lo0 apps.facebook.com\n")
242 (define dhcp-client-service-type
243 (shepherd-service-type
247 (file-append dhcp "/sbin/dhclient"))
250 "/var/run/dhclient.pid")
253 (documentation "Set up networking via DHCP.")
254 (requirement '(user-processes udev))
256 ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
257 ;; networking is unavailable, but also means that the interface is not up
258 ;; yet when 'start' completes. To wait for the interface to be ready, one
259 ;; should instead monitor udev events.
260 (provision '(networking))
263 ;; When invoked without any arguments, 'dhclient' discovers all
264 ;; non-loopback interfaces *that are up*. However, the relevant
265 ;; interfaces are typically down at this point. Thus we perform
266 ;; our own interface discovery here.
269 (and (arp-network-interface? interface)
270 (not (loopback-network-interface? interface))
271 ;; XXX: Make sure the interfaces are up so that
272 ;; 'dhclient' can actually send/receive over them.
273 ;; Ignore those that cannot be activated.
275 (set-network-interface-up interface)))))
277 (filter valid? (all-network-interface-names)))
279 (false-if-exception (delete-file #$pid-file))
280 (let ((pid (fork+exec-command
281 (cons* #$dhclient "-nw"
282 "-pf" #$pid-file ifaces))))
283 (and (zero? (cdr (waitpid pid)))
284 (read-pid-file #$pid-file)))))
285 (stop #~(make-kill-destructor))))
287 (description "Run @command{dhcp}, a Dynamic Host Configuration
288 Protocol (DHCP) client, on all the non-loopback network interfaces.")))
290 (define-deprecated (dhcp-client-service #:key (dhcp isc-dhcp))
291 dhcp-client-service-type
292 "Return a service that runs @var{dhcp}, a Dynamic Host Configuration
293 Protocol (DHCP) client, on all the non-loopback network interfaces."
294 (service dhcp-client-service-type dhcp))
296 (define-record-type* <dhcpd-configuration>
297 dhcpd-configuration make-dhcpd-configuration
299 (package dhcpd-configuration-package ;<package>
301 (config-file dhcpd-configuration-config-file ;file-like
303 (version dhcpd-configuration-version ;"4", "6", or "4o6"
305 (run-directory dhcpd-configuration-run-directory
306 (default "/run/dhcpd"))
307 (lease-file dhcpd-configuration-lease-file
308 (default "/var/db/dhcpd.leases"))
309 (pid-file dhcpd-configuration-pid-file
310 (default "/run/dhcpd/dhcpd.pid"))
311 ;; list of strings, e.g. (list "enp0s25")
312 (interfaces dhcpd-configuration-interfaces
315 (define dhcpd-shepherd-service
317 (($ <dhcpd-configuration> package config-file version run-directory
318 lease-file pid-file interfaces)
320 (error "Must supply a config-file"))
321 (list (shepherd-service
322 ;; Allow users to easily run multiple versions simultaneously.
323 (provision (list (string->symbol
324 (string-append "dhcpv" version "-daemon"))))
325 (documentation (string-append "Run the DHCPv" version " daemon"))
326 (requirement '(networking))
327 (start #~(make-forkexec-constructor
328 '(#$(file-append package "/sbin/dhcpd")
329 #$(string-append "-" version)
334 #:pid-file #$pid-file))
335 (stop #~(make-kill-destructor)))))))
337 (define dhcpd-activation
339 (($ <dhcpd-configuration> package config-file version run-directory
340 lease-file pid-file interfaces)
341 (with-imported-modules '((guix build utils))
343 (unless (file-exists? #$run-directory)
344 (mkdir #$run-directory))
345 ;; According to the DHCP manual (man dhcpd.leases), the lease
346 ;; database must be present for dhcpd to start successfully.
347 (unless (file-exists? #$lease-file)
348 (with-output-to-file #$lease-file
349 (lambda _ (display ""))))
350 ;; Validate the config.
352 #$(file-append package "/sbin/dhcpd") "-t" "-cf"
355 (define dhcpd-service-type
359 (list (service-extension shepherd-root-service-type dhcpd-shepherd-service)
360 (service-extension activation-service-type dhcpd-activation)))
361 (description "Run a DHCP (Dynamic Host Configuration Protocol) daemon. The
362 daemon is responsible for allocating IP addresses to its client.")))
369 (define ntp-server-types (make-enumeration
376 (define-record-type* <ntp-server>
377 ntp-server make-ntp-server
379 ;; The type can be one of the symbols of the NTP-SERVER-TYPE? enumeration.
380 (type ntp-server-type
382 (address ntp-server-address) ; a string
383 ;; The list of options can contain single option names or tuples in the form
385 (options ntp-server-options
388 (define (ntp-server->string ntp-server)
389 ;; Serialize the NTP server object as a string, ready to use in the NTP
390 ;; configuration file.
391 (define (flatten lst)
397 (cons (format #f "~a" x) res)))))
400 (($ <ntp-server> type address options)
401 ;; XXX: It'd be neater if fields were validated at the syntax level (for
402 ;; static ones at least). Perhaps the Guix record type could support a
403 ;; predicate property on a field?
404 (unless (enum-set-member? type ntp-server-types)
405 (error "Invalid NTP server type" type))
406 (string-join (cons* (symbol->string type)
408 (flatten options))))))
411 ;; Default set of NTP servers. These URLs are managed by the NTP Pool project.
412 ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact
413 ;; for this NTP pool "zone".
417 (address "0.guix.pool.ntp.org")
418 (options '("iburst"))))) ;as recommended in the ntpd manual
420 (define-record-type* <ntp-configuration>
421 ntp-configuration make-ntp-configuration
423 (ntp ntp-configuration-ntp
425 (servers %ntp-configuration-servers ;list of <ntp-server> objects
426 (default %ntp-servers))
427 (allow-large-adjustment? ntp-allow-large-adjustment?
428 (default #t))) ;as recommended in the ntpd manual
430 (define (ntp-configuration-servers ntp-configuration)
431 ;; A wrapper to support the deprecated form of this field.
432 (let ((ntp-servers (%ntp-configuration-servers ntp-configuration)))
434 (((? string?) (? string?) ...)
435 (format (current-error-port) "warning: Defining NTP servers as strings is \
436 deprecated. Please use <ntp-server> records instead.\n")
441 (options '()))) ntp-servers))
442 ((($ <ntp-server>) ($ <ntp-server>) ...)
445 (define ntp-shepherd-service
448 (($ <ntp-configuration> ntp servers allow-large-adjustment?)
449 (let ((servers (ntp-configuration-servers config)))
450 ;; TODO: Add authentication support.
452 (string-append "driftfile /var/run/ntpd/ntp.drift\n"
453 (string-join (map ntp-server->string servers)
456 # Disable status queries as a workaround for CVE-2013-5211:
457 # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
458 restrict default kod nomodify notrap nopeer noquery limited
459 restrict -6 default kod nomodify notrap nopeer noquery limited
461 # Yet, allow use of the local 'ntpq'.
465 # This is required to use servers from a pool directive when using the 'nopeer'
466 # option by default, as documented in the 'ntp.conf' manual.
467 restrict source notrap nomodify noquery\n"))
470 (plain-file "ntpd.conf" config))
472 (list (shepherd-service
474 (documentation "Run the Network Time Protocol (NTP) daemon.")
475 (requirement '(user-processes networking))
476 (start #~(make-forkexec-constructor
477 (list (string-append #$ntp "/bin/ntpd") "-n"
478 "-c" #$ntpd.conf "-u" "ntpd"
479 #$@(if allow-large-adjustment?
482 (stop #~(make-kill-destructor)))))))))
484 (define %ntp-accounts
489 (comment "NTP daemon user")
490 (home-directory "/var/empty")
491 (shell (file-append shadow "/sbin/nologin")))))
494 (define (ntp-service-activation config)
495 "Return the activation gexp for CONFIG."
496 (with-imported-modules '((guix build utils))
498 (use-modules (guix build utils))
502 (let ((directory "/var/run/ntpd"))
504 (chown directory (passwd:uid %user) (passwd:gid %user))))))
506 (define ntp-service-type
507 (service-type (name 'ntp)
509 (list (service-extension shepherd-root-service-type
510 ntp-shepherd-service)
511 (service-extension account-service-type
512 (const %ntp-accounts))
513 (service-extension activation-service-type
514 ntp-service-activation)))
516 "Run the @command{ntpd}, the Network Time Protocol (NTP)
517 daemon of the @uref{http://www.ntp.org, Network Time Foundation}. The daemon
518 will keep the system clock synchronized with that of the given servers.")
519 (default-value (ntp-configuration))))
521 (define-deprecated (ntp-service #:key (ntp ntp)
522 (servers %ntp-servers)
523 allow-large-adjustment?)
525 "Return a service that runs the daemon from @var{ntp}, the
526 @uref{http://www.ntp.org, Network Time Protocol package}. The daemon will
527 keep the system clock synchronized with that of @var{servers}.
528 @var{allow-large-adjustment?} determines whether @command{ntpd} is allowed to
529 make an initial adjustment of more than 1,000 seconds."
530 (service ntp-service-type
531 (ntp-configuration (ntp ntp)
533 (allow-large-adjustment?
534 allow-large-adjustment?))))
541 (define %openntpd-servers
542 (map ntp-server-address %ntp-servers))
544 (define-record-type* <openntpd-configuration>
545 openntpd-configuration make-openntpd-configuration
546 openntpd-configuration?
547 (openntpd openntpd-configuration-openntpd
549 (listen-on openntpd-listen-on
550 (default '("127.0.0.1"
552 (query-from openntpd-query-from
554 (sensor openntpd-sensor
556 (server openntpd-server
558 (servers openntpd-servers
559 (default %openntpd-servers))
560 (constraint-from openntpd-constraint-from
562 (constraints-from openntpd-constraints-from
565 (define (openntpd-configuration->string config)
567 (define (quote-field? name)
568 (member name '("constraints from")))
570 (match-record config <openntpd-configuration>
571 (listen-on query-from sensor server servers constraint-from
576 (filter-map (lambda (field values)
578 (() #f) ;discard entry with filter-map
579 ((val ...) ;validate value type
581 (if (quote-field? field)
582 (format #f "~a \"~a\"" field value)
583 (format #f "~a ~a" field value)))
586 '("listen on" "query from" "sensor" "server" "servers"
587 "constraint from" "constraints from")
588 ;; The corresponding entry values.
589 (list listen-on query-from sensor server servers
590 constraint-from constraints-from)))
592 "\n"))) ;add a trailing newline
594 (define (openntpd-shepherd-service config)
595 (let ((openntpd (openntpd-configuration-openntpd config)))
598 (plain-file "ntpd.conf" (openntpd-configuration->string config)))
600 (list (shepherd-service
602 (documentation "Run the Network Time Protocol (NTP) daemon.")
603 (requirement '(user-processes networking))
604 (start #~(make-forkexec-constructor
605 (list (string-append #$openntpd "/sbin/ntpd")
607 "-d") ;; don't daemonize
608 ;; When ntpd is daemonized it repeatedly tries to respawn
609 ;; while running, leading shepherd to disable it. To
610 ;; prevent spamming stderr, redirect output to logfile.
611 #:log-file "/var/log/ntpd"))
612 (stop #~(make-kill-destructor))))))
614 (define (openntpd-service-activation config)
615 "Return the activation gexp for CONFIG."
616 (with-imported-modules '((guix build utils))
618 (use-modules (guix build utils))
622 (unless (file-exists? "/var/db/ntpd.drift")
623 (with-output-to-file "/var/db/ntpd.drift"
625 (format #t "0.0")))))))
627 (define openntpd-service-type
628 (service-type (name 'openntpd)
630 (list (service-extension shepherd-root-service-type
631 openntpd-shepherd-service)
632 (service-extension account-service-type
633 (const %ntp-accounts))
634 (service-extension profile-service-type
635 (compose list openntpd-configuration-openntpd))
636 (service-extension activation-service-type
637 openntpd-service-activation)))
638 (default-value (openntpd-configuration))
640 "Run the @command{ntpd}, the Network Time Protocol (NTP)
641 daemon, as implemented by @uref{http://www.openntpd.org, OpenNTPD}. The
642 daemon will keep the system clock synchronized with that of the given servers.")))
649 (define-record-type* <inetd-configuration> inetd-configuration
650 make-inetd-configuration
652 (program inetd-configuration-program ;file-like
653 (default (file-append inetutils "/libexec/inetd")))
654 (entries inetd-configuration-entries ;list of <inetd-entry>
657 (define-record-type* <inetd-entry> inetd-entry make-inetd-entry
659 (node inetd-entry-node ;string or #f
661 (name inetd-entry-name) ;string, from /etc/services
663 (socket-type inetd-entry-socket-type) ;stream | dgram | raw |
665 (protocol inetd-entry-protocol) ;string, from /etc/protocols
667 (wait? inetd-entry-wait? ;Boolean
669 (user inetd-entry-user) ;string
671 (program inetd-entry-program ;string or file-like object
672 (default "internal"))
673 (arguments inetd-entry-arguments ;list of strings or file-like objects
676 (define (inetd-config-file entries)
677 (apply mixed-text-file "inetd.conf"
680 (let* ((node (inetd-entry-node entry))
681 (name (inetd-entry-name entry))
683 (if node (string-append node ":" name) name))
685 (match (inetd-entry-socket-type entry)
686 ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
687 (symbol->string (inetd-entry-socket-type entry)))))
688 (protocol (inetd-entry-protocol entry))
689 (wait (if (inetd-entry-wait? entry) "wait" "nowait"))
690 (user (inetd-entry-user entry))
691 (program (inetd-entry-program entry))
692 (args (inetd-entry-arguments entry)))
695 (list #$@(list socket type protocol wait user program) #$@args)
699 (define inetd-shepherd-service
701 (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing
702 (($ <inetd-configuration> program entries)
705 (documentation "Run inetd.")
707 (requirement '(user-processes networking syslogd))
708 (start #~(make-forkexec-constructor
709 (list #$program #$(inetd-config-file entries))
710 #:pid-file "/var/run/inetd.pid"))
711 (stop #~(make-kill-destructor)))))))
713 (define-public inetd-service-type
717 (list (service-extension shepherd-root-service-type
718 inetd-shepherd-service)))
720 ;; The service can be extended with additional lists of entries.
721 (compose concatenate)
722 (extend (lambda (config entries)
725 (entries (append (inetd-configuration-entries config)
728 "Start @command{inetd}, the @dfn{Internet superserver}. It is responsible
729 for listening on Internet sockets and spawning the corresponding services on
737 (define-record-type* <tor-configuration>
738 tor-configuration make-tor-configuration
740 (tor tor-configuration-tor
742 (config-file tor-configuration-config-file
743 (default (plain-file "empty" "")))
744 (hidden-services tor-configuration-hidden-services
746 (socks-socket-type tor-configuration-socks-socket-type ; 'tcp or 'unix
749 (define %tor-accounts
750 ;; User account and groups for Tor.
751 (list (user-group (name "tor") (system? #t))
756 (comment "Tor daemon user")
757 (home-directory "/var/empty")
758 (shell (file-append shadow "/sbin/nologin")))))
760 (define-record-type <hidden-service>
761 (hidden-service name mapping)
763 (name hidden-service-name) ;string
764 (mapping hidden-service-mapping)) ;list of port/address tuples
766 (define (tor-configuration->torrc config)
767 "Return a 'torrc' file for CONFIG."
769 (($ <tor-configuration> tor config-file services socks-socket-type)
772 (with-imported-modules '((guix build utils))
774 (use-modules (guix build utils)
777 (call-with-output-file #$output
780 ### These lines were generated from your system configuration:
782 DataDirectory /var/lib/tor
783 PidFile /var/run/tor/tor.pid
784 Log notice syslog\n" port)
785 (when (eq? 'unix '#$socks-socket-type)
787 SocksPort unix:/var/run/tor/socks-sock
788 UnixSocksGroupWritable 1\n" port))
790 (for-each (match-lambda
791 ((service (ports hosts) ...)
793 HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
795 (for-each (lambda (tcp-port host)
797 HiddenServicePort ~a ~a~%"
800 '#$(map (match-lambda
801 (($ <hidden-service> name mapping)
802 (cons name mapping)))
806 ### End of automatically generated lines.\n\n" port)
808 ;; Append the user's config file.
809 (call-with-input-file #$config-file
811 (dump-port input port)))
814 (define (tor-shepherd-service config)
815 "Return a <shepherd-service> running Tor."
817 (($ <tor-configuration> tor)
818 (let ((torrc (tor-configuration->torrc config)))
819 (with-imported-modules (source-module-closure
820 '((gnu build shepherd)
821 (gnu system file-systems)))
822 (list (shepherd-service
825 ;; Tor needs at least one network interface to be up, hence the
826 ;; dependency on 'loopback'.
827 (requirement '(user-processes loopback syslogd))
829 (modules '((gnu build shepherd)
830 (gnu system file-systems)))
832 (start #~(make-forkexec-constructor/container
833 (list #$(file-append tor "/bin/tor") "-f" #$torrc)
835 #:mappings (list (file-system-mapping
836 (source "/var/lib/tor")
840 (source "/dev/log") ;for syslog
843 (source "/var/run/tor")
846 #:pid-file "/var/run/tor/tor.pid"))
847 (stop #~(make-kill-destructor))
848 (documentation "Run the Tor anonymous network overlay."))))))))
850 (define (tor-activation config)
851 "Set up directories for Tor and its hidden services, if any."
853 (use-modules (guix build utils))
858 (define (initialize service)
859 (let ((directory (string-append "/var/lib/tor/hidden-services/"
862 (chown directory (passwd:uid %user) (passwd:gid %user))
864 ;; The daemon bails out if we give wider permissions.
865 (chmod directory #o700)))
867 ;; Allow Tor to write its PID file.
868 (mkdir-p "/var/run/tor")
869 (chown "/var/run/tor" (passwd:uid %user) (passwd:gid %user))
870 ;; Set the group permissions to rw so that if the system administrator
871 ;; has specified UnixSocksGroupWritable=1 in their torrc file, members
872 ;; of the "tor" group will be able to use the SOCKS socket.
873 (chmod "/var/run/tor" #o750)
875 ;; Allow Tor to access the hidden services' directories.
876 (mkdir-p "/var/lib/tor")
877 (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
878 (chmod "/var/lib/tor" #o700)
880 ;; Make sure /var/lib is accessible to the 'tor' user.
881 (chmod "/var/lib" #o755)
884 '#$(map hidden-service-name
885 (tor-configuration-hidden-services config)))))
887 (define tor-service-type
888 (service-type (name 'tor)
890 (list (service-extension shepherd-root-service-type
891 tor-shepherd-service)
892 (service-extension account-service-type
893 (const %tor-accounts))
894 (service-extension activation-service-type
897 ;; This can be extended with hidden services.
898 (compose concatenate)
899 (extend (lambda (config services)
903 (append (tor-configuration-hidden-services config)
905 (default-value (tor-configuration))
907 "Run the @uref{https://torproject.org, Tor} anonymous
908 networking daemon.")))
910 (define-deprecated (tor-service #:optional
911 (config-file (plain-file "empty" ""))
914 "Return a service to run the @uref{https://torproject.org, Tor} anonymous
917 The daemon runs as the @code{tor} unprivileged user. It is passed
918 @var{config-file}, a file-like object, with an additional @code{User tor} line
919 and lines for hidden services added via @code{tor-hidden-service}. Run
920 @command{man tor} for information about the configuration file."
921 (service tor-service-type
922 (tor-configuration (tor tor)
923 (config-file config-file))))
925 (define tor-hidden-service-type
926 ;; A type that extends Tor with hidden services.
927 (service-type (name 'tor-hidden-service)
929 (list (service-extension tor-service-type list)))
931 "Define a new Tor @dfn{hidden service}.")))
933 (define (tor-hidden-service name mapping)
934 "Define a new Tor @dfn{hidden service} called @var{name} and implementing
935 @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
938 '((22 \"127.0.0.1:22\")
939 (80 \"127.0.0.1:8080\"))
942 In this example, port 22 of the hidden service is mapped to local port 22, and
943 port 80 is mapped to local port 8080.
945 This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
946 the @file{hostname} file contains the @code{.onion} host name for the hidden
949 See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
950 project's documentation} for more information."
951 (service tor-hidden-service-type
952 (hidden-service name mapping)))
959 (define %wicd-activation
960 ;; Activation gexp for Wicd.
962 (use-modules (guix build utils))
964 (mkdir-p "/etc/wicd")
965 (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
966 (unless (file-exists? file-name)
967 (copy-file (string-append #$wicd file-name)
970 ;; Wicd invokes 'wpa_supplicant', which needs this directory for its
971 ;; named socket files.
972 (mkdir-p "/var/run/wpa_supplicant")
973 (chmod "/var/run/wpa_supplicant" #o750)))
975 (define (wicd-shepherd-service wicd)
976 "Return a shepherd service for WICD."
977 (list (shepherd-service
978 (documentation "Run the Wicd network manager.")
979 (provision '(networking))
980 (requirement '(user-processes dbus-system loopback))
981 (start #~(make-forkexec-constructor
982 (list (string-append #$wicd "/sbin/wicd")
984 (stop #~(make-kill-destructor)))))
986 (define wicd-service-type
987 (service-type (name 'wicd)
989 (list (service-extension shepherd-root-service-type
990 wicd-shepherd-service)
991 (service-extension dbus-root-service-type
993 (service-extension activation-service-type
994 (const %wicd-activation))
996 ;; Add Wicd to the global profile.
997 (service-extension profile-service-type list)))
999 "Run @url{https://launchpad.net/wicd,Wicd}, a network
1000 management daemon that aims to simplify wired and wireless networking.")))
1002 (define* (wicd-service #:key (wicd wicd))
1003 "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
1004 management daemon that aims to simplify wired and wireless networking.
1006 This service adds the @var{wicd} package to the global profile, providing
1007 several commands to interact with the daemon and configure networking:
1008 @command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
1009 and @command{wicd-curses} user interfaces."
1010 (service wicd-service-type wicd))
1017 (define-record-type* <modem-manager-configuration>
1018 modem-manager-configuration make-modem-manager-configuration
1019 modem-manager-configuration?
1020 (modem-manager modem-manager-configuration-modem-manager
1021 (default modem-manager)))
1028 (define-record-type* <network-manager-configuration>
1029 network-manager-configuration make-network-manager-configuration
1030 network-manager-configuration?
1031 (network-manager network-manager-configuration-network-manager
1032 (default network-manager))
1033 (dns network-manager-configuration-dns
1034 (default "default"))
1035 (vpn-plugins network-manager-configuration-vpn-plugins ;list of <package>
1038 (define network-manager-activation
1039 ;; Activation gexp for NetworkManager
1041 (($ <network-manager-configuration> network-manager dns vpn-plugins)
1043 (use-modules (guix build utils))
1044 (mkdir-p "/etc/NetworkManager/system-connections")
1045 #$@(if (equal? dns "dnsmasq")
1046 ;; create directory to store dnsmasq lease file
1047 '((mkdir-p "/var/lib/misc"))
1050 (define (vpn-plugin-directory plugins)
1051 "Return a directory containing PLUGINS, the NM VPN plugins."
1052 (directory-union "network-manager-vpn-plugins" plugins))
1054 (define (network-manager-accounts config)
1055 "Return the list of <user-account> and <user-group> for CONFIG."
1057 (file-append shadow "/sbin/nologin"))
1060 (append-map (lambda (package)
1062 (user-account (system? #t)
1064 (group "network-manager")
1065 (comment "NetworkManager helper")
1066 (home-directory "/var/empty")
1067 (create-home-directory? #f)
1069 (or (assoc-ref (package-properties package)
1072 (network-manager-configuration-vpn-plugins config)))
1078 (cons (user-group (name "network-manager") (system? #t))
1081 (define network-manager-environment
1083 (($ <network-manager-configuration> network-manager dns vpn-plugins)
1084 ;; Define this variable in the global environment such that
1085 ;; "nmcli connection import type openvpn file foo.ovpn" works.
1086 `(("NM_VPN_PLUGIN_DIR"
1087 . ,(file-append (vpn-plugin-directory vpn-plugins)
1088 "/lib/NetworkManager/VPN"))))))
1090 (define network-manager-shepherd-service
1092 (($ <network-manager-configuration> network-manager dns vpn-plugins)
1093 (let ((conf (plain-file "NetworkManager.conf"
1094 (string-append "[main]\ndns=" dns "\n")))
1095 (vpn (vpn-plugin-directory vpn-plugins)))
1096 (list (shepherd-service
1097 (documentation "Run the NetworkManager.")
1098 (provision '(networking))
1099 (requirement '(user-processes dbus-system wpa-supplicant loopback))
1100 (start #~(make-forkexec-constructor
1101 (list (string-append #$network-manager
1102 "/sbin/NetworkManager")
1103 (string-append "--config=" #$conf)
1105 #:environment-variables
1106 (list (string-append "NM_VPN_PLUGIN_DIR=" #$vpn
1107 "/lib/NetworkManager/VPN")
1108 ;; Override non-existent default users
1110 "NM_OPENVPN_GROUP=")))
1111 (stop #~(make-kill-destructor))))))))
1113 (define network-manager-service-type
1117 (($ <network-manager-configuration> network-manager _ vpn-plugins)
1118 `(,network-manager ,@vpn-plugins)))))
1121 (name 'network-manager)
1123 (list (service-extension shepherd-root-service-type
1124 network-manager-shepherd-service)
1125 (service-extension dbus-root-service-type config->packages)
1126 (service-extension polkit-service-type
1129 network-manager-configuration-network-manager))
1130 (service-extension account-service-type
1131 network-manager-accounts)
1132 (service-extension activation-service-type
1133 network-manager-activation)
1134 (service-extension session-environment-service-type
1135 network-manager-environment)
1136 ;; Add network-manager to the system profile.
1137 (service-extension profile-service-type config->packages)))
1138 (default-value (network-manager-configuration))
1140 "Run @uref{https://wiki.gnome.org/Projects/NetworkManager,
1141 NetworkManager}, a network management daemon that aims to simplify wired and
1142 wireless networking."))))
1149 (define-record-type* <connman-configuration>
1150 connman-configuration make-connman-configuration
1151 connman-configuration?
1152 (connman connman-configuration-connman
1154 (disable-vpn? connman-configuration-disable-vpn?
1157 (define (connman-activation config)
1158 (let ((disable-vpn? (connman-configuration-disable-vpn? config)))
1159 (with-imported-modules '((guix build utils))
1161 (use-modules (guix build utils))
1162 (mkdir-p "/var/lib/connman/")
1163 (unless #$disable-vpn?
1164 (mkdir-p "/var/lib/connman-vpn/"))))))
1166 (define (connman-shepherd-service config)
1167 "Return a shepherd service for Connman"
1169 (connman-configuration? config)
1170 (let ((connman (connman-configuration-connman config))
1171 (disable-vpn? (connman-configuration-disable-vpn? config)))
1172 (list (shepherd-service
1173 (documentation "Run Connman")
1174 (provision '(networking))
1176 '(user-processes dbus-system loopback wpa-supplicant))
1177 (start #~(make-forkexec-constructor
1178 (list (string-append #$connman
1182 #$@(if disable-vpn? '("--noplugin=vpn") '()))
1184 ;; As connman(8) notes, when passing '-n', connman
1185 ;; "directs log output to the controlling terminal in
1186 ;; addition to syslog." Redirect stdout and stderr
1187 ;; to avoid spamming the console (XXX: for some reason
1188 ;; redirecting to /dev/null doesn't work.)
1189 #:log-file "/var/log/connman.log"))
1190 (stop #~(make-kill-destructor)))))))
1192 (define connman-service-type
1193 (let ((connman-package (compose list connman-configuration-connman)))
1194 (service-type (name 'connman)
1196 (list (service-extension shepherd-root-service-type
1197 connman-shepherd-service)
1198 (service-extension polkit-service-type
1200 (service-extension dbus-root-service-type
1202 (service-extension activation-service-type
1204 ;; Add connman to the system profile.
1205 (service-extension profile-service-type
1207 (default-value (connman-configuration))
1209 "Run @url{https://01.org/connman,Connman},
1210 a network connection manager."))))
1217 (define modem-manager-service-type
1218 (let ((config->package
1220 (($ <modem-manager-configuration> modem-manager)
1221 (list modem-manager)))))
1222 (service-type (name 'modem-manager)
1224 (list (service-extension dbus-root-service-type
1226 (service-extension udev-service-type
1228 (service-extension polkit-service-type
1230 (default-value (modem-manager-configuration))
1232 "Run @uref{https://wiki.gnome.org/Projects/ModemManager,
1233 ModemManager}, a modem management daemon that aims to simplify dialup
1241 (define-record-type* <usb-modeswitch-configuration>
1242 usb-modeswitch-configuration make-usb-modeswitch-configuration
1243 usb-modeswitch-configuration?
1244 (usb-modeswitch usb-modeswitch-configuration-usb-modeswitch
1245 (default usb-modeswitch))
1246 (usb-modeswitch-data usb-modeswitch-configuration-usb-modeswitch-data
1247 (default usb-modeswitch-data))
1248 (config-file usb-modeswitch-configuration-config-file
1249 (default #~(string-append #$usb-modeswitch:dispatcher
1250 "/etc/usb_modeswitch.conf"))))
1252 (define (usb-modeswitch-sh usb-modeswitch config-file)
1253 "Build a copy of usb_modeswitch.sh located in package USB-MODESWITCH,
1254 modified to pass the CONFIG-FILE in its calls to usb_modeswitch_dispatcher,
1255 and wrap it to actually find the dispatcher in USB-MODESWITCH. The script
1256 will be run by USB_ModeSwitch’s udev rules file when a modeswitchable USB
1257 device is detected."
1260 (with-imported-modules '((guix build utils))
1262 (use-modules (guix build utils))
1265 #~(string-append " --config-file=" #$config-file)
1268 (install-file (string-append #$usb-modeswitch:dispatcher
1269 "/lib/udev/usb_modeswitch")
1272 ;; insert CFG-PARAM into usb_modeswitch_dispatcher command-lines
1273 (substitute* (string-append #$output "/usb_modeswitch")
1274 (("(exec usb_modeswitch_dispatcher .*)( 2>>)" _ left right)
1275 (string-append left cfg-param right))
1276 (("(exec usb_modeswitch_dispatcher .*)( &)" _ left right)
1277 (string-append left cfg-param right)))
1279 ;; wrap-program needs bash in PATH:
1280 (putenv (string-append "PATH=" #$bash "/bin"))
1281 (wrap-program (string-append #$output "/usb_modeswitch")
1282 `("PATH" ":" = (,(string-append #$coreutils "/bin")
1284 #$usb-modeswitch:dispatcher
1287 (define (usb-modeswitch-configuration->udev-rules config)
1288 "Build a rules file for extending udev-service-type from the rules in the
1289 usb-modeswitch package specified in CONFIG. The rules file will invoke
1290 usb_modeswitch.sh from the usb-modeswitch package, modified to pass the right
1293 (($ <usb-modeswitch-configuration> usb-modeswitch data config-file)
1295 "usb_modeswitch.rules"
1296 (with-imported-modules '((guix build utils))
1298 (use-modules (guix build utils))
1299 (let ((in (string-append #$data "/udev/40-usb_modeswitch.rules"))
1300 (out (string-append #$output "/lib/udev/rules.d"))
1301 (script #$(usb-modeswitch-sh usb-modeswitch config-file)))
1304 (install-file in out)
1305 (substitute* "40-usb_modeswitch.rules"
1306 (("PROGRAM=\"usb_modeswitch")
1307 (string-append "PROGRAM=\"" script "/usb_modeswitch"))
1308 (("RUN\\+=\"usb_modeswitch")
1309 (string-append "RUN+=\"" script "/usb_modeswitch"))))))))))
1311 (define usb-modeswitch-service-type
1313 (name 'usb-modeswitch)
1319 (let ((rules (usb-modeswitch-configuration->udev-rules config)))
1321 (default-value (usb-modeswitch-configuration))
1322 (description "Run @uref{http://www.draisberghof.de/usb_modeswitch/,
1323 USB_ModeSwitch}, a mode switching tool for controlling USB devices with
1324 multiple @dfn{modes}. When plugged in for the first time many USB
1325 devices (primarily high-speed WAN modems) act like a flash storage containing
1326 installers for Windows drivers. USB_ModeSwitch replays the sequence the
1327 Windows drivers would send to switch their mode from storage to modem (or
1328 whatever the thing is supposed to do).")))
1335 (define-record-type* <wpa-supplicant-configuration>
1336 wpa-supplicant-configuration make-wpa-supplicant-configuration
1337 wpa-supplicant-configuration?
1338 (wpa-supplicant wpa-supplicant-configuration-wpa-supplicant ;<package>
1339 (default wpa-supplicant))
1340 (requirement wpa-supplicant-configuration-requirement ;list of symbols
1341 (default '(user-processes loopback syslogd)))
1342 (pid-file wpa-supplicant-configuration-pid-file ;string
1343 (default "/var/run/wpa_supplicant.pid"))
1344 (dbus? wpa-supplicant-configuration-dbus? ;Boolean
1346 (interface wpa-supplicant-configuration-interface ;#f | string
1348 (config-file wpa-supplicant-configuration-config-file ;#f | <file-like>
1350 (extra-options wpa-supplicant-configuration-extra-options ;list of strings
1353 (define wpa-supplicant-shepherd-service
1355 (($ <wpa-supplicant-configuration> wpa-supplicant requirement pid-file dbus?
1356 interface config-file extra-options)
1357 (list (shepherd-service
1358 (documentation "Run the WPA supplicant daemon")
1359 (provision '(wpa-supplicant))
1360 (requirement (if dbus?
1361 (cons 'dbus-system requirement)
1363 (start #~(make-forkexec-constructor
1364 (list (string-append #$wpa-supplicant
1365 "/sbin/wpa_supplicant")
1366 (string-append "-P" #$pid-file)
1367 "-B" ;run in background
1368 "-s" ;log to syslogd
1373 #~((string-append "-i" #$interface))
1376 #~((string-append "-c" #$config-file))
1379 #:pid-file #$pid-file))
1380 (stop #~(make-kill-destructor)))))))
1382 (define wpa-supplicant-service-type
1383 (let ((config->package
1385 (($ <wpa-supplicant-configuration> wpa-supplicant)
1386 (list wpa-supplicant)))))
1387 (service-type (name 'wpa-supplicant)
1389 (list (service-extension shepherd-root-service-type
1390 wpa-supplicant-shepherd-service)
1391 (service-extension dbus-root-service-type config->package)
1392 (service-extension profile-service-type config->package)))
1393 (description "Run the WPA Supplicant daemon, a service that
1394 implements authentication, key negotiation and more for wireless networks.")
1395 (default-value (wpa-supplicant-configuration)))))
1402 (define-record-type* <hostapd-configuration>
1403 hostapd-configuration make-hostapd-configuration
1404 hostapd-configuration?
1405 (package hostapd-configuration-package
1407 (interface hostapd-configuration-interface ;string
1409 (ssid hostapd-configuration-ssid) ;string
1410 (broadcast-ssid? hostapd-configuration-broadcast-ssid? ;Boolean
1412 (channel hostapd-configuration-channel ;integer
1414 (driver hostapd-configuration-driver ;string
1415 (default "nl80211"))
1416 ;; See <https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf> for a list of
1417 ;; additional options we could add.
1418 (extra-settings hostapd-configuration-extra-settings ;string
1421 (define (hostapd-configuration-file config)
1422 "Return the configuration file for CONFIG, a <hostapd-configuration>."
1423 (match-record config <hostapd-configuration>
1424 (interface ssid broadcast-ssid? channel driver extra-settings)
1425 (plain-file "hostapd.conf"
1427 # Generated from your Guix configuration.
1429 interface=" interface "
1431 ignore_broadcast_ssid=" (if broadcast-ssid? "0" "1") "
1432 channel=" (number->string channel) "\n"
1433 extra-settings "\n"))))
1435 (define* (hostapd-shepherd-services config #:key (requirement '()))
1436 "Return Shepherd services for hostapd."
1437 (list (shepherd-service
1438 (provision '(hostapd))
1439 (requirement `(user-processes ,@requirement))
1440 (documentation "Run the hostapd WiFi access point daemon.")
1441 (start #~(make-forkexec-constructor
1442 (list #$(file-append hostapd "/sbin/hostapd")
1443 #$(hostapd-configuration-file config))
1444 #:log-file "/var/log/hostapd.log"))
1445 (stop #~(make-kill-destructor)))))
1447 (define hostapd-service-type
1451 (list (service-extension shepherd-root-service-type
1452 hostapd-shepherd-services)))
1454 "Run the @uref{https://w1.fi/hostapd/, hostapd} daemon for Wi-Fi access
1455 points and authentication servers.")))
1457 (define (simulated-wifi-shepherd-services config)
1458 "Return Shepherd services to run hostapd with CONFIG, a
1459 <hostapd-configuration>, as well as services to set up WiFi hardware
1461 (append (hostapd-shepherd-services config
1464 kernel-module-loader))
1465 (list (shepherd-service
1466 (provision '(unblocked-wifi))
1467 (requirement '(file-systems kernel-module-loader))
1469 "Unblock WiFi devices for use by mac80211_hwsim.")
1471 (invoke #$(file-append util-linux "/sbin/rfkill")
1473 (invoke #$(file-append util-linux "/sbin/rfkill")
1477 (define simulated-wifi-service-type
1479 (name 'simulated-wifi)
1481 (list (service-extension shepherd-root-service-type
1482 simulated-wifi-shepherd-services)
1483 (service-extension kernel-module-loader-service-type
1484 (const '("mac80211_hwsim")))))
1485 (default-value (hostapd-configuration
1487 (ssid "Test Network")))
1488 (description "Run hostapd to simulate WiFi connectivity.")))
1495 (define-record-type* <openvswitch-configuration>
1496 openvswitch-configuration make-openvswitch-configuration
1497 openvswitch-configuration?
1498 (package openvswitch-configuration-package
1499 (default openvswitch)))
1501 (define openvswitch-activation
1503 (($ <openvswitch-configuration> package)
1504 (let ((ovsdb-tool (file-append package "/bin/ovsdb-tool")))
1505 (with-imported-modules '((guix build utils))
1507 (use-modules (guix build utils))
1508 (mkdir-p "/var/run/openvswitch")
1509 (mkdir-p "/var/lib/openvswitch")
1510 (let ((conf.db "/var/lib/openvswitch/conf.db"))
1511 (unless (file-exists? conf.db)
1512 (system* #$ovsdb-tool "create" conf.db)))))))))
1514 (define openvswitch-shepherd-service
1516 (($ <openvswitch-configuration> package)
1517 (let ((ovsdb-server (file-append package "/sbin/ovsdb-server"))
1518 (ovs-vswitchd (file-append package "/sbin/ovs-vswitchd")))
1521 (provision '(ovsdb))
1522 (documentation "Run the Open vSwitch database server.")
1523 (start #~(make-forkexec-constructor
1524 (list #$ovsdb-server "--pidfile"
1525 "--remote=punix:/var/run/openvswitch/db.sock")
1526 #:pid-file "/var/run/openvswitch/ovsdb-server.pid"))
1527 (stop #~(make-kill-destructor)))
1529 (provision '(vswitchd))
1530 (requirement '(ovsdb))
1531 (documentation "Run the Open vSwitch daemon.")
1532 (start #~(make-forkexec-constructor
1533 (list #$ovs-vswitchd "--pidfile")
1534 #:pid-file "/var/run/openvswitch/ovs-vswitchd.pid"))
1535 (stop #~(make-kill-destructor))))))))
1537 (define openvswitch-service-type
1541 (list (service-extension activation-service-type
1542 openvswitch-activation)
1543 (service-extension profile-service-type
1544 (compose list openvswitch-configuration-package))
1545 (service-extension shepherd-root-service-type
1546 openvswitch-shepherd-service)))
1548 "Run @uref{http://www.openvswitch.org, Open vSwitch}, a multilayer virtual
1549 switch designed to enable massive network automation through programmatic
1551 (default-value (openvswitch-configuration))))
1557 (define %iptables-accept-all-rules
1558 (plain-file "iptables-accept-all.rules"
1566 (define-record-type* <iptables-configuration>
1567 iptables-configuration make-iptables-configuration iptables-configuration?
1568 (iptables iptables-configuration-iptables
1570 (ipv4-rules iptables-configuration-ipv4-rules
1571 (default %iptables-accept-all-rules))
1572 (ipv6-rules iptables-configuration-ipv6-rules
1573 (default %iptables-accept-all-rules)))
1575 (define iptables-shepherd-service
1577 (($ <iptables-configuration> iptables ipv4-rules ipv6-rules)
1578 (let ((iptables-restore (file-append iptables "/sbin/iptables-restore"))
1579 (ip6tables-restore (file-append iptables "/sbin/ip6tables-restore")))
1581 (documentation "Packet filtering framework")
1582 (provision '(iptables))
1584 (invoke #$iptables-restore #$ipv4-rules)
1585 (invoke #$ip6tables-restore #$ipv6-rules)))
1587 (invoke #$iptables-restore #$%iptables-accept-all-rules)
1588 (invoke #$ip6tables-restore #$%iptables-accept-all-rules))))))))
1590 (define iptables-service-type
1594 "Run @command{iptables-restore}, setting up the specified rules.")
1596 (list (service-extension shepherd-root-service-type
1597 (compose list iptables-shepherd-service))))))
1603 (define %default-nftables-ruleset
1604 (plain-file "nftables.conf"
1605 "# A simple and safe firewall
1608 type filter hook input priority 0; policy drop;
1610 # early drop of invalid connections
1611 ct state invalid drop
1613 # allow established/related connections
1614 ct state { established, related } accept
1616 # allow from loopback
1620 ip protocol icmp accept
1621 ip6 nexthdr icmpv6 accept
1624 tcp dport ssh accept
1626 # reject everything else
1627 reject with icmpx type port-unreachable
1630 type filter hook forward priority 0; policy drop;
1633 type filter hook output priority 0; policy accept;
1638 (define-record-type* <nftables-configuration>
1639 nftables-configuration
1640 make-nftables-configuration
1641 nftables-configuration?
1642 (package nftables-configuration-package
1644 (ruleset nftables-configuration-ruleset ; file-like object
1645 (default %default-nftables-ruleset)))
1647 (define nftables-shepherd-service
1649 (($ <nftables-configuration> package ruleset)
1650 (let ((nft (file-append package "/sbin/nft")))
1652 (documentation "Packet filtering and classification")
1653 (provision '(nftables))
1655 (invoke #$nft "--file" #$ruleset)))
1657 (invoke #$nft "flush" "ruleset"))))))))
1659 (define nftables-service-type
1663 "Run @command{nft}, setting up the specified ruleset.")
1665 (list (service-extension shepherd-root-service-type
1666 (compose list nftables-shepherd-service))
1667 (service-extension profile-service-type
1668 (compose list nftables-configuration-package))))
1669 (default-value (nftables-configuration))))
1676 (define-record-type* <pagekite-configuration>
1677 pagekite-configuration
1678 make-pagekite-configuration
1679 pagekite-configuration?
1680 (package pagekite-configuration-package
1682 (kitename pagekite-configuration-kitename
1684 (kitesecret pagekite-configuration-kitesecret
1686 (frontend pagekite-configuration-frontend
1688 (kites pagekite-configuration-kites
1689 (default '("http:@kitename:localhost:80:@kitesecret")))
1690 (extra-file pagekite-configuration-extra-file
1693 (define (pagekite-configuration-file config)
1694 (match-record config <pagekite-configuration>
1695 (package kitename kitesecret frontend kites extra-file)
1696 (mixed-text-file "pagekite.rc"
1698 (string-append "optfile = " extra-file "\n")
1701 (string-append "kitename = " kitename "\n")
1704 (string-append "kitesecret = " kitesecret "\n")
1707 (string-append "frontend = " frontend "\n")
1709 (string-join (map (lambda (kite)
1710 (string-append "service_on = " kite))
1715 (define (pagekite-shepherd-service config)
1716 (match-record config <pagekite-configuration>
1717 (package kitename kitesecret frontend kites extra-file)
1718 (with-imported-modules (source-module-closure
1719 '((gnu build shepherd)
1720 (gnu system file-systems)))
1722 (documentation "Run the PageKite service.")
1723 (provision '(pagekite))
1724 (requirement '(networking))
1725 (modules '((gnu build shepherd)
1726 (gnu system file-systems)))
1727 (start #~(make-forkexec-constructor/container
1728 (list #$(file-append package "/bin/pagekite")
1732 "--runas=pagekite:pagekite"
1733 (string-append "--optfile="
1734 #$(pagekite-configuration-file config)))
1735 #:log-file "/var/log/pagekite.log"
1736 #:mappings #$(if extra-file
1737 #~(list (file-system-mapping
1738 (source #$extra-file)
1741 ;; SIGTERM doesn't always work for some reason.
1742 (stop #~(make-kill-destructor SIGINT))))))
1744 (define %pagekite-accounts
1745 (list (user-group (name "pagekite") (system? #t))
1750 (comment "PageKite user")
1751 (home-directory "/var/empty")
1752 (shell (file-append shadow "/sbin/nologin")))))
1754 (define pagekite-service-type
1757 (default-value (pagekite-configuration))
1759 (list (service-extension shepherd-root-service-type
1760 (compose list pagekite-shepherd-service))
1761 (service-extension account-service-type
1762 (const %pagekite-accounts))))
1764 "Run @url{https://pagekite.net/,PageKite}, a tunneling solution to make
1765 local servers publicly accessible on the web, even behind NATs and firewalls.")))
1772 (define-record-type* <yggdrasil-configuration>
1773 yggdrasil-configuration
1774 make-yggdrasil-configuration
1775 yggdrasil-configuration?
1776 (package yggdrasil-configuration-package
1777 (default yggdrasil))
1778 (json-config yggdrasil-configuration-json-config
1780 (config-file yggdrasil-config-file
1781 (default "/etc/yggdrasil-private.conf"))
1782 (autoconf? yggdrasil-configuration-autoconf?
1784 (log-level yggdrasil-configuration-log-level
1786 (log-to yggdrasil-configuration-log-to
1789 (define (yggdrasil-configuration-file config)
1790 (define (scm->yggdrasil-json x)
1793 (define (param->camel str)
1797 (string-split str (cut eqv? <> #\-)))))
1804 (param->camel (symbol->string k))
1807 ((list? x) (map scm->yggdrasil-json x))
1808 ((vector? x) (vector-map scm->yggdrasil-json x))
1812 #~(call-with-output-file #$output
1814 ;; it's HJSON, so comments are a-okay
1815 (display "# Generated by yggdrasil-service\n" port)
1816 (display #$(scm->json-string
1817 (scm->yggdrasil-json
1818 (yggdrasil-configuration-json-config config)))
1821 (define (yggdrasil-shepherd-service config)
1822 "Return a <shepherd-service> for yggdrasil with CONFIG."
1823 (define yggdrasil-command
1825 (list (string-append
1826 #$(yggdrasil-configuration-package config)
1829 #$(yggdrasil-configuration-file config))
1830 (if #$(yggdrasil-configuration-autoconf? config)
1833 (let ((extraconf #$(yggdrasil-config-file config)))
1835 (list "-extraconffile" extraconf)
1839 (yggdrasil-configuration-log-level config))
1842 (yggdrasil-configuration-log-to config)))))
1843 (list (shepherd-service
1844 (documentation "Connect to the Yggdrasil mesh network")
1845 (provision '(yggdrasil))
1846 (requirement '(networking))
1847 (start #~(make-forkexec-constructor
1849 #:log-file "/var/log/yggdrasil.log"
1850 #:group "yggdrasil"))
1851 (stop #~(make-kill-destructor)))))
1853 (define %yggdrasil-accounts
1854 (list (user-group (name "yggdrasil") (system? #t))))
1856 (define yggdrasil-service-type
1860 "Connect to the Yggdrasil mesh network.
1861 See yggdrasil -genconf for config options.")
1863 (list (service-extension shepherd-root-service-type
1864 yggdrasil-shepherd-service)
1865 (service-extension account-service-type
1866 (const %yggdrasil-accounts))
1867 (service-extension profile-service-type
1868 (compose list yggdrasil-configuration-package))))))
1875 (define-record-type* <keepalived-configuration>
1876 keepalived-configuration make-keepalived-configuration
1877 keepalived-configuration?
1878 (keepalived keepalived-configuration-keepalived ;<package>
1879 (default keepalived))
1880 (config-file keepalived-configuration-config-file ;file-like
1883 (define keepalived-shepherd-service
1885 (($ <keepalived-configuration> keepalived config-file)
1888 (provision '(keepalived))
1889 (documentation "Run keepalived.")
1890 (requirement '(loopback))
1891 (start #~(make-forkexec-constructor
1892 (list (string-append #$keepalived "/sbin/keepalived")
1893 "--dont-fork" "--log-console" "--log-detail"
1894 "--pid=/var/run/keepalived.pid"
1895 (string-append "--use-file=" #$config-file))
1896 #:pid-file "/var/run/keepalived.pid"
1897 #:log-file "/var/log/keepalived.log"))
1899 (stop #~(make-kill-destructor)))))))
1901 (define keepalived-service-type
1902 (service-type (name 'keepalived)
1903 (extensions (list (service-extension shepherd-root-service-type
1904 keepalived-shepherd-service)))
1906 "Run @uref{https://www.keepalived.org/, Keepalived}
1907 routing software.")))
1909 ;;; networking.scm ends here