1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
4 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
5 ;;; Copyright © 2016 John Darrington <jmd@gnu.org>
7 ;;; This file is part of GNU Guix.
9 ;;; GNU Guix is free software; you can redistribute it and/or modify it
10 ;;; under the terms of the GNU General Public License as published by
11 ;;; the Free Software Foundation; either version 3 of the License, or (at
12 ;;; your option) any later version.
14 ;;; GNU Guix is distributed in the hope that it will be useful, but
15 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;;; GNU General Public License for more details.
19 ;;; You should have received a copy of the GNU General Public License
20 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
22 (define-module (gnu services networking)
23 #:use-module (gnu services)
24 #:use-module (gnu services shepherd)
25 #:use-module (gnu services dbus)
26 #:use-module (gnu system shadow)
27 #:use-module (gnu system pam)
28 #:use-module (gnu packages admin)
29 #:use-module (gnu packages connman)
30 #:use-module (gnu packages linux)
31 #:use-module (gnu packages tor)
32 #:use-module (gnu packages messaging)
33 #:use-module (gnu packages ntp)
34 #:use-module (gnu packages wicd)
35 #:use-module (gnu packages gnome)
36 #:use-module (guix gexp)
37 #:use-module (guix records)
38 #:use-module (srfi srfi-1)
39 #:use-module (srfi srfi-9)
40 #:use-module (srfi srfi-26)
41 #:use-module (ice-9 match)
42 #:export (%facebook-host-aliases
44 static-networking-service
45 static-networking-service-type
61 bitlbee-configuration?
66 network-manager-service
71 ;;; Networking services.
75 (define %facebook-host-aliases
76 ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
79 # Block Facebook IPv4.
80 127.0.0.1 www.facebook.com
81 127.0.0.1 facebook.com
82 127.0.0.1 login.facebook.com
83 127.0.0.1 www.login.facebook.com
85 127.0.0.1 www.fbcdn.net
87 127.0.0.1 www.fbcdn.com
88 127.0.0.1 static.ak.fbcdn.net
89 127.0.0.1 static.ak.connect.facebook.com
90 127.0.0.1 connect.facebook.net
91 127.0.0.1 www.connect.facebook.net
92 127.0.0.1 apps.facebook.com
94 # Block Facebook IPv6.
95 fe80::1%lo0 facebook.com
96 fe80::1%lo0 login.facebook.com
97 fe80::1%lo0 www.login.facebook.com
99 fe80::1%lo0 www.fbcdn.net
100 fe80::1%lo0 fbcdn.com
101 fe80::1%lo0 www.fbcdn.com
102 fe80::1%lo0 static.ak.fbcdn.net
103 fe80::1%lo0 static.ak.connect.facebook.com
104 fe80::1%lo0 connect.facebook.net
105 fe80::1%lo0 www.connect.facebook.net
106 fe80::1%lo0 apps.facebook.com\n")
109 (define-record-type* <static-networking>
110 static-networking make-static-networking
112 (interface static-networking-interface)
113 (ip static-networking-ip)
114 (gateway static-networking-gateway)
115 (provision static-networking-provision)
116 (name-servers static-networking-name-servers)
117 (net-tools static-networking-net-tools))
119 (define static-networking-service-type
120 (shepherd-service-type
123 (($ <static-networking> interface ip gateway provision
124 name-servers net-tools)
125 (let ((loopback? (memq 'loopback provision)))
127 ;; TODO: Eventually replace 'route' with bindings for the appropriate
131 ;; Unless we're providing the loopback interface, wait for udev to be up
132 ;; and running so that INTERFACE is actually usable.
133 (requirement (if loopback? '() '(udev)))
136 "Bring up the networking interface using a static IP address.")
137 (provision provision)
139 ;; Return #t if successfully started.
140 (let* ((addr (inet-pton AF_INET #$ip))
141 (sockaddr (make-socket-address AF_INET addr 0)))
142 (configure-network-interface #$interface sockaddr
148 #~(zero? (system* (string-append #$net-tools
150 "add" "-net" "default"
153 #$(if (pair? name-servers)
154 #~(call-with-output-file "/etc/resolv.conf"
157 "# Generated by 'static-networking-service'.\n"
159 (for-each (lambda (server)
160 (format port "nameserver ~a~%"
165 ;; Return #f is successfully stopped.
166 (let ((sock (socket AF_INET SOCK_STREAM 0)))
167 (set-network-interface-flags sock #$interface 0)
170 #~(system* (string-append #$net-tools
172 "del" "-net" "default")
176 (define* (static-networking-service interface ip
179 (provision '(networking))
181 (net-tools net-tools))
182 "Return a service that starts @var{interface} with address @var{ip}. If
183 @var{gateway} is true, it must be a string specifying the default network
185 (service static-networking-service-type
186 (static-networking (interface interface) (ip ip)
188 (provision provision)
189 (name-servers name-servers)
190 (net-tools net-tools))))
192 (define dhcp-client-service-type
193 (shepherd-service-type
197 (file-append dhcp "/sbin/dhclient"))
200 "/var/run/dhclient.pid")
203 (documentation "Set up networking via DHCP.")
204 (requirement '(user-processes udev))
206 ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
207 ;; networking is unavailable, but also means that the interface is not up
208 ;; yet when 'start' completes. To wait for the interface to be ready, one
209 ;; should instead monitor udev events.
210 (provision '(networking))
213 ;; When invoked without any arguments, 'dhclient' discovers all
214 ;; non-loopback interfaces *that are up*. However, the relevant
215 ;; interfaces are typically down at this point. Thus we perform
216 ;; our own interface discovery here.
218 (negate loopback-network-interface?))
220 (filter valid? (all-network-interface-names)))
222 ;; XXX: Make sure the interfaces are up so that 'dhclient' can
223 ;; actually send/receive over them.
224 (for-each set-network-interface-up ifaces)
226 (false-if-exception (delete-file #$pid-file))
227 (let ((pid (fork+exec-command
228 (cons* #$dhclient "-nw"
229 "-pf" #$pid-file ifaces))))
230 (and (zero? (cdr (waitpid pid)))
234 (call-with-input-file #$pid-file read))
236 ;; 'dhclient' returned before PID-FILE was created,
238 (let ((errno (system-error-errno args)))
243 (apply throw args))))))))))
244 (stop #~(make-kill-destructor))))))
246 (define* (dhcp-client-service #:key (dhcp isc-dhcp))
247 "Return a service that runs @var{dhcp}, a Dynamic Host Configuration
248 Protocol (DHCP) client, on all the non-loopback network interfaces."
249 (service dhcp-client-service-type dhcp))
252 ;; Default set of NTP servers.
263 (define-record-type* <ntp-configuration>
264 ntp-configuration make-ntp-configuration
266 (ntp ntp-configuration-ntp
268 (servers ntp-configuration-servers))
270 (define ntp-shepherd-service
272 (($ <ntp-configuration> ntp servers)
274 ;; TODO: Add authentication support.
276 (string-append "driftfile /var/run/ntpd/ntp.drift\n"
277 (string-join (map (cut string-append "server " <>)
281 # Disable status queries as a workaround for CVE-2013-5211:
282 # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
283 restrict default kod nomodify notrap nopeer noquery
284 restrict -6 default kod nomodify notrap nopeer noquery
286 # Yet, allow use of the local 'ntpq'.
291 (plain-file "ntpd.conf" config))
293 (list (shepherd-service
295 (documentation "Run the Network Time Protocol (NTP) daemon.")
296 (requirement '(user-processes networking))
297 (start #~(make-forkexec-constructor
298 (list (string-append #$ntp "/bin/ntpd") "-n"
299 "-c" #$ntpd.conf "-u" "ntpd")))
300 (stop #~(make-kill-destructor))))))))
302 (define %ntp-accounts
307 (comment "NTP daemon user")
308 (home-directory "/var/empty")
309 (shell (file-append shadow "/sbin/nologin")))))
312 (define (ntp-service-activation config)
313 "Return the activation gexp for CONFIG."
314 (with-imported-modules '((guix build utils))
319 (let ((directory "/var/run/ntpd"))
321 (chown directory (passwd:uid %user) (passwd:gid %user))))))
323 (define ntp-service-type
324 (service-type (name 'ntp)
326 (list (service-extension shepherd-root-service-type
327 ntp-shepherd-service)
328 (service-extension account-service-type
329 (const %ntp-accounts))
330 (service-extension activation-service-type
331 ntp-service-activation)))))
333 (define* (ntp-service #:key (ntp ntp)
334 (servers %ntp-servers))
335 "Return a service that runs the daemon from @var{ntp}, the
336 @uref{http://www.ntp.org, Network Time Protocol package}. The daemon will
337 keep the system clock synchronized with that of @var{servers}."
338 (service ntp-service-type
339 (ntp-configuration (ntp ntp) (servers servers))))
346 (define-record-type* <tor-configuration>
347 tor-configuration make-tor-configuration
349 (tor tor-configuration-tor
351 (config-file tor-configuration-config-file)
352 (hidden-services tor-configuration-hidden-services
355 (define %tor-accounts
356 ;; User account and groups for Tor.
357 (list (user-group (name "tor") (system? #t))
362 (comment "Tor daemon user")
363 (home-directory "/var/empty")
364 (shell (file-append shadow "/sbin/nologin")))))
366 (define-record-type <hidden-service>
367 (hidden-service name mapping)
369 (name hidden-service-name) ;string
370 (mapping hidden-service-mapping)) ;list of port/address tuples
372 (define (tor-configuration->torrc config)
373 "Return a 'torrc' file for CONFIG."
375 (($ <tor-configuration> tor config-file services)
378 (with-imported-modules '((guix build utils))
380 (use-modules (guix build utils)
383 (call-with-output-file #$output
386 # The beginning was automatically added.
388 DataDirectory /var/lib/tor
389 Log notice syslog\n" port)
391 (for-each (match-lambda
392 ((service (ports hosts) ...)
394 HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
396 (for-each (lambda (tcp-port host)
398 HiddenServicePort ~a ~a~%"
401 '#$(map (match-lambda
402 (($ <hidden-service> name mapping)
403 (cons name mapping)))
406 ;; Append the user's config file.
407 (call-with-input-file #$config-file
409 (dump-port input port)))
412 (define (tor-shepherd-service config)
413 "Return a <shepherd-service> running TOR."
415 (($ <tor-configuration> tor)
416 (let ((torrc (tor-configuration->torrc config)))
417 (list (shepherd-service
420 ;; Tor needs at least one network interface to be up, hence the
421 ;; dependency on 'loopback'.
422 (requirement '(user-processes loopback syslogd))
424 (start #~(make-forkexec-constructor
425 (list (string-append #$tor "/bin/tor") "-f" #$torrc)))
426 (stop #~(make-kill-destructor))
427 (documentation "Run the Tor anonymous network overlay.")))))))
429 (define (tor-hidden-service-activation config)
430 "Return the activation gexp for SERVICES, a list of hidden services."
432 (use-modules (guix build utils))
437 (define (initialize service)
438 (let ((directory (string-append "/var/lib/tor/hidden-services/"
441 (chown directory (passwd:uid %user) (passwd:gid %user))
443 ;; The daemon bails out if we give wider permissions.
444 (chmod directory #o700)))
446 (mkdir-p "/var/lib/tor")
447 (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
448 (chmod "/var/lib/tor" #o700)
451 '#$(map hidden-service-name
452 (tor-configuration-hidden-services config)))))
454 (define tor-service-type
455 (service-type (name 'tor)
457 (list (service-extension shepherd-root-service-type
458 tor-shepherd-service)
459 (service-extension account-service-type
460 (const %tor-accounts))
461 (service-extension activation-service-type
462 tor-hidden-service-activation)))
464 ;; This can be extended with hidden services.
465 (compose concatenate)
466 (extend (lambda (config services)
470 (append (tor-configuration-hidden-services config)
473 (define* (tor-service #:optional
474 (config-file (plain-file "empty" ""))
476 "Return a service to run the @uref{https://torproject.org, Tor} anonymous
479 The daemon runs as the @code{tor} unprivileged user. It is passed
480 @var{config-file}, a file-like object, with an additional @code{User tor} line
481 and lines for hidden services added via @code{tor-hidden-service}. Run
482 @command{man tor} for information about the configuration file."
483 (service tor-service-type
484 (tor-configuration (tor tor)
485 (config-file config-file))))
487 (define tor-hidden-service-type
488 ;; A type that extends Tor with hidden services.
489 (service-type (name 'tor-hidden-service)
491 (list (service-extension tor-service-type list)))))
493 (define (tor-hidden-service name mapping)
494 "Define a new Tor @dfn{hidden service} called @var{name} and implementing
495 @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
498 '((22 \"127.0.0.1:22\")
499 (80 \"127.0.0.1:8080\"))
502 In this example, port 22 of the hidden service is mapped to local port 22, and
503 port 80 is mapped to local port 8080.
505 This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
506 the @file{hostname} file contains the @code{.onion} host name for the hidden
509 See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
510 project's documentation} for more information."
511 (service tor-hidden-service-type
512 (hidden-service name mapping)))
519 (define-record-type* <bitlbee-configuration>
520 bitlbee-configuration make-bitlbee-configuration
521 bitlbee-configuration?
522 (bitlbee bitlbee-configuration-bitlbee
524 (interface bitlbee-configuration-interface)
525 (port bitlbee-configuration-port)
526 (extra-settings bitlbee-configuration-extra-settings))
528 (define bitlbee-shepherd-service
530 (($ <bitlbee-configuration> bitlbee interface port extra-settings)
531 (let ((conf (plain-file "bitlbee.conf"
535 ConfigDir = /var/lib/bitlbee
536 DaemonInterface = " interface "
537 DaemonPort = " (number->string port) "
540 (list (shepherd-service
541 (provision '(bitlbee))
542 (requirement '(user-processes loopback))
543 (start #~(make-forkexec-constructor
544 (list (string-append #$bitlbee "/sbin/bitlbee")
545 "-n" "-F" "-u" "bitlbee" "-c" #$conf)))
546 (stop #~(make-kill-destructor))))))))
548 (define %bitlbee-accounts
549 ;; User group and account to run BitlBee.
550 (list (user-group (name "bitlbee") (system? #t))
555 (comment "BitlBee daemon user")
556 (home-directory "/var/empty")
557 (shell (file-append shadow "/sbin/nologin")))))
559 (define %bitlbee-activation
560 ;; Activation gexp for BitlBee.
562 (use-modules (guix build utils))
564 ;; This directory is used to store OTR data.
565 (mkdir-p "/var/lib/bitlbee")
566 (let ((user (getpwnam "bitlbee")))
567 (chown "/var/lib/bitlbee"
568 (passwd:uid user) (passwd:gid user)))))
570 (define bitlbee-service-type
571 (service-type (name 'bitlbee)
573 (list (service-extension shepherd-root-service-type
574 bitlbee-shepherd-service)
575 (service-extension account-service-type
576 (const %bitlbee-accounts))
577 (service-extension activation-service-type
578 (const %bitlbee-activation))))))
580 (define* (bitlbee-service #:key (bitlbee bitlbee)
581 (interface "127.0.0.1") (port 6667)
583 "Return a service that runs @url{http://bitlbee.org,BitlBee}, a daemon that
584 acts as a gateway between IRC and chat networks.
586 The daemon will listen to the interface corresponding to the IP address
587 specified in @var{interface}, on @var{port}. @code{127.0.0.1} means that only
588 local clients can connect, whereas @code{0.0.0.0} means that connections can
589 come from any networking interface.
591 In addition, @var{extra-settings} specifies a string to append to the
593 (service bitlbee-service-type
594 (bitlbee-configuration
596 (interface interface) (port port)
597 (extra-settings extra-settings))))
604 (define %wicd-activation
605 ;; Activation gexp for Wicd.
607 (use-modules (guix build utils))
609 (mkdir-p "/etc/wicd")
610 (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
611 (unless (file-exists? file-name)
612 (copy-file (string-append #$wicd file-name)
615 (define (wicd-shepherd-service wicd)
616 "Return a shepherd service for WICD."
617 (list (shepherd-service
618 (documentation "Run the Wicd network manager.")
619 (provision '(networking))
620 (requirement '(user-processes dbus-system loopback))
621 (start #~(make-forkexec-constructor
622 (list (string-append #$wicd "/sbin/wicd")
624 (stop #~(make-kill-destructor)))))
626 (define wicd-service-type
627 (service-type (name 'wicd)
629 (list (service-extension shepherd-root-service-type
630 wicd-shepherd-service)
631 (service-extension dbus-root-service-type
633 (service-extension activation-service-type
634 (const %wicd-activation))
636 ;; Add Wicd to the global profile.
637 (service-extension profile-service-type list)))))
639 (define* (wicd-service #:key (wicd wicd))
640 "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
641 management daemon that aims to simplify wired and wireless networking.
643 This service adds the @var{wicd} package to the global profile, providing
644 several commands to interact with the daemon and configure networking:
645 @command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
646 and @command{wicd-curses} user interfaces."
647 (service wicd-service-type wicd))
654 (define %network-manager-activation
655 ;; Activation gexp for NetworkManager.
657 (use-modules (guix build utils))
658 (mkdir-p "/etc/NetworkManager/system-connections")))
660 (define (network-manager-shepherd-service network-manager)
661 "Return a shepherd service for NETWORK-MANAGER."
662 (list (shepherd-service
663 (documentation "Run the NetworkManager.")
664 (provision '(networking))
665 (requirement '(user-processes dbus-system loopback))
666 (start #~(make-forkexec-constructor
667 (list (string-append #$network-manager
668 "/sbin/NetworkManager")
670 (stop #~(make-kill-destructor)))))
672 (define network-manager-service-type
673 (service-type (name 'network-manager)
675 (list (service-extension shepherd-root-service-type
676 network-manager-shepherd-service)
677 (service-extension dbus-root-service-type list)
678 (service-extension activation-service-type
679 (const %network-manager-activation))
680 ;; Add network-manager to the system profile.
681 (service-extension profile-service-type list)))))
683 (define* (network-manager-service #:key (network-manager network-manager))
684 "Return a service that runs NetworkManager, a network connection manager
685 that attempting to keep active network connectivity when available."
686 (service network-manager-service-type network-manager))
693 (define %connman-activation
694 ;; Activation gexp for Connman.
696 (use-modules (guix build utils))
697 (mkdir-p "/var/lib/connman/")
698 (mkdir-p "/var/lib/connman-vpn/")))
700 (define (connman-shepherd-service connman)
701 "Return a shepherd service for Connman"
702 (list (shepherd-service
703 (documentation "Run Connman")
704 (provision '(networking))
705 (requirement '(user-processes dbus-system loopback))
706 (start #~(make-forkexec-constructor
707 (list (string-append #$connman
710 (stop #~(make-kill-destructor)))))
712 (define connman-service-type
713 (service-type (name 'connman)
715 (list (service-extension shepherd-root-service-type
716 connman-shepherd-service)
717 (service-extension dbus-root-service-type list)
718 (service-extension activation-service-type
719 (const %connman-activation))
720 ;; Add connman to the system profile.
721 (service-extension profile-service-type list)))))
723 (define* (connman-service #:key (connman connman))
724 "Return a service that runs @url{https://01.org/connman,Connman}, a network
727 This service adds the @var{connman} package to the global profile, providing
728 several the @command{connmanctl} command to interact with the daemon and
729 configure networking."
730 (service connman-service-type connman))
732 ;;; networking.scm ends here