services: tor: Store private data under /var/lib/tor.
[jackhill/guix/guix.git] / gnu / services / networking.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
4 ;;;
5 ;;; This file is part of GNU Guix.
6 ;;;
7 ;;; GNU Guix is free software; you can redistribute it and/or modify it
8 ;;; under the terms of the GNU General Public License as published by
9 ;;; the Free Software Foundation; either version 3 of the License, or (at
10 ;;; your option) any later version.
11 ;;;
12 ;;; GNU Guix is distributed in the hope that it will be useful, but
13 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;;; GNU General Public License for more details.
16 ;;;
17 ;;; You should have received a copy of the GNU General Public License
18 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20 (define-module (gnu services networking)
21 #:use-module (gnu services)
22 #:use-module (gnu services dmd)
23 #:use-module (gnu services dbus)
24 #:use-module (gnu system shadow)
25 #:use-module (gnu system pam)
26 #:use-module (gnu packages admin)
27 #:use-module (gnu packages linux)
28 #:use-module (gnu packages tor)
29 #:use-module (gnu packages messaging)
30 #:use-module (gnu packages ntp)
31 #:use-module (gnu packages wicd)
32 #:use-module (gnu packages gnome)
33 #:use-module (guix gexp)
34 #:use-module (guix records)
35 #:use-module (srfi srfi-1)
36 #:use-module (srfi srfi-9)
37 #:use-module (srfi srfi-26)
38 #:use-module (ice-9 match)
39 #:export (%facebook-host-aliases
40 static-networking-service
41 dhcp-client-service
42 %ntp-servers
43 ntp-service
44 tor-hidden-service
45 tor-service
46 bitlbee-service
47 wicd-service
48 network-manager-service))
49
50 ;;; Commentary:
51 ;;;
52 ;;; Networking services.
53 ;;;
54 ;;; Code:
55
56 (define %facebook-host-aliases
57 ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
58 ;; are to block it.
59 "\
60 # Block Facebook IPv4.
61 127.0.0.1 www.facebook.com
62 127.0.0.1 facebook.com
63 127.0.0.1 login.facebook.com
64 127.0.0.1 www.login.facebook.com
65 127.0.0.1 fbcdn.net
66 127.0.0.1 www.fbcdn.net
67 127.0.0.1 fbcdn.com
68 127.0.0.1 www.fbcdn.com
69 127.0.0.1 static.ak.fbcdn.net
70 127.0.0.1 static.ak.connect.facebook.com
71 127.0.0.1 connect.facebook.net
72 127.0.0.1 www.connect.facebook.net
73 127.0.0.1 apps.facebook.com
74
75 # Block Facebook IPv6.
76 fe80::1%lo0 facebook.com
77 fe80::1%lo0 login.facebook.com
78 fe80::1%lo0 www.login.facebook.com
79 fe80::1%lo0 fbcdn.net
80 fe80::1%lo0 www.fbcdn.net
81 fe80::1%lo0 fbcdn.com
82 fe80::1%lo0 www.fbcdn.com
83 fe80::1%lo0 static.ak.fbcdn.net
84 fe80::1%lo0 static.ak.connect.facebook.com
85 fe80::1%lo0 connect.facebook.net
86 fe80::1%lo0 www.connect.facebook.net
87 fe80::1%lo0 apps.facebook.com\n")
88
89
90 (define-record-type* <static-networking>
91 static-networking make-static-networking
92 static-networking?
93 (interface static-networking-interface)
94 (ip static-networking-ip)
95 (gateway static-networking-gateway)
96 (provision static-networking-provision)
97 (name-servers static-networking-name-servers)
98 (net-tools static-networking-net-tools))
99
100 (define static-networking-service-type
101 (dmd-service-type
102 'static-networking
103 (match-lambda
104 (($ <static-networking> interface ip gateway provision
105 name-servers net-tools)
106 (let ((loopback? (memq 'loopback provision)))
107
108 ;; TODO: Eventually replace 'route' with bindings for the appropriate
109 ;; ioctls.
110 (dmd-service
111
112 ;; Unless we're providing the loopback interface, wait for udev to be up
113 ;; and running so that INTERFACE is actually usable.
114 (requirement (if loopback? '() '(udev)))
115
116 (documentation
117 "Bring up the networking interface using a static IP address.")
118 (provision provision)
119 (start #~(lambda _
120 ;; Return #t if successfully started.
121 (let* ((addr (inet-pton AF_INET #$ip))
122 (sockaddr (make-socket-address AF_INET addr 0)))
123 (configure-network-interface #$interface sockaddr
124 (logior IFF_UP
125 #$(if loopback?
126 #~IFF_LOOPBACK
127 0))))
128 #$(if gateway
129 #~(zero? (system* (string-append #$net-tools
130 "/sbin/route")
131 "add" "-net" "default"
132 "gw" #$gateway))
133 #t)
134 #$(if (pair? name-servers)
135 #~(call-with-output-file "/etc/resolv.conf"
136 (lambda (port)
137 (display
138 "# Generated by 'static-networking-service'.\n"
139 port)
140 (for-each (lambda (server)
141 (format port "nameserver ~a~%"
142 server))
143 '#$name-servers)))
144 #t)))
145 (stop #~(lambda _
146 ;; Return #f is successfully stopped.
147 (let ((sock (socket AF_INET SOCK_STREAM 0)))
148 (set-network-interface-flags sock #$interface 0)
149 (close-port sock))
150 (not #$(if gateway
151 #~(system* (string-append #$net-tools
152 "/sbin/route")
153 "del" "-net" "default")
154 #t))))
155 (respawn? #f)))))))
156
157 (define* (static-networking-service interface ip
158 #:key
159 gateway
160 (provision '(networking))
161 (name-servers '())
162 (net-tools net-tools))
163 "Return a service that starts @var{interface} with address @var{ip}. If
164 @var{gateway} is true, it must be a string specifying the default network
165 gateway."
166 (service static-networking-service-type
167 (static-networking (interface interface) (ip ip)
168 (gateway gateway)
169 (provision provision)
170 (name-servers name-servers)
171 (net-tools net-tools))))
172
173 (define dhcp-client-service-type
174 (dmd-service-type
175 'dhcp-client
176 (lambda (dhcp)
177 (define dhclient
178 #~(string-append #$dhcp "/sbin/dhclient"))
179
180 (define pid-file
181 "/var/run/dhclient.pid")
182
183 (dmd-service
184 (documentation "Set up networking via DHCP.")
185 (requirement '(user-processes udev))
186
187 ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
188 ;; networking is unavailable, but also means that the interface is not up
189 ;; yet when 'start' completes. To wait for the interface to be ready, one
190 ;; should instead monitor udev events.
191 (provision '(networking))
192
193 (start #~(lambda _
194 ;; When invoked without any arguments, 'dhclient' discovers all
195 ;; non-loopback interfaces *that are up*. However, the relevant
196 ;; interfaces are typically down at this point. Thus we perform
197 ;; our own interface discovery here.
198 (define valid?
199 (negate loopback-network-interface?))
200 (define ifaces
201 (filter valid? (all-network-interface-names)))
202
203 ;; XXX: Make sure the interfaces are up so that 'dhclient' can
204 ;; actually send/receive over them.
205 (for-each set-network-interface-up ifaces)
206
207 (false-if-exception (delete-file #$pid-file))
208 (let ((pid (fork+exec-command
209 (cons* #$dhclient "-nw"
210 "-pf" #$pid-file ifaces))))
211 (and (zero? (cdr (waitpid pid)))
212 (let loop ()
213 (catch 'system-error
214 (lambda ()
215 (call-with-input-file #$pid-file read))
216 (lambda args
217 ;; 'dhclient' returned before PID-FILE was created,
218 ;; so try again.
219 (let ((errno (system-error-errno args)))
220 (if (= ENOENT errno)
221 (begin
222 (sleep 1)
223 (loop))
224 (apply throw args))))))))))
225 (stop #~(make-kill-destructor))))))
226
227 (define* (dhcp-client-service #:key (dhcp isc-dhcp))
228 "Return a service that runs @var{dhcp}, a Dynamic Host Configuration
229 Protocol (DHCP) client, on all the non-loopback network interfaces."
230 (service dhcp-client-service-type dhcp))
231
232 (define %ntp-servers
233 ;; Default set of NTP servers.
234 '("0.pool.ntp.org"
235 "1.pool.ntp.org"
236 "2.pool.ntp.org"))
237
238 \f
239 ;;;
240 ;;; NTP.
241 ;;;
242
243 ;; TODO: Export.
244 (define-record-type* <ntp-configuration>
245 ntp-configuration make-ntp-configuration
246 ntp-configuration?
247 (ntp ntp-configuration-ntp
248 (default ntp))
249 (servers ntp-configuration-servers))
250
251 (define ntp-dmd-service
252 (match-lambda
253 (($ <ntp-configuration> ntp servers)
254 (let ()
255 ;; TODO: Add authentication support.
256 (define config
257 (string-append "driftfile /var/run/ntp.drift\n"
258 (string-join (map (cut string-append "server " <>)
259 servers)
260 "\n")
261 "
262 # Disable status queries as a workaround for CVE-2013-5211:
263 # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
264 restrict default kod nomodify notrap nopeer noquery
265 restrict -6 default kod nomodify notrap nopeer noquery
266
267 # Yet, allow use of the local 'ntpq'.
268 restrict 127.0.0.1
269 restrict -6 ::1\n"))
270
271 (define ntpd.conf
272 (plain-file "ntpd.conf" config))
273
274 (list (dmd-service
275 (provision '(ntpd))
276 (documentation "Run the Network Time Protocol (NTP) daemon.")
277 (requirement '(user-processes networking))
278 (start #~(make-forkexec-constructor
279 (list (string-append #$ntp "/bin/ntpd") "-n"
280 "-c" #$ntpd.conf "-u" "ntpd")))
281 (stop #~(make-kill-destructor))))))))
282
283 (define %ntp-accounts
284 (list (user-account
285 (name "ntpd")
286 (group "nogroup")
287 (system? #t)
288 (comment "NTP daemon user")
289 (home-directory "/var/empty")
290 (shell #~(string-append #$shadow "/sbin/nologin")))))
291
292 (define ntp-service-type
293 (service-type (name 'ntp)
294 (extensions
295 (list (service-extension dmd-root-service-type
296 ntp-dmd-service)
297 (service-extension account-service-type
298 (const %ntp-accounts))))))
299
300 (define* (ntp-service #:key (ntp ntp)
301 (servers %ntp-servers))
302 "Return a service that runs the daemon from @var{ntp}, the
303 @uref{http://www.ntp.org, Network Time Protocol package}. The daemon will
304 keep the system clock synchronized with that of @var{servers}."
305 (service ntp-service-type
306 (ntp-configuration (ntp ntp) (servers servers))))
307
308 \f
309 ;;;
310 ;;; Tor.
311 ;;;
312
313 (define-record-type* <tor-configuration>
314 tor-configuration make-tor-configuration
315 tor-configuration?
316 (tor tor-configuration-tor
317 (default tor))
318 (config-file tor-configuration-config-file)
319 (hidden-services tor-configuration-hidden-services
320 (default '())))
321
322 (define %tor-accounts
323 ;; User account and groups for Tor.
324 (list (user-group (name "tor") (system? #t))
325 (user-account
326 (name "tor")
327 (group "tor")
328 (system? #t)
329 (comment "Tor daemon user")
330 (home-directory "/var/empty")
331 (shell #~(string-append #$shadow "/sbin/nologin")))))
332
333 (define-record-type <hidden-service>
334 (hidden-service name mapping)
335 hidden-service?
336 (name hidden-service-name) ;string
337 (mapping hidden-service-mapping)) ;list of port/address tuples
338
339 (define (tor-configuration->torrc config)
340 "Return a 'torrc' file for CONFIG."
341 (match config
342 (($ <tor-configuration> tor config-file services)
343 (computed-file
344 "torrc"
345 #~(begin
346 (use-modules (guix build utils)
347 (ice-9 match))
348
349 (call-with-output-file #$output
350 (lambda (port)
351 (display "\
352 # The beginning was automatically added.
353 User tor
354 DataDirectory /var/lib/tor
355 Log notice syslog\n" port)
356
357 (for-each (match-lambda
358 ((service (ports hosts) ...)
359 (format port "\
360 HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
361 service)
362 (for-each (lambda (tcp-port host)
363 (format port "\
364 HiddenServicePort ~a ~a~%"
365 tcp-port host))
366 ports hosts)))
367 '#$(map (match-lambda
368 (($ <hidden-service> name mapping)
369 (cons name mapping)))
370 services))
371
372 ;; Append the user's config file.
373 (call-with-input-file #$config-file
374 (lambda (input)
375 (dump-port input port)))
376 #t)))
377 #:modules '((guix build utils))))))
378
379 (define (tor-dmd-service config)
380 "Return a <dmd-service> running TOR."
381 (match config
382 (($ <tor-configuration> tor)
383 (let ((torrc (tor-configuration->torrc config)))
384 (list (dmd-service
385 (provision '(tor))
386
387 ;; Tor needs at least one network interface to be up, hence the
388 ;; dependency on 'loopback'.
389 (requirement '(user-processes loopback syslogd))
390
391 (start #~(make-forkexec-constructor
392 (list (string-append #$tor "/bin/tor") "-f" #$torrc)))
393 (stop #~(make-kill-destructor))
394 (documentation "Run the Tor anonymous network overlay.")))))))
395
396 (define (tor-hidden-service-activation config)
397 "Return the activation gexp for SERVICES, a list of hidden services."
398 #~(begin
399 (use-modules (guix build utils))
400
401 (define %user
402 (getpw "tor"))
403
404 (define (initialize service)
405 (let ((directory (string-append "/var/lib/tor/hidden-services/"
406 service)))
407 (mkdir-p directory)
408 (chown directory (passwd:uid %user) (passwd:gid %user))
409
410 ;; The daemon bails out if we give wider permissions.
411 (chmod directory #o700)))
412
413 (mkdir-p "/var/lib/tor")
414 (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
415 (chmod "/var/lib/tor" #o700)
416
417 (for-each initialize
418 '#$(map hidden-service-name
419 (tor-configuration-hidden-services config)))))
420
421 (define tor-service-type
422 (service-type (name 'tor)
423 (extensions
424 (list (service-extension dmd-root-service-type
425 tor-dmd-service)
426 (service-extension account-service-type
427 (const %tor-accounts))
428 (service-extension activation-service-type
429 tor-hidden-service-activation)))
430
431 ;; This can be extended with hidden services.
432 (compose concatenate)
433 (extend (lambda (config services)
434 (tor-configuration
435 (inherit config)
436 (hidden-services
437 (append (tor-configuration-hidden-services config)
438 services)))))))
439
440 (define* (tor-service #:optional
441 (config-file (plain-file "empty" ""))
442 #:key (tor tor))
443 "Return a service to run the @uref{https://torproject.org, Tor} anonymous
444 networking daemon.
445
446 The daemon runs as the @code{tor} unprivileged user. It is passed
447 @var{config-file}, a file-like object, with an additional @code{User tor} line
448 and lines for hidden services added via @code{tor-hidden-service}. Run
449 @command{man tor} for information about the configuration file."
450 (service tor-service-type
451 (tor-configuration (tor tor)
452 (config-file config-file))))
453
454 (define tor-hidden-service-type
455 ;; A type that extends Tor with hidden services.
456 (service-type (name 'tor-hidden-service)
457 (extensions
458 (list (service-extension tor-service-type list)))))
459
460 (define (tor-hidden-service name mapping)
461 "Define a new Tor @dfn{hidden service} called @var{name} and implementing
462 @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
463
464 @example
465 '((22 \"127.0.0.1:22\")
466 (80 \"127.0.0.1:8080\"))
467 @end example
468
469 In this example, port 22 of the hidden service is mapped to local port 22, and
470 port 80 is mapped to local port 8080.
471
472 This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
473 the @file{hostname} file contains the @code{.onion} host name for the hidden
474 service.
475
476 See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
477 project's documentation} for more information."
478 (service tor-hidden-service-type
479 (hidden-service name mapping)))
480
481 \f
482 ;;;
483 ;;; BitlBee.
484 ;;;
485
486 (define-record-type* <bitlbee-configuration>
487 bitlbee-configuration make-bitlbee-configuration
488 bitlbee-configuration?
489 (bitlbee bitlbee-configuration-bitlbee
490 (default bitlbee))
491 (interface bitlbee-configuration-interface)
492 (port bitlbee-configuration-port)
493 (extra-settings bitlbee-configuration-extra-settings))
494
495 (define bitlbee-dmd-service
496 (match-lambda
497 (($ <bitlbee-configuration> bitlbee interface port extra-settings)
498 (let ((conf (plain-file "bitlbee.conf"
499 (string-append "
500 [settings]
501 User = bitlbee
502 ConfigDir = /var/lib/bitlbee
503 DaemonInterface = " interface "
504 DaemonPort = " (number->string port) "
505 " extra-settings))))
506
507 (list (dmd-service
508 (provision '(bitlbee))
509 (requirement '(user-processes loopback))
510 (start #~(make-forkexec-constructor
511 (list (string-append #$bitlbee "/sbin/bitlbee")
512 "-n" "-F" "-u" "bitlbee" "-c" #$conf)))
513 (stop #~(make-kill-destructor))))))))
514
515 (define %bitlbee-accounts
516 ;; User group and account to run BitlBee.
517 (list (user-group (name "bitlbee") (system? #t))
518 (user-account
519 (name "bitlbee")
520 (group "bitlbee")
521 (system? #t)
522 (comment "BitlBee daemon user")
523 (home-directory "/var/empty")
524 (shell #~(string-append #$shadow "/sbin/nologin")))))
525
526 (define %bitlbee-activation
527 ;; Activation gexp for BitlBee.
528 #~(begin
529 (use-modules (guix build utils))
530
531 ;; This directory is used to store OTR data.
532 (mkdir-p "/var/lib/bitlbee")
533 (let ((user (getpwnam "bitlbee")))
534 (chown "/var/lib/bitlbee"
535 (passwd:uid user) (passwd:gid user)))))
536
537 (define bitlbee-service-type
538 (service-type (name 'bitlbee)
539 (extensions
540 (list (service-extension dmd-root-service-type
541 bitlbee-dmd-service)
542 (service-extension account-service-type
543 (const %bitlbee-accounts))
544 (service-extension activation-service-type
545 (const %bitlbee-activation))))))
546
547 (define* (bitlbee-service #:key (bitlbee bitlbee)
548 (interface "127.0.0.1") (port 6667)
549 (extra-settings ""))
550 "Return a service that runs @url{http://bitlbee.org,BitlBee}, a daemon that
551 acts as a gateway between IRC and chat networks.
552
553 The daemon will listen to the interface corresponding to the IP address
554 specified in @var{interface}, on @var{port}. @code{127.0.0.1} means that only
555 local clients can connect, whereas @code{0.0.0.0} means that connections can
556 come from any networking interface.
557
558 In addition, @var{extra-settings} specifies a string to append to the
559 configuration file."
560 (service bitlbee-service-type
561 (bitlbee-configuration
562 (bitlbee bitlbee)
563 (interface interface) (port port)
564 (extra-settings extra-settings))))
565
566 \f
567 ;;;
568 ;;; Wicd.
569 ;;;
570
571 (define %wicd-activation
572 ;; Activation gexp for Wicd.
573 #~(begin
574 (use-modules (guix build utils))
575
576 (mkdir-p "/etc/wicd")
577 (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
578 (unless (file-exists? file-name)
579 (copy-file (string-append #$wicd file-name)
580 file-name)))))
581
582 (define (wicd-dmd-service wicd)
583 "Return a dmd service for WICD."
584 (list (dmd-service
585 (documentation "Run the Wicd network manager.")
586 (provision '(networking))
587 (requirement '(user-processes dbus-system loopback))
588 (start #~(make-forkexec-constructor
589 (list (string-append #$wicd "/sbin/wicd")
590 "--no-daemon")))
591 (stop #~(make-kill-destructor)))))
592
593 (define wicd-service-type
594 (service-type (name 'wicd)
595 (extensions
596 (list (service-extension dmd-root-service-type
597 wicd-dmd-service)
598 (service-extension dbus-root-service-type
599 list)
600 (service-extension activation-service-type
601 (const %wicd-activation))
602
603 ;; Add Wicd to the global profile.
604 (service-extension profile-service-type list)))))
605
606 (define* (wicd-service #:key (wicd wicd))
607 "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
608 management daemon that aims to simplify wired and wireless networking.
609
610 This service adds the @var{wicd} package to the global profile, providing
611 several commands to interact with the daemon and configure networking:
612 @command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
613 and @command{wicd-curses} user interfaces."
614 (service wicd-service-type wicd))
615
616 \f
617 ;;;
618 ;;; NetworkManager
619 ;;;
620
621 (define %network-manager-activation
622 ;; Activation gexp for NetworkManager.
623 #~(begin
624 (use-modules (guix build utils))
625 (mkdir-p "/etc/NetworkManager/system-connections")))
626
627 (define (network-manager-dmd-service network-manager)
628 "Return a dmd service for NETWORK-MANAGER."
629 (list (dmd-service
630 (documentation "Run the NetworkManager.")
631 (provision '(networking))
632 (requirement '(user-processes dbus-system loopback))
633 (start #~(make-forkexec-constructor
634 (list (string-append #$network-manager
635 "/sbin/NetworkManager")
636 "--no-daemon")))
637 (stop #~(make-kill-destructor)))))
638
639 (define network-manager-service-type
640 (service-type (name 'network-manager)
641 (extensions
642 (list (service-extension dmd-root-service-type
643 network-manager-dmd-service)
644 (service-extension dbus-root-service-type list)
645 (service-extension activation-service-type
646 (const %network-manager-activation))
647 ;; Add network-manager to the system profile.
648 (service-extension profile-service-type list)))))
649
650 (define* (network-manager-service #:key (network-manager network-manager))
651 "Return a service that runs NetworkManager, a network connection manager
652 that attempting to keep active network connectivity when available."
653 (service network-manager-service-type network-manager))
654
655 ;;; networking.scm ends here