Merge branch 'master' into staging
[jackhill/guix/guix.git] / gnu / services / networking.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 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 ;;;
18 ;;; This file is part of GNU Guix.
19 ;;;
20 ;;; GNU Guix is free software; you can redistribute it and/or modify it
21 ;;; under the terms of the GNU General Public License as published by
22 ;;; the Free Software Foundation; either version 3 of the License, or (at
23 ;;; your option) any later version.
24 ;;;
25 ;;; GNU Guix is distributed in the hope that it will be useful, but
26 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
27 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 ;;; GNU General Public License for more details.
29 ;;;
30 ;;; You should have received a copy of the GNU General Public License
31 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
32
33 (define-module (gnu services networking)
34 #:use-module (gnu services)
35 #:use-module (gnu services base)
36 #:use-module (gnu services configuration)
37 #:use-module (gnu services linux)
38 #:use-module (gnu services shepherd)
39 #:use-module (gnu services dbus)
40 #:use-module (gnu system shadow)
41 #:use-module (gnu system pam)
42 #:use-module (gnu packages admin)
43 #:use-module (gnu packages base)
44 #:use-module (gnu packages bash)
45 #:use-module (gnu packages connman)
46 #:use-module (gnu packages freedesktop)
47 #:use-module (gnu packages linux)
48 #:use-module (gnu packages tor)
49 #:use-module (gnu packages usb-modeswitch)
50 #:use-module (gnu packages messaging)
51 #:use-module (gnu packages networking)
52 #:use-module (gnu packages ntp)
53 #:use-module (gnu packages wicd)
54 #:use-module (gnu packages gnome)
55 #:use-module (guix gexp)
56 #:use-module (guix records)
57 #:use-module (guix modules)
58 #:use-module (guix packages)
59 #:use-module (guix deprecation)
60 #:use-module (rnrs enums)
61 #:use-module (srfi srfi-1)
62 #:use-module (srfi srfi-9)
63 #:use-module (srfi srfi-26)
64 #:use-module (ice-9 match)
65 #:re-export (static-networking-service
66 static-networking-service-type)
67 #:export (%facebook-host-aliases
68 dhcp-client-service
69 dhcp-client-service-type
70
71 dhcpd-service-type
72 dhcpd-configuration
73 dhcpd-configuration?
74 dhcpd-configuration-package
75 dhcpd-configuration-config-file
76 dhcpd-configuration-version
77 dhcpd-configuration-run-directory
78 dhcpd-configuration-lease-file
79 dhcpd-configuration-pid-file
80 dhcpd-configuration-interfaces
81
82 ntp-configuration
83 ntp-configuration?
84 ntp-configuration-ntp
85 ntp-configuration-servers
86 ntp-allow-large-adjustment?
87
88 %ntp-servers
89 ntp-server
90 ntp-server-type
91 ntp-server-address
92 ntp-server-options
93
94 ntp-service
95 ntp-service-type
96
97 %openntpd-servers
98 openntpd-configuration
99 openntpd-configuration?
100 openntpd-service-type
101
102 inetd-configuration
103 inetd-entry
104 inetd-service-type
105
106 tor-configuration
107 tor-configuration?
108 tor-hidden-service
109 tor-service
110 tor-service-type
111
112 wicd-service-type
113 wicd-service
114
115 network-manager-configuration
116 network-manager-configuration?
117 network-manager-configuration-dns
118 network-manager-configuration-vpn-plugins
119 network-manager-service-type
120
121 connman-configuration
122 connman-configuration?
123 connman-service-type
124
125 modem-manager-configuration
126 modem-manager-configuration?
127 modem-manager-service-type
128
129 usb-modeswitch-configuration
130 usb-modeswitch-configuration?
131 usb-modeswitch-configuration-usb-modeswitch
132 usb-modeswitch-configuration-usb-modeswitch-data
133 usb-modeswitch-service-type
134
135 wpa-supplicant-configuration
136 wpa-supplicant-configuration?
137 wpa-supplicant-configuration-wpa-supplicant
138 wpa-supplicant-configuration-requirement
139 wpa-supplicant-configuration-pid-file
140 wpa-supplicant-configuration-dbus?
141 wpa-supplicant-configuration-interface
142 wpa-supplicant-configuration-config-file
143 wpa-supplicant-configuration-extra-options
144 wpa-supplicant-service-type
145
146 hostapd-configuration
147 hostapd-configuration?
148 hostapd-configuration-package
149 hostapd-configuration-interface
150 hostapd-configuration-ssid
151 hostapd-configuration-broadcast-ssid?
152 hostapd-configuration-channel
153 hostapd-configuration-driver
154 hostapd-service-type
155
156 simulated-wifi-service-type
157
158 openvswitch-service-type
159 openvswitch-configuration
160
161 iptables-configuration
162 iptables-configuration?
163 iptables-configuration-iptables
164 iptables-configuration-ipv4-rules
165 iptables-configuration-ipv6-rules
166 iptables-service-type
167
168 nftables-service-type
169 nftables-configuration
170 nftables-configuration?
171 nftables-configuration-package
172 nftables-configuration-ruleset
173 %default-nftables-ruleset
174
175 pagekite-service-type
176 pagekite-configuration
177 pagekite-configuration?
178 pagekite-configuration-package
179 pagekite-configuration-kitename
180 pagekite-configuration-kitesecret
181 pagekite-configuration-frontend
182 pagekite-configuration-kites
183 pagekite-configuration-extra-file))
184
185 ;;; Commentary:
186 ;;;
187 ;;; Networking services.
188 ;;;
189 ;;; Code:
190
191 (define %facebook-host-aliases
192 ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
193 ;; are to block it.
194 "\
195 # Block Facebook IPv4.
196 127.0.0.1 www.facebook.com
197 127.0.0.1 facebook.com
198 127.0.0.1 login.facebook.com
199 127.0.0.1 www.login.facebook.com
200 127.0.0.1 fbcdn.net
201 127.0.0.1 www.fbcdn.net
202 127.0.0.1 fbcdn.com
203 127.0.0.1 www.fbcdn.com
204 127.0.0.1 static.ak.fbcdn.net
205 127.0.0.1 static.ak.connect.facebook.com
206 127.0.0.1 connect.facebook.net
207 127.0.0.1 www.connect.facebook.net
208 127.0.0.1 apps.facebook.com
209
210 # Block Facebook IPv6.
211 fe80::1%lo0 facebook.com
212 fe80::1%lo0 login.facebook.com
213 fe80::1%lo0 www.login.facebook.com
214 fe80::1%lo0 fbcdn.net
215 fe80::1%lo0 www.fbcdn.net
216 fe80::1%lo0 fbcdn.com
217 fe80::1%lo0 www.fbcdn.com
218 fe80::1%lo0 static.ak.fbcdn.net
219 fe80::1%lo0 static.ak.connect.facebook.com
220 fe80::1%lo0 connect.facebook.net
221 fe80::1%lo0 www.connect.facebook.net
222 fe80::1%lo0 apps.facebook.com\n")
223
224 (define dhcp-client-service-type
225 (shepherd-service-type
226 'dhcp-client
227 (lambda (dhcp)
228 (define dhclient
229 (file-append dhcp "/sbin/dhclient"))
230
231 (define pid-file
232 "/var/run/dhclient.pid")
233
234 (shepherd-service
235 (documentation "Set up networking via DHCP.")
236 (requirement '(user-processes udev))
237
238 ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
239 ;; networking is unavailable, but also means that the interface is not up
240 ;; yet when 'start' completes. To wait for the interface to be ready, one
241 ;; should instead monitor udev events.
242 (provision '(networking))
243
244 (start #~(lambda _
245 ;; When invoked without any arguments, 'dhclient' discovers all
246 ;; non-loopback interfaces *that are up*. However, the relevant
247 ;; interfaces are typically down at this point. Thus we perform
248 ;; our own interface discovery here.
249 (define valid?
250 (lambda (interface)
251 (and (arp-network-interface? interface)
252 (not (loopback-network-interface? interface))
253 ;; XXX: Make sure the interfaces are up so that
254 ;; 'dhclient' can actually send/receive over them.
255 ;; Ignore those that cannot be activated.
256 (false-if-exception
257 (set-network-interface-up interface)))))
258 (define ifaces
259 (filter valid? (all-network-interface-names)))
260
261 (false-if-exception (delete-file #$pid-file))
262 (let ((pid (fork+exec-command
263 (cons* #$dhclient "-nw"
264 "-pf" #$pid-file ifaces))))
265 (and (zero? (cdr (waitpid pid)))
266 (read-pid-file #$pid-file)))))
267 (stop #~(make-kill-destructor))))
268 isc-dhcp))
269
270 (define-deprecated (dhcp-client-service #:key (dhcp isc-dhcp))
271 dhcp-client-service-type
272 "Return a service that runs @var{dhcp}, a Dynamic Host Configuration
273 Protocol (DHCP) client, on all the non-loopback network interfaces."
274 (service dhcp-client-service-type dhcp))
275
276 (define-record-type* <dhcpd-configuration>
277 dhcpd-configuration make-dhcpd-configuration
278 dhcpd-configuration?
279 (package dhcpd-configuration-package ;<package>
280 (default isc-dhcp))
281 (config-file dhcpd-configuration-config-file ;file-like
282 (default #f))
283 (version dhcpd-configuration-version ;"4", "6", or "4o6"
284 (default "4"))
285 (run-directory dhcpd-configuration-run-directory
286 (default "/run/dhcpd"))
287 (lease-file dhcpd-configuration-lease-file
288 (default "/var/db/dhcpd.leases"))
289 (pid-file dhcpd-configuration-pid-file
290 (default "/run/dhcpd/dhcpd.pid"))
291 ;; list of strings, e.g. (list "enp0s25")
292 (interfaces dhcpd-configuration-interfaces
293 (default '())))
294
295 (define dhcpd-shepherd-service
296 (match-lambda
297 (($ <dhcpd-configuration> package config-file version run-directory
298 lease-file pid-file interfaces)
299 (unless config-file
300 (error "Must supply a config-file"))
301 (list (shepherd-service
302 ;; Allow users to easily run multiple versions simultaneously.
303 (provision (list (string->symbol
304 (string-append "dhcpv" version "-daemon"))))
305 (documentation (string-append "Run the DHCPv" version " daemon"))
306 (requirement '(networking))
307 (start #~(make-forkexec-constructor
308 '(#$(file-append package "/sbin/dhcpd")
309 #$(string-append "-" version)
310 "-lf" #$lease-file
311 "-pf" #$pid-file
312 "-cf" #$config-file
313 #$@interfaces)
314 #:pid-file #$pid-file))
315 (stop #~(make-kill-destructor)))))))
316
317 (define dhcpd-activation
318 (match-lambda
319 (($ <dhcpd-configuration> package config-file version run-directory
320 lease-file pid-file interfaces)
321 (with-imported-modules '((guix build utils))
322 #~(begin
323 (unless (file-exists? #$run-directory)
324 (mkdir #$run-directory))
325 ;; According to the DHCP manual (man dhcpd.leases), the lease
326 ;; database must be present for dhcpd to start successfully.
327 (unless (file-exists? #$lease-file)
328 (with-output-to-file #$lease-file
329 (lambda _ (display ""))))
330 ;; Validate the config.
331 (invoke/quiet
332 #$(file-append package "/sbin/dhcpd") "-t" "-cf"
333 #$config-file))))))
334
335 (define dhcpd-service-type
336 (service-type
337 (name 'dhcpd)
338 (extensions
339 (list (service-extension shepherd-root-service-type dhcpd-shepherd-service)
340 (service-extension activation-service-type dhcpd-activation)))
341 (description "Run a DHCP (Dynamic Host Configuration Protocol) daemon. The
342 daemon is responsible for allocating IP addresses to its client.")))
343
344 \f
345 ;;;
346 ;;; NTP.
347 ;;;
348
349 (define ntp-server-types (make-enumeration
350 '(pool
351 server
352 peer
353 broadcast
354 manycastclient)))
355
356 (define-record-type* <ntp-server>
357 ntp-server make-ntp-server
358 ntp-server?
359 ;; The type can be one of the symbols of the NTP-SERVER-TYPE? enumeration.
360 (type ntp-server-type
361 (default 'server))
362 (address ntp-server-address) ; a string
363 ;; The list of options can contain single option names or tuples in the form
364 ;; '(name value).
365 (options ntp-server-options
366 (default '())))
367
368 (define (ntp-server->string ntp-server)
369 ;; Serialize the NTP server object as a string, ready to use in the NTP
370 ;; configuration file.
371 (define (flatten lst)
372 (reverse
373 (let loop ((x lst)
374 (res '()))
375 (if (list? x)
376 (fold loop res x)
377 (cons (format #f "~a" x) res)))))
378
379 (match ntp-server
380 (($ <ntp-server> type address options)
381 ;; XXX: It'd be neater if fields were validated at the syntax level (for
382 ;; static ones at least). Perhaps the Guix record type could support a
383 ;; predicate property on a field?
384 (unless (enum-set-member? type ntp-server-types)
385 (error "Invalid NTP server type" type))
386 (string-join (cons* (symbol->string type)
387 address
388 (flatten options))))))
389
390 (define %ntp-servers
391 ;; Default set of NTP servers. These URLs are managed by the NTP Pool project.
392 ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact
393 ;; for this NTP pool "zone".
394 (list
395 (ntp-server
396 (type 'pool)
397 (address "0.guix.pool.ntp.org")
398 (options '("iburst"))))) ;as recommended in the ntpd manual
399
400 (define-record-type* <ntp-configuration>
401 ntp-configuration make-ntp-configuration
402 ntp-configuration?
403 (ntp ntp-configuration-ntp
404 (default ntp))
405 (servers %ntp-configuration-servers ;list of <ntp-server> objects
406 (default %ntp-servers))
407 (allow-large-adjustment? ntp-allow-large-adjustment?
408 (default #t))) ;as recommended in the ntpd manual
409
410 (define (ntp-configuration-servers ntp-configuration)
411 ;; A wrapper to support the deprecated form of this field.
412 (let ((ntp-servers (%ntp-configuration-servers ntp-configuration)))
413 (match ntp-servers
414 (((? string?) (? string?) ...)
415 (format (current-error-port) "warning: Defining NTP servers as strings is \
416 deprecated. Please use <ntp-server> records instead.\n")
417 (map (lambda (addr)
418 (ntp-server
419 (type 'server)
420 (address addr)
421 (options '()))) ntp-servers))
422 ((($ <ntp-server>) ($ <ntp-server>) ...)
423 ntp-servers))))
424
425 (define ntp-shepherd-service
426 (lambda (config)
427 (match config
428 (($ <ntp-configuration> ntp servers allow-large-adjustment?)
429 (let ((servers (ntp-configuration-servers config)))
430 ;; TODO: Add authentication support.
431 (define config
432 (string-append "driftfile /var/run/ntpd/ntp.drift\n"
433 (string-join (map ntp-server->string servers)
434 "\n")
435 "
436 # Disable status queries as a workaround for CVE-2013-5211:
437 # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
438 restrict default kod nomodify notrap nopeer noquery limited
439 restrict -6 default kod nomodify notrap nopeer noquery limited
440
441 # Yet, allow use of the local 'ntpq'.
442 restrict 127.0.0.1
443 restrict -6 ::1
444
445 # This is required to use servers from a pool directive when using the 'nopeer'
446 # option by default, as documented in the 'ntp.conf' manual.
447 restrict source notrap nomodify noquery\n"))
448
449 (define ntpd.conf
450 (plain-file "ntpd.conf" config))
451
452 (list (shepherd-service
453 (provision '(ntpd))
454 (documentation "Run the Network Time Protocol (NTP) daemon.")
455 (requirement '(user-processes networking))
456 (start #~(make-forkexec-constructor
457 (list (string-append #$ntp "/bin/ntpd") "-n"
458 "-c" #$ntpd.conf "-u" "ntpd"
459 #$@(if allow-large-adjustment?
460 '("-g")
461 '()))))
462 (stop #~(make-kill-destructor)))))))))
463
464 (define %ntp-accounts
465 (list (user-account
466 (name "ntpd")
467 (group "nogroup")
468 (system? #t)
469 (comment "NTP daemon user")
470 (home-directory "/var/empty")
471 (shell (file-append shadow "/sbin/nologin")))))
472
473
474 (define (ntp-service-activation config)
475 "Return the activation gexp for CONFIG."
476 (with-imported-modules '((guix build utils))
477 #~(begin
478 (use-modules (guix build utils))
479 (define %user
480 (getpw "ntpd"))
481
482 (let ((directory "/var/run/ntpd"))
483 (mkdir-p directory)
484 (chown directory (passwd:uid %user) (passwd:gid %user))))))
485
486 (define ntp-service-type
487 (service-type (name 'ntp)
488 (extensions
489 (list (service-extension shepherd-root-service-type
490 ntp-shepherd-service)
491 (service-extension account-service-type
492 (const %ntp-accounts))
493 (service-extension activation-service-type
494 ntp-service-activation)))
495 (description
496 "Run the @command{ntpd}, the Network Time Protocol (NTP)
497 daemon of the @uref{http://www.ntp.org, Network Time Foundation}. The daemon
498 will keep the system clock synchronized with that of the given servers.")
499 (default-value (ntp-configuration))))
500
501 (define-deprecated (ntp-service #:key (ntp ntp)
502 (servers %ntp-servers)
503 allow-large-adjustment?)
504 ntp-service-type
505 "Return a service that runs the daemon from @var{ntp}, the
506 @uref{http://www.ntp.org, Network Time Protocol package}. The daemon will
507 keep the system clock synchronized with that of @var{servers}.
508 @var{allow-large-adjustment?} determines whether @command{ntpd} is allowed to
509 make an initial adjustment of more than 1,000 seconds."
510 (service ntp-service-type
511 (ntp-configuration (ntp ntp)
512 (servers servers)
513 (allow-large-adjustment?
514 allow-large-adjustment?))))
515
516 \f
517 ;;;
518 ;;; OpenNTPD.
519 ;;;
520
521 (define %openntpd-servers
522 (map ntp-server-address %ntp-servers))
523
524 (define-record-type* <openntpd-configuration>
525 openntpd-configuration make-openntpd-configuration
526 openntpd-configuration?
527 (openntpd openntpd-configuration-openntpd
528 (default openntpd))
529 (listen-on openntpd-listen-on
530 (default '("127.0.0.1"
531 "::1")))
532 (query-from openntpd-query-from
533 (default '()))
534 (sensor openntpd-sensor
535 (default '()))
536 (server openntpd-server
537 (default '()))
538 (servers openntpd-servers
539 (default %openntpd-servers))
540 (constraint-from openntpd-constraint-from
541 (default '()))
542 (constraints-from openntpd-constraints-from
543 (default '()))
544 (allow-large-adjustment? openntpd-allow-large-adjustment?
545 (default #f))) ; upstream default
546
547 (define (openntpd-configuration->string config)
548
549 (define (quote-field? name)
550 (member name '("constraints from")))
551
552 (match-record config <openntpd-configuration>
553 (listen-on query-from sensor server servers constraint-from
554 constraints-from)
555 (string-append
556 (string-join
557 (concatenate
558 (filter-map (lambda (field values)
559 (match values
560 (() #f) ;discard entry with filter-map
561 ((val ...) ;validate value type
562 (map (lambda (value)
563 (if (quote-field? field)
564 (format #f "~a \"~a\"" field value)
565 (format #f "~a ~a" field value)))
566 values))))
567 ;; The entry names.
568 '("listen on" "query from" "sensor" "server" "servers"
569 "constraint from" "constraints from")
570 ;; The corresponding entry values.
571 (list listen-on query-from sensor server servers
572 constraint-from constraints-from)))
573 "\n")
574 "\n"))) ;add a trailing newline
575
576 (define (openntpd-shepherd-service config)
577 (let ((openntpd (openntpd-configuration-openntpd config))
578 (allow-large-adjustment? (openntpd-allow-large-adjustment? config)))
579
580 (define ntpd.conf
581 (plain-file "ntpd.conf" (openntpd-configuration->string config)))
582
583 (list (shepherd-service
584 (provision '(ntpd))
585 (documentation "Run the Network Time Protocol (NTP) daemon.")
586 (requirement '(user-processes networking))
587 (start #~(make-forkexec-constructor
588 (list (string-append #$openntpd "/sbin/ntpd")
589 "-f" #$ntpd.conf
590 "-d" ;; don't daemonize
591 #$@(if allow-large-adjustment?
592 '("-s")
593 '()))
594 ;; When ntpd is daemonized it repeatedly tries to respawn
595 ;; while running, leading shepherd to disable it. To
596 ;; prevent spamming stderr, redirect output to logfile.
597 #:log-file "/var/log/ntpd"))
598 (stop #~(make-kill-destructor))))))
599
600 (define (openntpd-service-activation config)
601 "Return the activation gexp for CONFIG."
602 (with-imported-modules '((guix build utils))
603 #~(begin
604 (use-modules (guix build utils))
605
606 (mkdir-p "/var/db")
607 (mkdir-p "/var/run")
608 (unless (file-exists? "/var/db/ntpd.drift")
609 (with-output-to-file "/var/db/ntpd.drift"
610 (lambda _
611 (format #t "0.0")))))))
612
613 (define openntpd-service-type
614 (service-type (name 'openntpd)
615 (extensions
616 (list (service-extension shepherd-root-service-type
617 openntpd-shepherd-service)
618 (service-extension account-service-type
619 (const %ntp-accounts))
620 (service-extension profile-service-type
621 (compose list openntpd-configuration-openntpd))
622 (service-extension activation-service-type
623 openntpd-service-activation)))
624 (default-value (openntpd-configuration))
625 (description
626 "Run the @command{ntpd}, the Network Time Protocol (NTP)
627 daemon, as implemented by @uref{http://www.openntpd.org, OpenNTPD}. The
628 daemon will keep the system clock synchronized with that of the given servers.")))
629
630 \f
631 ;;;
632 ;;; Inetd.
633 ;;;
634
635 (define-record-type* <inetd-configuration> inetd-configuration
636 make-inetd-configuration
637 inetd-configuration?
638 (program inetd-configuration-program ;file-like
639 (default (file-append inetutils "/libexec/inetd")))
640 (entries inetd-configuration-entries ;list of <inetd-entry>
641 (default '())))
642
643 (define-record-type* <inetd-entry> inetd-entry make-inetd-entry
644 inetd-entry?
645 (node inetd-entry-node ;string or #f
646 (default #f))
647 (name inetd-entry-name) ;string, from /etc/services
648
649 (socket-type inetd-entry-socket-type) ;stream | dgram | raw |
650 ;rdm | seqpacket
651 (protocol inetd-entry-protocol) ;string, from /etc/protocols
652
653 (wait? inetd-entry-wait? ;Boolean
654 (default #t))
655 (user inetd-entry-user) ;string
656
657 (program inetd-entry-program ;string or file-like object
658 (default "internal"))
659 (arguments inetd-entry-arguments ;list of strings or file-like objects
660 (default '())))
661
662 (define (inetd-config-file entries)
663 (apply mixed-text-file "inetd.conf"
664 (map
665 (lambda (entry)
666 (let* ((node (inetd-entry-node entry))
667 (name (inetd-entry-name entry))
668 (socket
669 (if node (string-append node ":" name) name))
670 (type
671 (match (inetd-entry-socket-type entry)
672 ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
673 (symbol->string (inetd-entry-socket-type entry)))))
674 (protocol (inetd-entry-protocol entry))
675 (wait (if (inetd-entry-wait? entry) "wait" "nowait"))
676 (user (inetd-entry-user entry))
677 (program (inetd-entry-program entry))
678 (args (inetd-entry-arguments entry)))
679 #~(string-append
680 (string-join
681 (list #$@(list socket type protocol wait user program) #$@args)
682 " ") "\n")))
683 entries)))
684
685 (define inetd-shepherd-service
686 (match-lambda
687 (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing
688 (($ <inetd-configuration> program entries)
689 (list
690 (shepherd-service
691 (documentation "Run inetd.")
692 (provision '(inetd))
693 (requirement '(user-processes networking syslogd))
694 (start #~(make-forkexec-constructor
695 (list #$program #$(inetd-config-file entries))
696 #:pid-file "/var/run/inetd.pid"))
697 (stop #~(make-kill-destructor)))))))
698
699 (define-public inetd-service-type
700 (service-type
701 (name 'inetd)
702 (extensions
703 (list (service-extension shepherd-root-service-type
704 inetd-shepherd-service)))
705
706 ;; The service can be extended with additional lists of entries.
707 (compose concatenate)
708 (extend (lambda (config entries)
709 (inetd-configuration
710 (inherit config)
711 (entries (append (inetd-configuration-entries config)
712 entries)))))
713 (description
714 "Start @command{inetd}, the @dfn{Internet superserver}. It is responsible
715 for listening on Internet sockets and spawning the corresponding services on
716 demand.")))
717
718 \f
719 ;;;
720 ;;; Tor.
721 ;;;
722
723 (define-record-type* <tor-configuration>
724 tor-configuration make-tor-configuration
725 tor-configuration?
726 (tor tor-configuration-tor
727 (default tor))
728 (config-file tor-configuration-config-file
729 (default (plain-file "empty" "")))
730 (hidden-services tor-configuration-hidden-services
731 (default '()))
732 (socks-socket-type tor-configuration-socks-socket-type ; 'tcp or 'unix
733 (default 'tcp)))
734
735 (define %tor-accounts
736 ;; User account and groups for Tor.
737 (list (user-group (name "tor") (system? #t))
738 (user-account
739 (name "tor")
740 (group "tor")
741 (system? #t)
742 (comment "Tor daemon user")
743 (home-directory "/var/empty")
744 (shell (file-append shadow "/sbin/nologin")))))
745
746 (define-record-type <hidden-service>
747 (hidden-service name mapping)
748 hidden-service?
749 (name hidden-service-name) ;string
750 (mapping hidden-service-mapping)) ;list of port/address tuples
751
752 (define (tor-configuration->torrc config)
753 "Return a 'torrc' file for CONFIG."
754 (match config
755 (($ <tor-configuration> tor config-file services socks-socket-type)
756 (computed-file
757 "torrc"
758 (with-imported-modules '((guix build utils))
759 #~(begin
760 (use-modules (guix build utils)
761 (ice-9 match))
762
763 (call-with-output-file #$output
764 (lambda (port)
765 (display "\
766 ### These lines were generated from your system configuration:
767 User tor
768 DataDirectory /var/lib/tor
769 PidFile /var/run/tor/tor.pid
770 Log notice syslog\n" port)
771 (when (eq? 'unix '#$socks-socket-type)
772 (display "\
773 SocksPort unix:/var/run/tor/socks-sock
774 UnixSocksGroupWritable 1\n" port))
775
776 (for-each (match-lambda
777 ((service (ports hosts) ...)
778 (format port "\
779 HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
780 service)
781 (for-each (lambda (tcp-port host)
782 (format port "\
783 HiddenServicePort ~a ~a~%"
784 tcp-port host))
785 ports hosts)))
786 '#$(map (match-lambda
787 (($ <hidden-service> name mapping)
788 (cons name mapping)))
789 services))
790
791 (display "\
792 ### End of automatically generated lines.\n\n" port)
793
794 ;; Append the user's config file.
795 (call-with-input-file #$config-file
796 (lambda (input)
797 (dump-port input port)))
798 #t))))))))
799
800 (define (tor-shepherd-service config)
801 "Return a <shepherd-service> running Tor."
802 (match config
803 (($ <tor-configuration> tor)
804 (let ((torrc (tor-configuration->torrc config)))
805 (with-imported-modules (source-module-closure
806 '((gnu build shepherd)
807 (gnu system file-systems)))
808 (list (shepherd-service
809 (provision '(tor))
810
811 ;; Tor needs at least one network interface to be up, hence the
812 ;; dependency on 'loopback'.
813 (requirement '(user-processes loopback syslogd))
814
815 (modules '((gnu build shepherd)
816 (gnu system file-systems)))
817
818 (start #~(make-forkexec-constructor/container
819 (list #$(file-append tor "/bin/tor") "-f" #$torrc)
820
821 #:mappings (list (file-system-mapping
822 (source "/var/lib/tor")
823 (target source)
824 (writable? #t))
825 (file-system-mapping
826 (source "/dev/log") ;for syslog
827 (target source))
828 (file-system-mapping
829 (source "/var/run/tor")
830 (target source)
831 (writable? #t)))
832 #:pid-file "/var/run/tor/tor.pid"))
833 (stop #~(make-kill-destructor))
834 (documentation "Run the Tor anonymous network overlay."))))))))
835
836 (define (tor-activation config)
837 "Set up directories for Tor and its hidden services, if any."
838 #~(begin
839 (use-modules (guix build utils))
840
841 (define %user
842 (getpw "tor"))
843
844 (define (initialize service)
845 (let ((directory (string-append "/var/lib/tor/hidden-services/"
846 service)))
847 (mkdir-p directory)
848 (chown directory (passwd:uid %user) (passwd:gid %user))
849
850 ;; The daemon bails out if we give wider permissions.
851 (chmod directory #o700)))
852
853 ;; Allow Tor to write its PID file.
854 (mkdir-p "/var/run/tor")
855 (chown "/var/run/tor" (passwd:uid %user) (passwd:gid %user))
856 ;; Set the group permissions to rw so that if the system administrator
857 ;; has specified UnixSocksGroupWritable=1 in their torrc file, members
858 ;; of the "tor" group will be able to use the SOCKS socket.
859 (chmod "/var/run/tor" #o750)
860
861 ;; Allow Tor to access the hidden services' directories.
862 (mkdir-p "/var/lib/tor")
863 (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
864 (chmod "/var/lib/tor" #o700)
865
866 ;; Make sure /var/lib is accessible to the 'tor' user.
867 (chmod "/var/lib" #o755)
868
869 (for-each initialize
870 '#$(map hidden-service-name
871 (tor-configuration-hidden-services config)))))
872
873 (define tor-service-type
874 (service-type (name 'tor)
875 (extensions
876 (list (service-extension shepherd-root-service-type
877 tor-shepherd-service)
878 (service-extension account-service-type
879 (const %tor-accounts))
880 (service-extension activation-service-type
881 tor-activation)))
882
883 ;; This can be extended with hidden services.
884 (compose concatenate)
885 (extend (lambda (config services)
886 (tor-configuration
887 (inherit config)
888 (hidden-services
889 (append (tor-configuration-hidden-services config)
890 services)))))
891 (default-value (tor-configuration))
892 (description
893 "Run the @uref{https://torproject.org, Tor} anonymous
894 networking daemon.")))
895
896 (define-deprecated (tor-service #:optional
897 (config-file (plain-file "empty" ""))
898 #:key (tor tor))
899 tor-service-type
900 "Return a service to run the @uref{https://torproject.org, Tor} anonymous
901 networking daemon.
902
903 The daemon runs as the @code{tor} unprivileged user. It is passed
904 @var{config-file}, a file-like object, with an additional @code{User tor} line
905 and lines for hidden services added via @code{tor-hidden-service}. Run
906 @command{man tor} for information about the configuration file."
907 (service tor-service-type
908 (tor-configuration (tor tor)
909 (config-file config-file))))
910
911 (define tor-hidden-service-type
912 ;; A type that extends Tor with hidden services.
913 (service-type (name 'tor-hidden-service)
914 (extensions
915 (list (service-extension tor-service-type list)))
916 (description
917 "Define a new Tor @dfn{hidden service}.")))
918
919 (define (tor-hidden-service name mapping)
920 "Define a new Tor @dfn{hidden service} called @var{name} and implementing
921 @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
922
923 @example
924 '((22 \"127.0.0.1:22\")
925 (80 \"127.0.0.1:8080\"))
926 @end example
927
928 In this example, port 22 of the hidden service is mapped to local port 22, and
929 port 80 is mapped to local port 8080.
930
931 This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
932 the @file{hostname} file contains the @code{.onion} host name for the hidden
933 service.
934
935 See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
936 project's documentation} for more information."
937 (service tor-hidden-service-type
938 (hidden-service name mapping)))
939
940 \f
941 ;;;
942 ;;; Wicd.
943 ;;;
944
945 (define %wicd-activation
946 ;; Activation gexp for Wicd.
947 #~(begin
948 (use-modules (guix build utils))
949
950 (mkdir-p "/etc/wicd")
951 (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
952 (unless (file-exists? file-name)
953 (copy-file (string-append #$wicd file-name)
954 file-name)))
955
956 ;; Wicd invokes 'wpa_supplicant', which needs this directory for its
957 ;; named socket files.
958 (mkdir-p "/var/run/wpa_supplicant")
959 (chmod "/var/run/wpa_supplicant" #o750)))
960
961 (define (wicd-shepherd-service wicd)
962 "Return a shepherd service for WICD."
963 (list (shepherd-service
964 (documentation "Run the Wicd network manager.")
965 (provision '(networking))
966 (requirement '(user-processes dbus-system loopback))
967 (start #~(make-forkexec-constructor
968 (list (string-append #$wicd "/sbin/wicd")
969 "--no-daemon")))
970 (stop #~(make-kill-destructor)))))
971
972 (define wicd-service-type
973 (service-type (name 'wicd)
974 (extensions
975 (list (service-extension shepherd-root-service-type
976 wicd-shepherd-service)
977 (service-extension dbus-root-service-type
978 list)
979 (service-extension activation-service-type
980 (const %wicd-activation))
981
982 ;; Add Wicd to the global profile.
983 (service-extension profile-service-type list)))
984 (description
985 "Run @url{https://launchpad.net/wicd,Wicd}, a network
986 management daemon that aims to simplify wired and wireless networking.")))
987
988 (define* (wicd-service #:key (wicd wicd))
989 "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
990 management daemon that aims to simplify wired and wireless networking.
991
992 This service adds the @var{wicd} package to the global profile, providing
993 several commands to interact with the daemon and configure networking:
994 @command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
995 and @command{wicd-curses} user interfaces."
996 (service wicd-service-type wicd))
997
998 \f
999 ;;;
1000 ;;; ModemManager
1001 ;;;
1002
1003 (define-record-type* <modem-manager-configuration>
1004 modem-manager-configuration make-modem-manager-configuration
1005 modem-manager-configuration?
1006 (modem-manager modem-manager-configuration-modem-manager
1007 (default modem-manager)))
1008
1009 \f
1010 ;;;
1011 ;;; NetworkManager
1012 ;;;
1013
1014 (define-record-type* <network-manager-configuration>
1015 network-manager-configuration make-network-manager-configuration
1016 network-manager-configuration?
1017 (network-manager network-manager-configuration-network-manager
1018 (default network-manager))
1019 (dns network-manager-configuration-dns
1020 (default "default"))
1021 (vpn-plugins network-manager-configuration-vpn-plugins ;list of <package>
1022 (default '())))
1023
1024 (define network-manager-activation
1025 ;; Activation gexp for NetworkManager
1026 (match-lambda
1027 (($ <network-manager-configuration> network-manager dns vpn-plugins)
1028 #~(begin
1029 (use-modules (guix build utils))
1030 (mkdir-p "/etc/NetworkManager/system-connections")
1031 #$@(if (equal? dns "dnsmasq")
1032 ;; create directory to store dnsmasq lease file
1033 '((mkdir-p "/var/lib/misc"))
1034 '())))))
1035
1036 (define (vpn-plugin-directory plugins)
1037 "Return a directory containing PLUGINS, the NM VPN plugins."
1038 (directory-union "network-manager-vpn-plugins" plugins))
1039
1040 (define (network-manager-accounts config)
1041 "Return the list of <user-account> and <user-group> for CONFIG."
1042 (define nologin
1043 (file-append shadow "/sbin/nologin"))
1044
1045 (define accounts
1046 (append-map (lambda (package)
1047 (map (lambda (name)
1048 (user-account (system? #t)
1049 (name name)
1050 (group "network-manager")
1051 (comment "NetworkManager helper")
1052 (home-directory "/var/empty")
1053 (create-home-directory? #f)
1054 (shell nologin)))
1055 (or (assoc-ref (package-properties package)
1056 'user-accounts)
1057 '())))
1058 (network-manager-configuration-vpn-plugins config)))
1059
1060 (match accounts
1061 (()
1062 '())
1063 (_
1064 (cons (user-group (name "network-manager") (system? #t))
1065 accounts))))
1066
1067 (define network-manager-environment
1068 (match-lambda
1069 (($ <network-manager-configuration> network-manager dns vpn-plugins)
1070 ;; Define this variable in the global environment such that
1071 ;; "nmcli connection import type openvpn file foo.ovpn" works.
1072 `(("NM_VPN_PLUGIN_DIR"
1073 . ,(file-append (vpn-plugin-directory vpn-plugins)
1074 "/lib/NetworkManager/VPN"))))))
1075
1076 (define network-manager-shepherd-service
1077 (match-lambda
1078 (($ <network-manager-configuration> network-manager dns vpn-plugins)
1079 (let ((conf (plain-file "NetworkManager.conf"
1080 (string-append "[main]\ndns=" dns "\n")))
1081 (vpn (vpn-plugin-directory vpn-plugins)))
1082 (list (shepherd-service
1083 (documentation "Run the NetworkManager.")
1084 (provision '(networking))
1085 (requirement '(user-processes dbus-system wpa-supplicant loopback))
1086 (start #~(make-forkexec-constructor
1087 (list (string-append #$network-manager
1088 "/sbin/NetworkManager")
1089 (string-append "--config=" #$conf)
1090 "--no-daemon")
1091 #:environment-variables
1092 (list (string-append "NM_VPN_PLUGIN_DIR=" #$vpn
1093 "/lib/NetworkManager/VPN")
1094 ;; Override non-existent default users
1095 "NM_OPENVPN_USER="
1096 "NM_OPENVPN_GROUP=")))
1097 (stop #~(make-kill-destructor))))))))
1098
1099 (define network-manager-service-type
1100 (let
1101 ((config->packages
1102 (match-lambda
1103 (($ <network-manager-configuration> network-manager _ vpn-plugins)
1104 `(,network-manager ,@vpn-plugins)))))
1105
1106 (service-type
1107 (name 'network-manager)
1108 (extensions
1109 (list (service-extension shepherd-root-service-type
1110 network-manager-shepherd-service)
1111 (service-extension dbus-root-service-type config->packages)
1112 (service-extension polkit-service-type
1113 (compose
1114 list
1115 network-manager-configuration-network-manager))
1116 (service-extension account-service-type
1117 network-manager-accounts)
1118 (service-extension activation-service-type
1119 network-manager-activation)
1120 (service-extension session-environment-service-type
1121 network-manager-environment)
1122 ;; Add network-manager to the system profile.
1123 (service-extension profile-service-type config->packages)))
1124 (default-value (network-manager-configuration))
1125 (description
1126 "Run @uref{https://wiki.gnome.org/Projects/NetworkManager,
1127 NetworkManager}, a network management daemon that aims to simplify wired and
1128 wireless networking."))))
1129
1130 \f
1131 ;;;
1132 ;;; Connman
1133 ;;;
1134
1135 (define-record-type* <connman-configuration>
1136 connman-configuration make-connman-configuration
1137 connman-configuration?
1138 (connman connman-configuration-connman
1139 (default connman))
1140 (disable-vpn? connman-configuration-disable-vpn?
1141 (default #f)))
1142
1143 (define (connman-activation config)
1144 (let ((disable-vpn? (connman-configuration-disable-vpn? config)))
1145 (with-imported-modules '((guix build utils))
1146 #~(begin
1147 (use-modules (guix build utils))
1148 (mkdir-p "/var/lib/connman/")
1149 (unless #$disable-vpn?
1150 (mkdir-p "/var/lib/connman-vpn/"))))))
1151
1152 (define (connman-shepherd-service config)
1153 "Return a shepherd service for Connman"
1154 (and
1155 (connman-configuration? config)
1156 (let ((connman (connman-configuration-connman config))
1157 (disable-vpn? (connman-configuration-disable-vpn? config)))
1158 (list (shepherd-service
1159 (documentation "Run Connman")
1160 (provision '(networking))
1161 (requirement
1162 '(user-processes dbus-system loopback wpa-supplicant))
1163 (start #~(make-forkexec-constructor
1164 (list (string-append #$connman
1165 "/sbin/connmand")
1166 "--nodaemon"
1167 "--nodnsproxy"
1168 #$@(if disable-vpn? '("--noplugin=vpn") '()))
1169
1170 ;; As connman(8) notes, when passing '-n', connman
1171 ;; "directs log output to the controlling terminal in
1172 ;; addition to syslog." Redirect stdout and stderr
1173 ;; to avoid spamming the console (XXX: for some reason
1174 ;; redirecting to /dev/null doesn't work.)
1175 #:log-file "/var/log/connman.log"))
1176 (stop #~(make-kill-destructor)))))))
1177
1178 (define connman-service-type
1179 (let ((connman-package (compose list connman-configuration-connman)))
1180 (service-type (name 'connman)
1181 (extensions
1182 (list (service-extension shepherd-root-service-type
1183 connman-shepherd-service)
1184 (service-extension polkit-service-type
1185 connman-package)
1186 (service-extension dbus-root-service-type
1187 connman-package)
1188 (service-extension activation-service-type
1189 connman-activation)
1190 ;; Add connman to the system profile.
1191 (service-extension profile-service-type
1192 connman-package)))
1193 (default-value (connman-configuration))
1194 (description
1195 "Run @url{https://01.org/connman,Connman},
1196 a network connection manager."))))
1197
1198 \f
1199 ;;;
1200 ;;; Modem manager
1201 ;;;
1202
1203 (define modem-manager-service-type
1204 (let ((config->package
1205 (match-lambda
1206 (($ <modem-manager-configuration> modem-manager)
1207 (list modem-manager)))))
1208 (service-type (name 'modem-manager)
1209 (extensions
1210 (list (service-extension dbus-root-service-type
1211 config->package)
1212 (service-extension udev-service-type
1213 config->package)
1214 (service-extension polkit-service-type
1215 config->package)))
1216 (default-value (modem-manager-configuration))
1217 (description
1218 "Run @uref{https://wiki.gnome.org/Projects/ModemManager,
1219 ModemManager}, a modem management daemon that aims to simplify dialup
1220 networking."))))
1221
1222 \f
1223 ;;;
1224 ;;; USB_ModeSwitch
1225 ;;;
1226
1227 (define-record-type* <usb-modeswitch-configuration>
1228 usb-modeswitch-configuration make-usb-modeswitch-configuration
1229 usb-modeswitch-configuration?
1230 (usb-modeswitch usb-modeswitch-configuration-usb-modeswitch
1231 (default usb-modeswitch))
1232 (usb-modeswitch-data usb-modeswitch-configuration-usb-modeswitch-data
1233 (default usb-modeswitch-data))
1234 (config-file usb-modeswitch-configuration-config-file
1235 (default #~(string-append #$usb-modeswitch:dispatcher
1236 "/etc/usb_modeswitch.conf"))))
1237
1238 (define (usb-modeswitch-sh usb-modeswitch config-file)
1239 "Build a copy of usb_modeswitch.sh located in package USB-MODESWITCH,
1240 modified to pass the CONFIG-FILE in its calls to usb_modeswitch_dispatcher,
1241 and wrap it to actually find the dispatcher in USB-MODESWITCH. The script
1242 will be run by USB_ModeSwitch’s udev rules file when a modeswitchable USB
1243 device is detected."
1244 (computed-file
1245 "usb_modeswitch-sh"
1246 (with-imported-modules '((guix build utils))
1247 #~(begin
1248 (use-modules (guix build utils))
1249 (let ((cfg-param
1250 #$(if config-file
1251 #~(string-append " --config-file=" #$config-file)
1252 "")))
1253 (mkdir #$output)
1254 (install-file (string-append #$usb-modeswitch:dispatcher
1255 "/lib/udev/usb_modeswitch")
1256 #$output)
1257
1258 ;; insert CFG-PARAM into usb_modeswitch_dispatcher command-lines
1259 (substitute* (string-append #$output "/usb_modeswitch")
1260 (("(exec usb_modeswitch_dispatcher .*)( 2>>)" _ left right)
1261 (string-append left cfg-param right))
1262 (("(exec usb_modeswitch_dispatcher .*)( &)" _ left right)
1263 (string-append left cfg-param right)))
1264
1265 ;; wrap-program needs bash in PATH:
1266 (putenv (string-append "PATH=" #$bash "/bin"))
1267 (wrap-program (string-append #$output "/usb_modeswitch")
1268 `("PATH" ":" = (,(string-append #$coreutils "/bin")
1269 ,(string-append
1270 #$usb-modeswitch:dispatcher
1271 "/bin")))))))))
1272
1273 (define (usb-modeswitch-configuration->udev-rules config)
1274 "Build a rules file for extending udev-service-type from the rules in the
1275 usb-modeswitch package specified in CONFIG. The rules file will invoke
1276 usb_modeswitch.sh from the usb-modeswitch package, modified to pass the right
1277 config file."
1278 (match config
1279 (($ <usb-modeswitch-configuration> usb-modeswitch data config-file)
1280 (computed-file
1281 "usb_modeswitch.rules"
1282 (with-imported-modules '((guix build utils))
1283 #~(begin
1284 (use-modules (guix build utils))
1285 (let ((in (string-append #$data "/udev/40-usb_modeswitch.rules"))
1286 (out (string-append #$output "/lib/udev/rules.d"))
1287 (script #$(usb-modeswitch-sh usb-modeswitch config-file)))
1288 (mkdir-p out)
1289 (chdir out)
1290 (install-file in out)
1291 (substitute* "40-usb_modeswitch.rules"
1292 (("PROGRAM=\"usb_modeswitch")
1293 (string-append "PROGRAM=\"" script "/usb_modeswitch"))
1294 (("RUN\\+=\"usb_modeswitch")
1295 (string-append "RUN+=\"" script "/usb_modeswitch"))))))))))
1296
1297 (define usb-modeswitch-service-type
1298 (service-type
1299 (name 'usb-modeswitch)
1300 (extensions
1301 (list
1302 (service-extension
1303 udev-service-type
1304 (lambda (config)
1305 (let ((rules (usb-modeswitch-configuration->udev-rules config)))
1306 (list rules))))))
1307 (default-value (usb-modeswitch-configuration))
1308 (description "Run @uref{http://www.draisberghof.de/usb_modeswitch/,
1309 USB_ModeSwitch}, a mode switching tool for controlling USB devices with
1310 multiple @dfn{modes}. When plugged in for the first time many USB
1311 devices (primarily high-speed WAN modems) act like a flash storage containing
1312 installers for Windows drivers. USB_ModeSwitch replays the sequence the
1313 Windows drivers would send to switch their mode from storage to modem (or
1314 whatever the thing is supposed to do).")))
1315
1316 \f
1317 ;;;
1318 ;;; WPA supplicant
1319 ;;;
1320
1321 (define-record-type* <wpa-supplicant-configuration>
1322 wpa-supplicant-configuration make-wpa-supplicant-configuration
1323 wpa-supplicant-configuration?
1324 (wpa-supplicant wpa-supplicant-configuration-wpa-supplicant ;<package>
1325 (default wpa-supplicant))
1326 (requirement wpa-supplicant-configuration-requirement ;list of symbols
1327 (default '(user-processes loopback syslogd)))
1328 (pid-file wpa-supplicant-configuration-pid-file ;string
1329 (default "/var/run/wpa_supplicant.pid"))
1330 (dbus? wpa-supplicant-configuration-dbus? ;Boolean
1331 (default #t))
1332 (interface wpa-supplicant-configuration-interface ;#f | string
1333 (default #f))
1334 (config-file wpa-supplicant-configuration-config-file ;#f | <file-like>
1335 (default #f))
1336 (extra-options wpa-supplicant-configuration-extra-options ;list of strings
1337 (default '())))
1338
1339 (define wpa-supplicant-shepherd-service
1340 (match-lambda
1341 (($ <wpa-supplicant-configuration> wpa-supplicant requirement pid-file dbus?
1342 interface config-file extra-options)
1343 (list (shepherd-service
1344 (documentation "Run the WPA supplicant daemon")
1345 (provision '(wpa-supplicant))
1346 (requirement (if dbus?
1347 (cons 'dbus-system requirement)
1348 requirement))
1349 (start #~(make-forkexec-constructor
1350 (list (string-append #$wpa-supplicant
1351 "/sbin/wpa_supplicant")
1352 (string-append "-P" #$pid-file)
1353 "-B" ;run in background
1354 "-s" ;log to syslogd
1355 #$@(if dbus?
1356 #~("-u")
1357 #~())
1358 #$@(if interface
1359 #~((string-append "-i" #$interface))
1360 #~())
1361 #$@(if config-file
1362 #~((string-append "-c" #$config-file))
1363 #~())
1364 #$@extra-options)
1365 #:pid-file #$pid-file))
1366 (stop #~(make-kill-destructor)))))))
1367
1368 (define wpa-supplicant-service-type
1369 (let ((config->package
1370 (match-lambda
1371 (($ <wpa-supplicant-configuration> wpa-supplicant)
1372 (list wpa-supplicant)))))
1373 (service-type (name 'wpa-supplicant)
1374 (extensions
1375 (list (service-extension shepherd-root-service-type
1376 wpa-supplicant-shepherd-service)
1377 (service-extension dbus-root-service-type config->package)
1378 (service-extension profile-service-type config->package)))
1379 (description "Run the WPA Supplicant daemon, a service that
1380 implements authentication, key negotiation and more for wireless networks.")
1381 (default-value (wpa-supplicant-configuration)))))
1382
1383 \f
1384 ;;;
1385 ;;; Hostapd.
1386 ;;;
1387
1388 (define-record-type* <hostapd-configuration>
1389 hostapd-configuration make-hostapd-configuration
1390 hostapd-configuration?
1391 (package hostapd-configuration-package
1392 (default hostapd))
1393 (interface hostapd-configuration-interface ;string
1394 (default "wlan0"))
1395 (ssid hostapd-configuration-ssid) ;string
1396 (broadcast-ssid? hostapd-configuration-broadcast-ssid? ;Boolean
1397 (default #t))
1398 (channel hostapd-configuration-channel ;integer
1399 (default 1))
1400 (driver hostapd-configuration-driver ;string
1401 (default "nl80211"))
1402 ;; See <https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf> for a list of
1403 ;; additional options we could add.
1404 (extra-settings hostapd-configuration-extra-settings ;string
1405 (default "")))
1406
1407 (define (hostapd-configuration-file config)
1408 "Return the configuration file for CONFIG, a <hostapd-configuration>."
1409 (match-record config <hostapd-configuration>
1410 (interface ssid broadcast-ssid? channel driver extra-settings)
1411 (plain-file "hostapd.conf"
1412 (string-append "\
1413 # Generated from your Guix configuration.
1414
1415 interface=" interface "
1416 ssid=" ssid "
1417 ignore_broadcast_ssid=" (if broadcast-ssid? "0" "1") "
1418 channel=" (number->string channel) "\n"
1419 extra-settings "\n"))))
1420
1421 (define* (hostapd-shepherd-services config #:key (requirement '()))
1422 "Return Shepherd services for hostapd."
1423 (list (shepherd-service
1424 (provision '(hostapd))
1425 (requirement `(user-processes ,@requirement))
1426 (documentation "Run the hostapd WiFi access point daemon.")
1427 (start #~(make-forkexec-constructor
1428 (list #$(file-append hostapd "/sbin/hostapd")
1429 #$(hostapd-configuration-file config))
1430 #:log-file "/var/log/hostapd.log"))
1431 (stop #~(make-kill-destructor)))))
1432
1433 (define hostapd-service-type
1434 (service-type
1435 (name 'hostapd)
1436 (extensions
1437 (list (service-extension shepherd-root-service-type
1438 hostapd-shepherd-services)))
1439 (description
1440 "Run the @uref{https://w1.fi/hostapd/, hostapd} daemon for Wi-Fi access
1441 points and authentication servers.")))
1442
1443 (define (simulated-wifi-shepherd-services config)
1444 "Return Shepherd services to run hostapd with CONFIG, a
1445 <hostapd-configuration>, as well as services to set up WiFi hardware
1446 simulation."
1447 (append (hostapd-shepherd-services config
1448 #:requirement
1449 '(unblocked-wifi
1450 kernel-module-loader))
1451 (list (shepherd-service
1452 (provision '(unblocked-wifi))
1453 (requirement '(file-systems kernel-module-loader))
1454 (documentation
1455 "Unblock WiFi devices for use by mac80211_hwsim.")
1456 (start #~(lambda _
1457 (invoke #$(file-append util-linux "/sbin/rfkill")
1458 "unblock" "0")
1459 (invoke #$(file-append util-linux "/sbin/rfkill")
1460 "unblock" "1")))
1461 (one-shot? #t)))))
1462
1463 (define simulated-wifi-service-type
1464 (service-type
1465 (name 'simulated-wifi)
1466 (extensions
1467 (list (service-extension shepherd-root-service-type
1468 simulated-wifi-shepherd-services)
1469 (service-extension kernel-module-loader-service-type
1470 (const '("mac80211_hwsim")))))
1471 (default-value (hostapd-configuration
1472 (interface "wlan1")
1473 (ssid "Test Network")))
1474 (description "Run hostapd to simulate WiFi connectivity.")))
1475
1476 \f
1477 ;;;
1478 ;;; Open vSwitch
1479 ;;;
1480
1481 (define-record-type* <openvswitch-configuration>
1482 openvswitch-configuration make-openvswitch-configuration
1483 openvswitch-configuration?
1484 (package openvswitch-configuration-package
1485 (default openvswitch)))
1486
1487 (define openvswitch-activation
1488 (match-lambda
1489 (($ <openvswitch-configuration> package)
1490 (let ((ovsdb-tool (file-append package "/bin/ovsdb-tool")))
1491 (with-imported-modules '((guix build utils))
1492 #~(begin
1493 (use-modules (guix build utils))
1494 (mkdir-p "/var/run/openvswitch")
1495 (mkdir-p "/var/lib/openvswitch")
1496 (let ((conf.db "/var/lib/openvswitch/conf.db"))
1497 (unless (file-exists? conf.db)
1498 (system* #$ovsdb-tool "create" conf.db)))))))))
1499
1500 (define openvswitch-shepherd-service
1501 (match-lambda
1502 (($ <openvswitch-configuration> package)
1503 (let ((ovsdb-server (file-append package "/sbin/ovsdb-server"))
1504 (ovs-vswitchd (file-append package "/sbin/ovs-vswitchd")))
1505 (list
1506 (shepherd-service
1507 (provision '(ovsdb))
1508 (documentation "Run the Open vSwitch database server.")
1509 (start #~(make-forkexec-constructor
1510 (list #$ovsdb-server "--pidfile"
1511 "--remote=punix:/var/run/openvswitch/db.sock")
1512 #:pid-file "/var/run/openvswitch/ovsdb-server.pid"))
1513 (stop #~(make-kill-destructor)))
1514 (shepherd-service
1515 (provision '(vswitchd))
1516 (requirement '(ovsdb))
1517 (documentation "Run the Open vSwitch daemon.")
1518 (start #~(make-forkexec-constructor
1519 (list #$ovs-vswitchd "--pidfile")
1520 #:pid-file "/var/run/openvswitch/ovs-vswitchd.pid"))
1521 (stop #~(make-kill-destructor))))))))
1522
1523 (define openvswitch-service-type
1524 (service-type
1525 (name 'openvswitch)
1526 (extensions
1527 (list (service-extension activation-service-type
1528 openvswitch-activation)
1529 (service-extension profile-service-type
1530 (compose list openvswitch-configuration-package))
1531 (service-extension shepherd-root-service-type
1532 openvswitch-shepherd-service)))
1533 (description
1534 "Run @uref{http://www.openvswitch.org, Open vSwitch}, a multilayer virtual
1535 switch designed to enable massive network automation through programmatic
1536 extension.")
1537 (default-value (openvswitch-configuration))))
1538
1539 ;;;
1540 ;;; iptables
1541 ;;;
1542
1543 (define %iptables-accept-all-rules
1544 (plain-file "iptables-accept-all.rules"
1545 "*filter
1546 :INPUT ACCEPT
1547 :FORWARD ACCEPT
1548 :OUTPUT ACCEPT
1549 COMMIT
1550 "))
1551
1552 (define-record-type* <iptables-configuration>
1553 iptables-configuration make-iptables-configuration iptables-configuration?
1554 (iptables iptables-configuration-iptables
1555 (default iptables))
1556 (ipv4-rules iptables-configuration-ipv4-rules
1557 (default %iptables-accept-all-rules))
1558 (ipv6-rules iptables-configuration-ipv6-rules
1559 (default %iptables-accept-all-rules)))
1560
1561 (define iptables-shepherd-service
1562 (match-lambda
1563 (($ <iptables-configuration> iptables ipv4-rules ipv6-rules)
1564 (let ((iptables-restore (file-append iptables "/sbin/iptables-restore"))
1565 (ip6tables-restore (file-append iptables "/sbin/ip6tables-restore")))
1566 (shepherd-service
1567 (documentation "Packet filtering framework")
1568 (provision '(iptables))
1569 (start #~(lambda _
1570 (invoke #$iptables-restore #$ipv4-rules)
1571 (invoke #$ip6tables-restore #$ipv6-rules)))
1572 (stop #~(lambda _
1573 (invoke #$iptables-restore #$%iptables-accept-all-rules)
1574 (invoke #$ip6tables-restore #$%iptables-accept-all-rules))))))))
1575
1576 (define iptables-service-type
1577 (service-type
1578 (name 'iptables)
1579 (description
1580 "Run @command{iptables-restore}, setting up the specified rules.")
1581 (extensions
1582 (list (service-extension shepherd-root-service-type
1583 (compose list iptables-shepherd-service))))))
1584
1585 ;;;
1586 ;;; nftables
1587 ;;;
1588
1589 (define %default-nftables-ruleset
1590 (plain-file "nftables.conf"
1591 "# A simple and safe firewall
1592 table inet filter {
1593 chain input {
1594 type filter hook input priority 0; policy drop;
1595
1596 # early drop of invalid connections
1597 ct state invalid drop
1598
1599 # allow established/related connections
1600 ct state { established, related } accept
1601
1602 # allow from loopback
1603 iifname lo accept
1604
1605 # allow icmp
1606 ip protocol icmp accept
1607 ip6 nexthdr icmpv6 accept
1608
1609 # allow ssh
1610 tcp dport ssh accept
1611
1612 # reject everything else
1613 reject with icmpx type port-unreachable
1614 }
1615 chain forward {
1616 type filter hook forward priority 0; policy drop;
1617 }
1618 chain output {
1619 type filter hook output priority 0; policy accept;
1620 }
1621 }
1622 "))
1623
1624 (define-record-type* <nftables-configuration>
1625 nftables-configuration
1626 make-nftables-configuration
1627 nftables-configuration?
1628 (package nftables-configuration-package
1629 (default nftables))
1630 (ruleset nftables-configuration-ruleset ; file-like object
1631 (default %default-nftables-ruleset)))
1632
1633 (define nftables-shepherd-service
1634 (match-lambda
1635 (($ <nftables-configuration> package ruleset)
1636 (let ((nft (file-append package "/sbin/nft")))
1637 (shepherd-service
1638 (documentation "Packet filtering and classification")
1639 (provision '(nftables))
1640 (start #~(lambda _
1641 (invoke #$nft "--file" #$ruleset)))
1642 (stop #~(lambda _
1643 (invoke #$nft "flush" "ruleset"))))))))
1644
1645 (define nftables-service-type
1646 (service-type
1647 (name 'nftables)
1648 (description
1649 "Run @command{nft}, setting up the specified ruleset.")
1650 (extensions
1651 (list (service-extension shepherd-root-service-type
1652 (compose list nftables-shepherd-service))
1653 (service-extension profile-service-type
1654 (compose list nftables-configuration-package))))
1655 (default-value (nftables-configuration))))
1656
1657 \f
1658 ;;;
1659 ;;; PageKite
1660 ;;;
1661
1662 (define-record-type* <pagekite-configuration>
1663 pagekite-configuration
1664 make-pagekite-configuration
1665 pagekite-configuration?
1666 (package pagekite-configuration-package
1667 (default pagekite))
1668 (kitename pagekite-configuration-kitename
1669 (default #f))
1670 (kitesecret pagekite-configuration-kitesecret
1671 (default #f))
1672 (frontend pagekite-configuration-frontend
1673 (default #f))
1674 (kites pagekite-configuration-kites
1675 (default '("http:@kitename:localhost:80:@kitesecret")))
1676 (extra-file pagekite-configuration-extra-file
1677 (default #f)))
1678
1679 (define (pagekite-configuration-file config)
1680 (match-record config <pagekite-configuration>
1681 (package kitename kitesecret frontend kites extra-file)
1682 (mixed-text-file "pagekite.rc"
1683 (if extra-file
1684 (string-append "optfile = " extra-file "\n")
1685 "")
1686 (if kitename
1687 (string-append "kitename = " kitename "\n")
1688 "")
1689 (if kitesecret
1690 (string-append "kitesecret = " kitesecret "\n")
1691 "")
1692 (if frontend
1693 (string-append "frontend = " frontend "\n")
1694 "defaults\n")
1695 (string-join (map (lambda (kite)
1696 (string-append "service_on = " kite))
1697 kites)
1698 "\n"
1699 'suffix))))
1700
1701 (define (pagekite-shepherd-service config)
1702 (match-record config <pagekite-configuration>
1703 (package kitename kitesecret frontend kites extra-file)
1704 (with-imported-modules (source-module-closure
1705 '((gnu build shepherd)
1706 (gnu system file-systems)))
1707 (shepherd-service
1708 (documentation "Run the PageKite service.")
1709 (provision '(pagekite))
1710 (requirement '(networking))
1711 (modules '((gnu build shepherd)
1712 (gnu system file-systems)))
1713 (start #~(make-forkexec-constructor/container
1714 (list #$(file-append package "/bin/pagekite")
1715 "--clean"
1716 "--nullui"
1717 "--nocrashreport"
1718 "--runas=pagekite:pagekite"
1719 (string-append "--optfile="
1720 #$(pagekite-configuration-file config)))
1721 #:log-file "/var/log/pagekite.log"
1722 #:mappings #$(if extra-file
1723 #~(list (file-system-mapping
1724 (source #$extra-file)
1725 (target source)))
1726 #~'())))
1727 ;; SIGTERM doesn't always work for some reason.
1728 (stop #~(make-kill-destructor SIGINT))))))
1729
1730 (define %pagekite-accounts
1731 (list (user-group (name "pagekite") (system? #t))
1732 (user-account
1733 (name "pagekite")
1734 (group "pagekite")
1735 (system? #t)
1736 (comment "PageKite user")
1737 (home-directory "/var/empty")
1738 (shell (file-append shadow "/sbin/nologin")))))
1739
1740 (define pagekite-service-type
1741 (service-type
1742 (name 'pagekite)
1743 (default-value (pagekite-configuration))
1744 (extensions
1745 (list (service-extension shepherd-root-service-type
1746 (compose list pagekite-shepherd-service))
1747 (service-extension account-service-type
1748 (const %pagekite-accounts))))
1749 (description
1750 "Run @url{https://pagekite.net/,PageKite}, a tunneling solution to make
1751 local servers publicly accessible on the web, even behind NATs and firewalls.")))
1752
1753 ;;; networking.scm ends here