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