1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
4 ;;; Copyright © 2016, 2018 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>
15 ;;; This file is part of GNU Guix.
17 ;;; GNU Guix is free software; you can redistribute it and/or modify it
18 ;;; under the terms of the GNU General Public License as published by
19 ;;; the Free Software Foundation; either version 3 of the License, or (at
20 ;;; your option) any later version.
22 ;;; GNU Guix is distributed in the hope that it will be useful, but
23 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
24 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 ;;; GNU General Public License for more details.
27 ;;; You should have received a copy of the GNU General Public License
28 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
30 (define-module (gnu services networking)
31 #:use-module (gnu services)
32 #:use-module (gnu services base)
33 #:use-module (gnu services shepherd)
34 #:use-module (gnu services dbus)
35 #:use-module (gnu system shadow)
36 #:use-module (gnu system pam)
37 #:use-module (gnu packages admin)
38 #:use-module (gnu packages base)
39 #:use-module (gnu packages bash)
40 #:use-module (gnu packages connman)
41 #:use-module (gnu packages freedesktop)
42 #:use-module (gnu packages linux)
43 #:use-module (gnu packages tor)
44 #:use-module (gnu packages usb-modeswitch)
45 #:use-module (gnu packages messaging)
46 #:use-module (gnu packages networking)
47 #:use-module (gnu packages ntp)
48 #:use-module (gnu packages wicd)
49 #:use-module (gnu packages gnome)
50 #:use-module (guix gexp)
51 #:use-module (guix records)
52 #:use-module (guix modules)
53 #:use-module (guix deprecation)
54 #:use-module (rnrs enums)
55 #:use-module (srfi srfi-1)
56 #:use-module (srfi srfi-9)
57 #:use-module (srfi srfi-26)
58 #:use-module (ice-9 match)
59 #:re-export (static-networking-service
60 static-networking-service-type)
61 #:export (%facebook-host-aliases
63 dhcp-client-service-type
68 dhcpd-configuration-package
69 dhcpd-configuration-config-file
70 dhcpd-configuration-version
71 dhcpd-configuration-run-directory
72 dhcpd-configuration-lease-file
73 dhcpd-configuration-pid-file
74 dhcpd-configuration-interfaces
79 ntp-configuration-servers
80 ntp-allow-large-adjustment?
92 openntpd-configuration
93 openntpd-configuration?
109 network-manager-configuration
110 network-manager-configuration?
111 network-manager-configuration-dns
112 network-manager-service-type
114 connman-configuration
115 connman-configuration?
118 modem-manager-configuration
119 modem-manager-configuration?
120 modem-manager-service-type
122 usb-modeswitch-configuration
123 usb-modeswitch-configuration?
124 usb-modeswitch-configuration-usb-modeswitch
125 usb-modeswitch-configuration-usb-modeswitch-data
126 usb-modeswitch-service-type
128 <wpa-supplicant-configuration>
129 wpa-supplicant-configuration
130 wpa-supplicant-configuration?
131 wpa-supplicant-configuration-wpa-supplicant
132 wpa-supplicant-configuration-pid-file
133 wpa-supplicant-configuration-dbus?
134 wpa-supplicant-configuration-interface
135 wpa-supplicant-configuration-config-file
136 wpa-supplicant-configuration-extra-options
137 wpa-supplicant-service-type
139 openvswitch-service-type
140 openvswitch-configuration
142 iptables-configuration
143 iptables-configuration?
144 iptables-configuration-iptables
145 iptables-configuration-ipv4-rules
146 iptables-configuration-ipv6-rules
147 iptables-service-type))
151 ;;; Networking services.
155 (define %facebook-host-aliases
156 ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
159 # Block Facebook IPv4.
160 127.0.0.1 www.facebook.com
161 127.0.0.1 facebook.com
162 127.0.0.1 login.facebook.com
163 127.0.0.1 www.login.facebook.com
165 127.0.0.1 www.fbcdn.net
167 127.0.0.1 www.fbcdn.com
168 127.0.0.1 static.ak.fbcdn.net
169 127.0.0.1 static.ak.connect.facebook.com
170 127.0.0.1 connect.facebook.net
171 127.0.0.1 www.connect.facebook.net
172 127.0.0.1 apps.facebook.com
174 # Block Facebook IPv6.
175 fe80::1%lo0 facebook.com
176 fe80::1%lo0 login.facebook.com
177 fe80::1%lo0 www.login.facebook.com
178 fe80::1%lo0 fbcdn.net
179 fe80::1%lo0 www.fbcdn.net
180 fe80::1%lo0 fbcdn.com
181 fe80::1%lo0 www.fbcdn.com
182 fe80::1%lo0 static.ak.fbcdn.net
183 fe80::1%lo0 static.ak.connect.facebook.com
184 fe80::1%lo0 connect.facebook.net
185 fe80::1%lo0 www.connect.facebook.net
186 fe80::1%lo0 apps.facebook.com\n")
188 (define dhcp-client-service-type
189 (shepherd-service-type
193 (file-append dhcp "/sbin/dhclient"))
196 "/var/run/dhclient.pid")
199 (documentation "Set up networking via DHCP.")
200 (requirement '(user-processes udev))
202 ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
203 ;; networking is unavailable, but also means that the interface is not up
204 ;; yet when 'start' completes. To wait for the interface to be ready, one
205 ;; should instead monitor udev events.
206 (provision '(networking))
209 ;; When invoked without any arguments, 'dhclient' discovers all
210 ;; non-loopback interfaces *that are up*. However, the relevant
211 ;; interfaces are typically down at this point. Thus we perform
212 ;; our own interface discovery here.
215 (and (arp-network-interface? interface)
216 (not (loopback-network-interface? interface)))))
218 (filter valid? (all-network-interface-names)))
220 ;; XXX: Make sure the interfaces are up so that 'dhclient' can
221 ;; actually send/receive over them.
222 (for-each set-network-interface-up ifaces)
224 (false-if-exception (delete-file #$pid-file))
225 (let ((pid (fork+exec-command
226 (cons* #$dhclient "-nw"
227 "-pf" #$pid-file ifaces))))
228 (and (zero? (cdr (waitpid pid)))
229 (read-pid-file #$pid-file)))))
230 (stop #~(make-kill-destructor))))
233 (define-deprecated (dhcp-client-service #:key (dhcp isc-dhcp))
234 dhcp-client-service-type
235 "Return a service that runs @var{dhcp}, a Dynamic Host Configuration
236 Protocol (DHCP) client, on all the non-loopback network interfaces."
237 (service dhcp-client-service-type dhcp))
239 (define-record-type* <dhcpd-configuration>
240 dhcpd-configuration make-dhcpd-configuration
242 (package dhcpd-configuration-package ;<package>
244 (config-file dhcpd-configuration-config-file ;file-like
246 (version dhcpd-configuration-version ;"4", "6", or "4o6"
248 (run-directory dhcpd-configuration-run-directory
249 (default "/run/dhcpd"))
250 (lease-file dhcpd-configuration-lease-file
251 (default "/var/db/dhcpd.leases"))
252 (pid-file dhcpd-configuration-pid-file
253 (default "/run/dhcpd/dhcpd.pid"))
254 ;; list of strings, e.g. (list "enp0s25")
255 (interfaces dhcpd-configuration-interfaces
258 (define dhcpd-shepherd-service
260 (($ <dhcpd-configuration> package config-file version run-directory
261 lease-file pid-file interfaces)
263 (error "Must supply a config-file"))
264 (list (shepherd-service
265 ;; Allow users to easily run multiple versions simultaneously.
266 (provision (list (string->symbol
267 (string-append "dhcpv" version "-daemon"))))
268 (documentation (string-append "Run the DHCPv" version " daemon"))
269 (requirement '(networking))
270 (start #~(make-forkexec-constructor
271 '(#$(file-append package "/sbin/dhcpd")
272 #$(string-append "-" version)
277 #:pid-file #$pid-file))
278 (stop #~(make-kill-destructor)))))))
280 (define dhcpd-activation
282 (($ <dhcpd-configuration> package config-file version run-directory
283 lease-file pid-file interfaces)
284 (with-imported-modules '((guix build utils))
286 (unless (file-exists? #$run-directory)
287 (mkdir #$run-directory))
288 ;; According to the DHCP manual (man dhcpd.leases), the lease
289 ;; database must be present for dhcpd to start successfully.
290 (unless (file-exists? #$lease-file)
291 (with-output-to-file #$lease-file
292 (lambda _ (display ""))))
293 ;; Validate the config.
295 #$(file-append package "/sbin/dhcpd") "-t" "-cf"
298 (define dhcpd-service-type
302 (list (service-extension shepherd-root-service-type dhcpd-shepherd-service)
303 (service-extension activation-service-type dhcpd-activation)))))
310 (define ntp-server-types (make-enumeration
317 (define-record-type* <ntp-server>
318 ntp-server make-ntp-server
320 ;; The type can be one of the symbols of the NTP-SERVER-TYPE? enumeration.
321 (type ntp-server-type
323 (address ntp-server-address) ; a string
324 ;; The list of options can contain single option names or tuples in the form
326 (options ntp-server-options
329 (define (ntp-server->string ntp-server)
330 ;; Serialize the NTP server object as a string, ready to use in the NTP
331 ;; configuration file.
332 (define (flatten lst)
338 (cons (format #f "~s" x) res)))))
341 (($ <ntp-server> type address options)
342 ;; XXX: It'd be neater if fields were validated at the syntax level (for
343 ;; static ones at least). Perhaps the Guix record type could support a
344 ;; predicate property on a field?
345 (unless (enum-set-member? type ntp-server-types)
346 (error "Invalid NTP server type" type))
347 (string-join (cons* (symbol->string type)
349 (flatten options))))))
352 ;; Default set of NTP servers. These URLs are managed by the NTP Pool project.
353 ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact
354 ;; for this NTP pool "zone".
358 (address "0.guix.pool.ntp.org")
359 (options '("iburst"))))) ;as recommended in the ntpd manual
361 (define-record-type* <ntp-configuration>
362 ntp-configuration make-ntp-configuration
364 (ntp ntp-configuration-ntp
366 (servers %ntp-configuration-servers ;list of <ntp-server> objects
367 (default %ntp-servers))
368 (allow-large-adjustment? ntp-allow-large-adjustment?
369 (default #t))) ;as recommended in the ntpd manual
371 (define (ntp-configuration-servers ntp-configuration)
372 ;; A wrapper to support the deprecated form of this field.
373 (let ((ntp-servers (%ntp-configuration-servers ntp-configuration)))
375 (((? string?) (? string?) ...)
376 (format (current-error-port) "warning: Defining NTP servers as strings is \
377 deprecated. Please use <ntp-server> records instead.\n")
382 (options '()))) ntp-servers))
383 ((($ <ntp-server>) ($ <ntp-server>) ...)
386 (define ntp-shepherd-service
388 (($ <ntp-configuration> ntp servers allow-large-adjustment?)
390 ;; TODO: Add authentication support.
392 (string-append "driftfile /var/run/ntpd/ntp.drift\n"
393 (string-join (map ntp-server->string servers)
396 # Disable status queries as a workaround for CVE-2013-5211:
397 # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
398 restrict default kod nomodify notrap nopeer noquery limited
399 restrict -6 default kod nomodify notrap nopeer noquery limited
401 # Yet, allow use of the local 'ntpq'.
405 # This is required to use servers from a pool directive when using the 'nopeer'
406 # option by default, as documented in the 'ntp.conf' manual.
407 restrict source notrap nomodify noquery\n"))
410 (plain-file "ntpd.conf" config))
412 (list (shepherd-service
414 (documentation "Run the Network Time Protocol (NTP) daemon.")
415 (requirement '(user-processes networking))
416 (start #~(make-forkexec-constructor
417 (list (string-append #$ntp "/bin/ntpd") "-n"
418 "-c" #$ntpd.conf "-u" "ntpd"
419 #$@(if allow-large-adjustment?
422 (stop #~(make-kill-destructor))))))))
424 (define %ntp-accounts
429 (comment "NTP daemon user")
430 (home-directory "/var/empty")
431 (shell (file-append shadow "/sbin/nologin")))))
434 (define (ntp-service-activation config)
435 "Return the activation gexp for CONFIG."
436 (with-imported-modules '((guix build utils))
438 (use-modules (guix build utils))
442 (let ((directory "/var/run/ntpd"))
444 (chown directory (passwd:uid %user) (passwd:gid %user))))))
446 (define ntp-service-type
447 (service-type (name 'ntp)
449 (list (service-extension shepherd-root-service-type
450 ntp-shepherd-service)
451 (service-extension account-service-type
452 (const %ntp-accounts))
453 (service-extension activation-service-type
454 ntp-service-activation)))
456 "Run the @command{ntpd}, the Network Time Protocol (NTP)
457 daemon of the @uref{http://www.ntp.org, Network Time Foundation}. The daemon
458 will keep the system clock synchronized with that of the given servers.")
459 (default-value (ntp-configuration))))
461 (define-deprecated (ntp-service #:key (ntp ntp)
462 (servers %ntp-servers)
463 allow-large-adjustment?)
465 "Return a service that runs the daemon from @var{ntp}, the
466 @uref{http://www.ntp.org, Network Time Protocol package}. The daemon will
467 keep the system clock synchronized with that of @var{servers}.
468 @var{allow-large-adjustment?} determines whether @command{ntpd} is allowed to
469 make an initial adjustment of more than 1,000 seconds."
470 (service ntp-service-type
471 (ntp-configuration (ntp ntp)
473 (allow-large-adjustment?
474 allow-large-adjustment?))))
481 (define %openntpd-servers
482 (map ntp-server-address %ntp-servers))
484 (define-record-type* <openntpd-configuration>
485 openntpd-configuration make-openntpd-configuration
486 openntpd-configuration?
487 (openntpd openntpd-configuration-openntpd
489 (listen-on openntpd-listen-on
490 (default '("127.0.0.1"
492 (query-from openntpd-query-from
494 (sensor openntpd-sensor
496 (server openntpd-server
498 (servers openntpd-servers
499 (default %openntpd-servers))
500 (constraint-from openntpd-constraint-from
502 (constraints-from openntpd-constraints-from
504 (allow-large-adjustment? openntpd-allow-large-adjustment?
505 (default #f))) ; upstream default
507 (define (openntpd-configuration->string config)
508 (match-record config <openntpd-configuration>
509 (listen-on query-from sensor server servers constraint-from
513 (lambda (field value)
515 (map (cut string-append field <> "\n")
517 '("listen on " "query from " "sensor " "server " "servers "
519 (list listen-on query-from sensor server servers constraint-from))
520 ;; The 'constraints from' field needs to be enclosed in double quotes.
522 (map (cut string-append "constraints from \"" <> "\"\n")
523 constraints-from)))))
525 (define (openntpd-shepherd-service config)
526 (let ((openntpd (openntpd-configuration-openntpd config))
527 (allow-large-adjustment? (openntpd-allow-large-adjustment? config)))
530 (plain-file "ntpd.conf" (openntpd-configuration->string config)))
532 (list (shepherd-service
534 (documentation "Run the Network Time Protocol (NTP) daemon.")
535 (requirement '(user-processes networking))
536 (start #~(make-forkexec-constructor
537 (list (string-append #$openntpd "/sbin/ntpd")
539 "-d" ;; don't daemonize
540 #$@(if allow-large-adjustment?
543 ;; When ntpd is daemonized it repeatedly tries to respawn
544 ;; while running, leading shepherd to disable it. To
545 ;; prevent spamming stderr, redirect output to logfile.
546 #:log-file "/var/log/ntpd"))
547 (stop #~(make-kill-destructor))))))
549 (define (openntpd-service-activation config)
550 "Return the activation gexp for CONFIG."
551 (with-imported-modules '((guix build utils))
553 (use-modules (guix build utils))
557 (unless (file-exists? "/var/db/ntpd.drift")
558 (with-output-to-file "/var/db/ntpd.drift"
560 (format #t "0.0")))))))
562 (define openntpd-service-type
563 (service-type (name 'openntpd)
565 (list (service-extension shepherd-root-service-type
566 openntpd-shepherd-service)
567 (service-extension account-service-type
568 (const %ntp-accounts))
569 (service-extension profile-service-type
570 (compose list openntpd-configuration-openntpd))
571 (service-extension activation-service-type
572 openntpd-service-activation)))
573 (default-value (openntpd-configuration))
575 "Run the @command{ntpd}, the Network Time Protocol (NTP)
576 daemon, as implemented by @uref{http://www.openntpd.org, OpenNTPD}. The
577 daemon will keep the system clock synchronized with that of the given servers.")))
584 (define-record-type* <inetd-configuration> inetd-configuration
585 make-inetd-configuration
587 (program inetd-configuration-program ;file-like
588 (default (file-append inetutils "/libexec/inetd")))
589 (entries inetd-configuration-entries ;list of <inetd-entry>
592 (define-record-type* <inetd-entry> inetd-entry make-inetd-entry
594 (node inetd-entry-node ;string or #f
596 (name inetd-entry-name) ;string, from /etc/services
598 (socket-type inetd-entry-socket-type) ;stream | dgram | raw |
600 (protocol inetd-entry-protocol) ;string, from /etc/protocols
602 (wait? inetd-entry-wait? ;Boolean
604 (user inetd-entry-user) ;string
606 (program inetd-entry-program ;string or file-like object
607 (default "internal"))
608 (arguments inetd-entry-arguments ;list of strings or file-like objects
611 (define (inetd-config-file entries)
612 (apply mixed-text-file "inetd.conf"
615 (let* ((node (inetd-entry-node entry))
616 (name (inetd-entry-name entry))
618 (if node (string-append node ":" name) name))
620 (match (inetd-entry-socket-type entry)
621 ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
622 (symbol->string (inetd-entry-socket-type entry)))))
623 (protocol (inetd-entry-protocol entry))
624 (wait (if (inetd-entry-wait? entry) "wait" "nowait"))
625 (user (inetd-entry-user entry))
626 (program (inetd-entry-program entry))
627 (args (inetd-entry-arguments entry)))
630 (list #$@(list socket type protocol wait user program) #$@args)
634 (define inetd-shepherd-service
636 (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing
637 (($ <inetd-configuration> program entries)
640 (documentation "Run inetd.")
642 (requirement '(user-processes networking syslogd))
643 (start #~(make-forkexec-constructor
644 (list #$program #$(inetd-config-file entries))
645 #:pid-file "/var/run/inetd.pid"))
646 (stop #~(make-kill-destructor)))))))
648 (define-public inetd-service-type
652 (list (service-extension shepherd-root-service-type
653 inetd-shepherd-service)))
655 ;; The service can be extended with additional lists of entries.
656 (compose concatenate)
657 (extend (lambda (config entries)
660 (entries (append (inetd-configuration-entries config)
663 "Start @command{inetd}, the @dfn{Internet superserver}. It is responsible
664 for listening on Internet sockets and spawning the corresponding services on
672 (define-record-type* <tor-configuration>
673 tor-configuration make-tor-configuration
675 (tor tor-configuration-tor
677 (config-file tor-configuration-config-file
678 (default (plain-file "empty" "")))
679 (hidden-services tor-configuration-hidden-services
681 (socks-socket-type tor-configuration-socks-socket-type ; 'tcp or 'unix
684 (define %tor-accounts
685 ;; User account and groups for Tor.
686 (list (user-group (name "tor") (system? #t))
691 (comment "Tor daemon user")
692 (home-directory "/var/empty")
693 (shell (file-append shadow "/sbin/nologin")))))
695 (define-record-type <hidden-service>
696 (hidden-service name mapping)
698 (name hidden-service-name) ;string
699 (mapping hidden-service-mapping)) ;list of port/address tuples
701 (define (tor-configuration->torrc config)
702 "Return a 'torrc' file for CONFIG."
704 (($ <tor-configuration> tor config-file services socks-socket-type)
707 (with-imported-modules '((guix build utils))
709 (use-modules (guix build utils)
712 (call-with-output-file #$output
715 ### These lines were generated from your system configuration:
717 DataDirectory /var/lib/tor
718 PidFile /var/run/tor/tor.pid
719 Log notice syslog\n" port)
720 (when (eq? 'unix '#$socks-socket-type)
722 SocksPort unix:/var/run/tor/socks-sock
723 UnixSocksGroupWritable 1\n" port))
725 (for-each (match-lambda
726 ((service (ports hosts) ...)
728 HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
730 (for-each (lambda (tcp-port host)
732 HiddenServicePort ~a ~a~%"
735 '#$(map (match-lambda
736 (($ <hidden-service> name mapping)
737 (cons name mapping)))
741 ### End of automatically generated lines.\n\n" port)
743 ;; Append the user's config file.
744 (call-with-input-file #$config-file
746 (dump-port input port)))
749 (define (tor-shepherd-service config)
750 "Return a <shepherd-service> running Tor."
752 (($ <tor-configuration> tor)
753 (let ((torrc (tor-configuration->torrc config)))
754 (with-imported-modules (source-module-closure
755 '((gnu build shepherd)
756 (gnu system file-systems)))
757 (list (shepherd-service
760 ;; Tor needs at least one network interface to be up, hence the
761 ;; dependency on 'loopback'.
762 (requirement '(user-processes loopback syslogd))
764 (modules '((gnu build shepherd)
765 (gnu system file-systems)))
767 (start #~(make-forkexec-constructor/container
768 (list #$(file-append tor "/bin/tor") "-f" #$torrc)
770 #:mappings (list (file-system-mapping
771 (source "/var/lib/tor")
775 (source "/dev/log") ;for syslog
778 (source "/var/run/tor")
781 #:pid-file "/var/run/tor/tor.pid"))
782 (stop #~(make-kill-destructor))
783 (documentation "Run the Tor anonymous network overlay."))))))))
785 (define (tor-activation config)
786 "Set up directories for Tor and its hidden services, if any."
788 (use-modules (guix build utils))
793 (define (initialize service)
794 (let ((directory (string-append "/var/lib/tor/hidden-services/"
797 (chown directory (passwd:uid %user) (passwd:gid %user))
799 ;; The daemon bails out if we give wider permissions.
800 (chmod directory #o700)))
802 ;; Allow Tor to write its PID file.
803 (mkdir-p "/var/run/tor")
804 (chown "/var/run/tor" (passwd:uid %user) (passwd:gid %user))
805 ;; Set the group permissions to rw so that if the system administrator
806 ;; has specified UnixSocksGroupWritable=1 in their torrc file, members
807 ;; of the "tor" group will be able to use the SOCKS socket.
808 (chmod "/var/run/tor" #o750)
810 ;; Allow Tor to access the hidden services' directories.
811 (mkdir-p "/var/lib/tor")
812 (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
813 (chmod "/var/lib/tor" #o700)
815 ;; Make sure /var/lib is accessible to the 'tor' user.
816 (chmod "/var/lib" #o755)
819 '#$(map hidden-service-name
820 (tor-configuration-hidden-services config)))))
822 (define tor-service-type
823 (service-type (name 'tor)
825 (list (service-extension shepherd-root-service-type
826 tor-shepherd-service)
827 (service-extension account-service-type
828 (const %tor-accounts))
829 (service-extension activation-service-type
832 ;; This can be extended with hidden services.
833 (compose concatenate)
834 (extend (lambda (config services)
838 (append (tor-configuration-hidden-services config)
840 (default-value (tor-configuration))
842 "Run the @uref{https://torproject.org, Tor} anonymous
843 networking daemon.")))
845 (define-deprecated (tor-service #:optional
846 (config-file (plain-file "empty" ""))
849 "Return a service to run the @uref{https://torproject.org, Tor} anonymous
852 The daemon runs as the @code{tor} unprivileged user. It is passed
853 @var{config-file}, a file-like object, with an additional @code{User tor} line
854 and lines for hidden services added via @code{tor-hidden-service}. Run
855 @command{man tor} for information about the configuration file."
856 (service tor-service-type
857 (tor-configuration (tor tor)
858 (config-file config-file))))
860 (define tor-hidden-service-type
861 ;; A type that extends Tor with hidden services.
862 (service-type (name 'tor-hidden-service)
864 (list (service-extension tor-service-type list)))
866 "Define a new Tor @dfn{hidden service}.")))
868 (define (tor-hidden-service name mapping)
869 "Define a new Tor @dfn{hidden service} called @var{name} and implementing
870 @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
873 '((22 \"127.0.0.1:22\")
874 (80 \"127.0.0.1:8080\"))
877 In this example, port 22 of the hidden service is mapped to local port 22, and
878 port 80 is mapped to local port 8080.
880 This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
881 the @file{hostname} file contains the @code{.onion} host name for the hidden
884 See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
885 project's documentation} for more information."
886 (service tor-hidden-service-type
887 (hidden-service name mapping)))
894 (define %wicd-activation
895 ;; Activation gexp for Wicd.
897 (use-modules (guix build utils))
899 (mkdir-p "/etc/wicd")
900 (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
901 (unless (file-exists? file-name)
902 (copy-file (string-append #$wicd file-name)
905 ;; Wicd invokes 'wpa_supplicant', which needs this directory for its
906 ;; named socket files.
907 (mkdir-p "/var/run/wpa_supplicant")
908 (chmod "/var/run/wpa_supplicant" #o750)))
910 (define (wicd-shepherd-service wicd)
911 "Return a shepherd service for WICD."
912 (list (shepherd-service
913 (documentation "Run the Wicd network manager.")
914 (provision '(networking))
915 (requirement '(user-processes dbus-system loopback))
916 (start #~(make-forkexec-constructor
917 (list (string-append #$wicd "/sbin/wicd")
919 (stop #~(make-kill-destructor)))))
921 (define wicd-service-type
922 (service-type (name 'wicd)
924 (list (service-extension shepherd-root-service-type
925 wicd-shepherd-service)
926 (service-extension dbus-root-service-type
928 (service-extension activation-service-type
929 (const %wicd-activation))
931 ;; Add Wicd to the global profile.
932 (service-extension profile-service-type list)))
934 "Run @url{https://launchpad.net/wicd,Wicd}, a network
935 management daemon that aims to simplify wired and wireless networking.")))
937 (define* (wicd-service #:key (wicd wicd))
938 "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
939 management daemon that aims to simplify wired and wireless networking.
941 This service adds the @var{wicd} package to the global profile, providing
942 several commands to interact with the daemon and configure networking:
943 @command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
944 and @command{wicd-curses} user interfaces."
945 (service wicd-service-type wicd))
952 (define-record-type* <modem-manager-configuration>
953 modem-manager-configuration make-modem-manager-configuration
954 modem-manager-configuration?
955 (modem-manager modem-manager-configuration-modem-manager
956 (default modem-manager)))
963 (define-record-type* <network-manager-configuration>
964 network-manager-configuration make-network-manager-configuration
965 network-manager-configuration?
966 (network-manager network-manager-configuration-network-manager
967 (default network-manager))
968 (dns network-manager-configuration-dns
970 (vpn-plugins network-manager-vpn-plugins ;list of <package>
973 (define network-manager-activation
974 ;; Activation gexp for NetworkManager
976 (($ <network-manager-configuration> network-manager dns vpn-plugins)
978 (use-modules (guix build utils))
979 (mkdir-p "/etc/NetworkManager/system-connections")
980 #$@(if (equal? dns "dnsmasq")
981 ;; create directory to store dnsmasq lease file
982 '((mkdir-p "/var/lib/misc"))
985 (define (vpn-plugin-directory plugins)
986 "Return a directory containing PLUGINS, the NM VPN plugins."
987 (directory-union "network-manager-vpn-plugins" plugins))
989 (define network-manager-environment
991 (($ <network-manager-configuration> network-manager dns vpn-plugins)
992 ;; Define this variable in the global environment such that
993 ;; "nmcli connection import type openvpn file foo.ovpn" works.
994 `(("NM_VPN_PLUGIN_DIR"
995 . ,(file-append (vpn-plugin-directory vpn-plugins)
996 "/lib/NetworkManager/VPN"))))))
998 (define network-manager-shepherd-service
1000 (($ <network-manager-configuration> network-manager dns vpn-plugins)
1001 (let ((conf (plain-file "NetworkManager.conf"
1002 (string-append "[main]\ndns=" dns "\n")))
1003 (vpn (vpn-plugin-directory vpn-plugins)))
1004 (list (shepherd-service
1005 (documentation "Run the NetworkManager.")
1006 (provision '(networking))
1007 (requirement '(user-processes dbus-system wpa-supplicant loopback))
1008 (start #~(make-forkexec-constructor
1009 (list (string-append #$network-manager
1010 "/sbin/NetworkManager")
1011 (string-append "--config=" #$conf)
1013 #:environment-variables
1014 (list (string-append "NM_VPN_PLUGIN_DIR=" #$vpn
1015 "/lib/NetworkManager/VPN")
1016 ;; Override non-existent default users
1018 "NM_OPENVPN_GROUP=")))
1019 (stop #~(make-kill-destructor))))))))
1021 (define network-manager-service-type
1025 (($ <network-manager-configuration> network-manager _ vpn-plugins)
1026 `(,network-manager ,@vpn-plugins)))))
1029 (name 'network-manager)
1031 (list (service-extension shepherd-root-service-type
1032 network-manager-shepherd-service)
1033 (service-extension dbus-root-service-type config->packages)
1034 (service-extension polkit-service-type
1037 network-manager-configuration-network-manager))
1038 (service-extension activation-service-type
1039 network-manager-activation)
1040 (service-extension session-environment-service-type
1041 network-manager-environment)
1042 ;; Add network-manager to the system profile.
1043 (service-extension profile-service-type config->packages)))
1044 (default-value (network-manager-configuration))
1046 "Run @uref{https://wiki.gnome.org/Projects/NetworkManager,
1047 NetworkManager}, a network management daemon that aims to simplify wired and
1048 wireless networking."))))
1055 (define-record-type* <connman-configuration>
1056 connman-configuration make-connman-configuration
1057 connman-configuration?
1058 (connman connman-configuration-connman
1060 (disable-vpn? connman-configuration-disable-vpn?
1063 (define (connman-activation config)
1064 (let ((disable-vpn? (connman-configuration-disable-vpn? config)))
1065 (with-imported-modules '((guix build utils))
1067 (use-modules (guix build utils))
1068 (mkdir-p "/var/lib/connman/")
1069 (unless #$disable-vpn?
1070 (mkdir-p "/var/lib/connman-vpn/"))))))
1072 (define (connman-shepherd-service config)
1073 "Return a shepherd service for Connman"
1075 (connman-configuration? config)
1076 (let ((connman (connman-configuration-connman config))
1077 (disable-vpn? (connman-configuration-disable-vpn? config)))
1078 (list (shepherd-service
1079 (documentation "Run Connman")
1080 (provision '(networking))
1082 '(user-processes dbus-system loopback wpa-supplicant))
1083 (start #~(make-forkexec-constructor
1084 (list (string-append #$connman
1087 #$@(if disable-vpn? '("--noplugin=vpn") '()))
1089 ;; As connman(8) notes, when passing '-n', connman
1090 ;; "directs log output to the controlling terminal in
1091 ;; addition to syslog." Redirect stdout and stderr
1092 ;; to avoid spamming the console (XXX: for some reason
1093 ;; redirecting to /dev/null doesn't work.)
1094 #:log-file "/var/log/connman.log"))
1095 (stop #~(make-kill-destructor)))))))
1097 (define connman-service-type
1098 (let ((connman-package (compose list connman-configuration-connman)))
1099 (service-type (name 'connman)
1101 (list (service-extension shepherd-root-service-type
1102 connman-shepherd-service)
1103 (service-extension polkit-service-type
1105 (service-extension dbus-root-service-type
1107 (service-extension activation-service-type
1109 ;; Add connman to the system profile.
1110 (service-extension profile-service-type
1112 (default-value (connman-configuration))
1114 "Run @url{https://01.org/connman,Connman},
1115 a network connection manager."))))
1122 (define modem-manager-service-type
1123 (let ((config->package
1125 (($ <modem-manager-configuration> modem-manager)
1126 (list modem-manager)))))
1127 (service-type (name 'modem-manager)
1129 (list (service-extension dbus-root-service-type
1131 (service-extension udev-service-type
1133 (service-extension polkit-service-type
1135 (default-value (modem-manager-configuration))
1137 "Run @uref{https://wiki.gnome.org/Projects/ModemManager,
1138 ModemManager}, a modem management daemon that aims to simplify dialup
1146 (define-record-type* <usb-modeswitch-configuration>
1147 usb-modeswitch-configuration make-usb-modeswitch-configuration
1148 usb-modeswitch-configuration?
1149 (usb-modeswitch usb-modeswitch-configuration-usb-modeswitch
1150 (default usb-modeswitch))
1151 (usb-modeswitch-data usb-modeswitch-configuration-usb-modeswitch-data
1152 (default usb-modeswitch-data))
1153 (config-file usb-modeswitch-configuration-config-file
1154 (default #~(string-append #$usb-modeswitch:dispatcher
1155 "/etc/usb_modeswitch.conf"))))
1157 (define (usb-modeswitch-sh usb-modeswitch config-file)
1158 "Build a copy of usb_modeswitch.sh located in package USB-MODESWITCH,
1159 modified to pass the CONFIG-FILE in its calls to usb_modeswitch_dispatcher,
1160 and wrap it to actually find the dispatcher in USB-MODESWITCH. The script
1161 will be run by USB_ModeSwitch’s udev rules file when a modeswitchable USB
1162 device is detected."
1165 (with-imported-modules '((guix build utils))
1167 (use-modules (guix build utils))
1170 #~(string-append " --config-file=" #$config-file)
1173 (install-file (string-append #$usb-modeswitch:dispatcher
1174 "/lib/udev/usb_modeswitch")
1177 ;; insert CFG-PARAM into usb_modeswitch_dispatcher command-lines
1178 (substitute* (string-append #$output "/usb_modeswitch")
1179 (("(exec usb_modeswitch_dispatcher .*)( 2>>)" _ left right)
1180 (string-append left cfg-param right))
1181 (("(exec usb_modeswitch_dispatcher .*)( &)" _ left right)
1182 (string-append left cfg-param right)))
1184 ;; wrap-program needs bash in PATH:
1185 (putenv (string-append "PATH=" #$bash "/bin"))
1186 (wrap-program (string-append #$output "/usb_modeswitch")
1187 `("PATH" ":" = (,(string-append #$coreutils "/bin")
1189 #$usb-modeswitch:dispatcher
1192 (define (usb-modeswitch-configuration->udev-rules config)
1193 "Build a rules file for extending udev-service-type from the rules in the
1194 usb-modeswitch package specified in CONFIG. The rules file will invoke
1195 usb_modeswitch.sh from the usb-modeswitch package, modified to pass the right
1198 (($ <usb-modeswitch-configuration> usb-modeswitch data config-file)
1200 "usb_modeswitch.rules"
1201 (with-imported-modules '((guix build utils))
1203 (use-modules (guix build utils))
1204 (let ((in (string-append #$data "/udev/40-usb_modeswitch.rules"))
1205 (out (string-append #$output "/lib/udev/rules.d"))
1206 (script #$(usb-modeswitch-sh usb-modeswitch config-file)))
1209 (install-file in out)
1210 (substitute* "40-usb_modeswitch.rules"
1211 (("PROGRAM=\"usb_modeswitch")
1212 (string-append "PROGRAM=\"" script "/usb_modeswitch"))
1213 (("RUN\\+=\"usb_modeswitch")
1214 (string-append "RUN+=\"" script "/usb_modeswitch"))))))))))
1216 (define usb-modeswitch-service-type
1218 (name 'usb-modeswitch)
1224 (let ((rules (usb-modeswitch-configuration->udev-rules config)))
1226 (default-value (usb-modeswitch-configuration))
1227 (description "Run @uref{http://www.draisberghof.de/usb_modeswitch/,
1228 USB_ModeSwitch}, a mode switching tool for controlling USB devices with
1229 multiple @dfn{modes}. When plugged in for the first time many USB
1230 devices (primarily high-speed WAN modems) act like a flash storage containing
1231 installers for Windows drivers. USB_ModeSwitch replays the sequence the
1232 Windows drivers would send to switch their mode from storage to modem (or
1233 whatever the thing is supposed to do).")))
1240 (define-record-type* <wpa-supplicant-configuration>
1241 wpa-supplicant-configuration make-wpa-supplicant-configuration
1242 wpa-supplicant-configuration?
1243 (wpa-supplicant wpa-supplicant-configuration-wpa-supplicant ;<package>
1244 (default wpa-supplicant))
1245 (pid-file wpa-supplicant-configuration-pid-file ;string
1246 (default "/var/run/wpa_supplicant.pid"))
1247 (dbus? wpa-supplicant-configuration-dbus? ;Boolean
1249 (interface wpa-supplicant-configuration-interface ;#f | string
1251 (config-file wpa-supplicant-configuration-config-file ;#f | <file-like>
1253 (extra-options wpa-supplicant-configuration-extra-options ;list of strings
1256 (define wpa-supplicant-shepherd-service
1258 (($ <wpa-supplicant-configuration> wpa-supplicant pid-file dbus? interface
1259 config-file extra-options)
1260 (list (shepherd-service
1261 (documentation "Run the WPA supplicant daemon")
1262 (provision '(wpa-supplicant))
1263 (requirement '(user-processes dbus-system loopback syslogd))
1264 (start #~(make-forkexec-constructor
1265 (list (string-append #$wpa-supplicant
1266 "/sbin/wpa_supplicant")
1267 (string-append "-P" #$pid-file)
1268 "-B" ;run in background
1269 "-s" ;log to syslogd
1274 #~((string-append "-i" #$interface))
1277 #~((string-append "-c" #$config-file))
1280 #:pid-file #$pid-file))
1281 (stop #~(make-kill-destructor)))))))
1283 (define wpa-supplicant-service-type
1284 (let ((config->package
1286 (($ <wpa-supplicant-configuration> wpa-supplicant)
1287 (list wpa-supplicant)))))
1288 (service-type (name 'wpa-supplicant)
1290 (list (service-extension shepherd-root-service-type
1291 wpa-supplicant-shepherd-service)
1292 (service-extension dbus-root-service-type config->package)
1293 (service-extension profile-service-type config->package)))
1294 (description "Run the WPA Supplicant daemon, a service that
1295 implements authentication, key negotiation and more for wireless networks.")
1296 (default-value (wpa-supplicant-configuration)))))
1303 (define-record-type* <openvswitch-configuration>
1304 openvswitch-configuration make-openvswitch-configuration
1305 openvswitch-configuration?
1306 (package openvswitch-configuration-package
1307 (default openvswitch)))
1309 (define openvswitch-activation
1311 (($ <openvswitch-configuration> package)
1312 (let ((ovsdb-tool (file-append package "/bin/ovsdb-tool")))
1313 (with-imported-modules '((guix build utils))
1315 (use-modules (guix build utils))
1316 (mkdir-p "/var/run/openvswitch")
1317 (mkdir-p "/var/lib/openvswitch")
1318 (let ((conf.db "/var/lib/openvswitch/conf.db"))
1319 (unless (file-exists? conf.db)
1320 (system* #$ovsdb-tool "create" conf.db)))))))))
1322 (define openvswitch-shepherd-service
1324 (($ <openvswitch-configuration> package)
1325 (let ((ovsdb-server (file-append package "/sbin/ovsdb-server"))
1326 (ovs-vswitchd (file-append package "/sbin/ovs-vswitchd")))
1329 (provision '(ovsdb))
1330 (documentation "Run the Open vSwitch database server.")
1331 (start #~(make-forkexec-constructor
1332 (list #$ovsdb-server "--pidfile"
1333 "--remote=punix:/var/run/openvswitch/db.sock")
1334 #:pid-file "/var/run/openvswitch/ovsdb-server.pid"))
1335 (stop #~(make-kill-destructor)))
1337 (provision '(vswitchd))
1338 (requirement '(ovsdb))
1339 (documentation "Run the Open vSwitch daemon.")
1340 (start #~(make-forkexec-constructor
1341 (list #$ovs-vswitchd "--pidfile")
1342 #:pid-file "/var/run/openvswitch/ovs-vswitchd.pid"))
1343 (stop #~(make-kill-destructor))))))))
1345 (define openvswitch-service-type
1349 (list (service-extension activation-service-type
1350 openvswitch-activation)
1351 (service-extension profile-service-type
1352 (compose list openvswitch-configuration-package))
1353 (service-extension shepherd-root-service-type
1354 openvswitch-shepherd-service)))
1356 "Run @uref{http://www.openvswitch.org, Open vSwitch}, a multilayer virtual
1357 switch designed to enable massive network automation through programmatic
1359 (default-value (openvswitch-configuration))))
1365 (define %iptables-accept-all-rules
1366 (plain-file "iptables-accept-all.rules"
1374 (define-record-type* <iptables-configuration>
1375 iptables-configuration make-iptables-configuration iptables-configuration?
1376 (iptables iptables-configuration-iptables
1378 (ipv4-rules iptables-configuration-ipv4-rules
1379 (default %iptables-accept-all-rules))
1380 (ipv6-rules iptables-configuration-ipv6-rules
1381 (default %iptables-accept-all-rules)))
1383 (define iptables-shepherd-service
1385 (($ <iptables-configuration> iptables ipv4-rules ipv6-rules)
1386 (let ((iptables-restore (file-append iptables "/sbin/iptables-restore"))
1387 (ip6tables-restore (file-append iptables "/sbin/ip6tables-restore")))
1389 (documentation "Packet filtering framework")
1390 (provision '(iptables))
1392 (invoke #$iptables-restore #$ipv4-rules)
1393 (invoke #$ip6tables-restore #$ipv6-rules)))
1395 (invoke #$iptables-restore #$%iptables-accept-all-rules)
1396 (invoke #$ip6tables-restore #$%iptables-accept-all-rules))))))))
1398 (define iptables-service-type
1402 "Run @command{iptables-restore}, setting up the specified rules.")
1404 (list (service-extension shepherd-root-service-type
1405 (compose list iptables-shepherd-service))))))
1407 ;;; networking.scm ends here