1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2013, 2014, 2015, 2016, 2017 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>
6 ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
8 ;;; This file is part of GNU Guix.
10 ;;; GNU Guix is free software; you can redistribute it and/or modify it
11 ;;; under the terms of the GNU General Public License as published by
12 ;;; the Free Software Foundation; either version 3 of the License, or (at
13 ;;; your option) any later version.
15 ;;; GNU Guix is distributed in the hope that it will be useful, but
16 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;;; GNU General Public License for more details.
20 ;;; You should have received a copy of the GNU General Public License
21 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
23 (define-module (gnu services networking)
24 #:use-module (gnu services)
25 #:use-module (gnu services shepherd)
26 #:use-module (gnu services dbus)
27 #:use-module (gnu system shadow)
28 #:use-module (gnu system pam)
29 #:use-module (gnu packages admin)
30 #:use-module (gnu packages connman)
31 #:use-module (gnu packages linux)
32 #:use-module (gnu packages tor)
33 #:use-module (gnu packages messaging)
34 #:use-module (gnu packages ntp)
35 #:use-module (gnu packages wicd)
36 #:use-module (gnu packages gnome)
37 #:use-module (guix gexp)
38 #:use-module (guix records)
39 #:use-module (srfi srfi-1)
40 #:use-module (srfi srfi-9)
41 #:use-module (srfi srfi-26)
42 #:use-module (ice-9 match)
43 #:export (%facebook-host-aliases
47 static-networking-interface
49 static-networking-netmask
50 static-networking-gateway
52 static-networking-service
53 static-networking-service-type
69 bitlbee-configuration?
76 network-manager-configuration
77 network-manager-configuration?
78 network-manager-configuration-dns
79 network-manager-service-type
82 wpa-supplicant-service-type))
86 ;;; Networking services.
90 (define %facebook-host-aliases
91 ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
94 # Block Facebook IPv4.
95 127.0.0.1 www.facebook.com
96 127.0.0.1 facebook.com
97 127.0.0.1 login.facebook.com
98 127.0.0.1 www.login.facebook.com
100 127.0.0.1 www.fbcdn.net
102 127.0.0.1 www.fbcdn.com
103 127.0.0.1 static.ak.fbcdn.net
104 127.0.0.1 static.ak.connect.facebook.com
105 127.0.0.1 connect.facebook.net
106 127.0.0.1 www.connect.facebook.net
107 127.0.0.1 apps.facebook.com
109 # Block Facebook IPv6.
110 fe80::1%lo0 facebook.com
111 fe80::1%lo0 login.facebook.com
112 fe80::1%lo0 www.login.facebook.com
113 fe80::1%lo0 fbcdn.net
114 fe80::1%lo0 www.fbcdn.net
115 fe80::1%lo0 fbcdn.com
116 fe80::1%lo0 www.fbcdn.com
117 fe80::1%lo0 static.ak.fbcdn.net
118 fe80::1%lo0 static.ak.connect.facebook.com
119 fe80::1%lo0 connect.facebook.net
120 fe80::1%lo0 www.connect.facebook.net
121 fe80::1%lo0 apps.facebook.com\n")
124 (define-record-type* <static-networking>
125 static-networking make-static-networking
127 (interface static-networking-interface)
128 (ip static-networking-ip)
129 (netmask static-networking-netmask
131 (gateway static-networking-gateway ;FIXME: doesn't belong here
133 (provision static-networking-provision
135 (name-servers static-networking-name-servers ;FIXME: doesn't belong here
138 (define static-networking-shepherd-service
140 (($ <static-networking> interface ip netmask gateway provision
142 (let ((loopback? (and provision (memq 'loopback provision))))
145 ;; Unless we're providing the loopback interface, wait for udev to be up
146 ;; and running so that INTERFACE is actually usable.
147 (requirement (if loopback? '() '(udev)))
150 "Bring up the networking interface using a static IP address.")
151 (provision (or provision
152 (list (symbol-append 'networking-
153 (string->symbol interface)))))
156 ;; Return #t if successfully started.
157 (let* ((addr (inet-pton AF_INET #$ip))
158 (sockaddr (make-socket-address AF_INET addr 0))
160 (inet-pton AF_INET #$netmask)))
162 (make-socket-address AF_INET
164 (gateway (and #$gateway
165 (inet-pton AF_INET #$gateway)))
166 (gatewayaddr (and gateway
167 (make-socket-address AF_INET
169 (configure-network-interface #$interface sockaddr
176 (let ((sock (socket AF_INET SOCK_DGRAM 0)))
177 (add-network-route/gateway sock gatewayaddr)
178 (close-port sock))))))
180 ;; Return #f is successfully stopped.
181 (let ((sock (socket AF_INET SOCK_STREAM 0)))
183 (delete-network-route sock
185 AF_INET INADDR_ANY 0)))
186 (set-network-interface-flags sock #$interface 0)
191 (define (static-networking-etc-files interfaces)
192 "Return a /etc/resolv.conf entry for INTERFACES or the empty list."
193 (match (delete-duplicates
194 (append-map static-networking-name-servers
199 (let ((content (string-join
200 (map (cut string-append "nameserver " <>)
204 ,(plain-file "resolv.conf"
206 # Generated by 'static-networking-service'.\n"
209 (define (static-networking-shepherd-services interfaces)
210 "Return the list of Shepherd services to bring up INTERFACES, a list of
211 <static-networking> objects."
212 (define (loopback? service)
213 (memq 'loopback (shepherd-service-provision service)))
215 (let ((services (map static-networking-shepherd-service interfaces)))
216 (match (remove loopback? services)
218 ;; There's no interface other than 'loopback', so we assume that the
219 ;; 'networking' service will be provided by dhclient or similar.
222 ;; Assume we're providing all the interfaces, and thus, provide a
223 ;; 'networking' service.
224 (cons (shepherd-service
225 (provision '(networking))
226 (requirement (append-map shepherd-service-provision
230 (documentation "Bring up all the networking interfaces."))
233 (define static-networking-service-type
234 ;; The service type for statically-defined network interfaces.
235 (service-type (name 'static-networking)
238 (service-extension shepherd-root-service-type
239 static-networking-shepherd-services)
240 (service-extension etc-service-type
241 static-networking-etc-files)))
242 (compose concatenate)
245 (define* (static-networking-service interface ip
247 netmask gateway provision
249 "Return a service that starts @var{interface} with address @var{ip}. If
250 @var{netmask} is true, use it as the network mask. If @var{gateway} is true,
251 it must be a string specifying the default network gateway.
253 This procedure can be called several times, one for each network
254 interface of interest. Behind the scenes what it does is extend
255 @code{static-networking-service-type} with additional network interfaces
257 (simple-service 'static-network-interface
258 static-networking-service-type
259 (list (static-networking (interface interface) (ip ip)
260 (netmask netmask) (gateway gateway)
261 (provision provision)
262 (name-servers name-servers)))))
264 (define dhcp-client-service-type
265 (shepherd-service-type
269 (file-append dhcp "/sbin/dhclient"))
272 "/var/run/dhclient.pid")
275 (documentation "Set up networking via DHCP.")
276 (requirement '(user-processes udev))
278 ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
279 ;; networking is unavailable, but also means that the interface is not up
280 ;; yet when 'start' completes. To wait for the interface to be ready, one
281 ;; should instead monitor udev events.
282 (provision '(networking))
285 ;; When invoked without any arguments, 'dhclient' discovers all
286 ;; non-loopback interfaces *that are up*. However, the relevant
287 ;; interfaces are typically down at this point. Thus we perform
288 ;; our own interface discovery here.
290 (negate loopback-network-interface?))
292 (filter valid? (all-network-interface-names)))
294 ;; XXX: Make sure the interfaces are up so that 'dhclient' can
295 ;; actually send/receive over them.
296 (for-each set-network-interface-up ifaces)
298 (false-if-exception (delete-file #$pid-file))
299 (let ((pid (fork+exec-command
300 (cons* #$dhclient "-nw"
301 "-pf" #$pid-file ifaces))))
302 (and (zero? (cdr (waitpid pid)))
306 (call-with-input-file #$pid-file read))
308 ;; 'dhclient' returned before PID-FILE was created,
310 (let ((errno (system-error-errno args)))
315 (apply throw args))))))))))
316 (stop #~(make-kill-destructor))))))
318 (define* (dhcp-client-service #:key (dhcp isc-dhcp))
319 "Return a service that runs @var{dhcp}, a Dynamic Host Configuration
320 Protocol (DHCP) client, on all the non-loopback network interfaces."
321 (service dhcp-client-service-type dhcp))
324 ;; Default set of NTP servers.
335 (define-record-type* <ntp-configuration>
336 ntp-configuration make-ntp-configuration
338 (ntp ntp-configuration-ntp
340 (servers ntp-configuration-servers)
341 (allow-large-adjustment? ntp-allow-large-adjustment?
344 (define ntp-shepherd-service
346 (($ <ntp-configuration> ntp servers allow-large-adjustment?)
348 ;; TODO: Add authentication support.
350 (string-append "driftfile /var/run/ntpd/ntp.drift\n"
351 (string-join (map (cut string-append "server " <>)
355 # Disable status queries as a workaround for CVE-2013-5211:
356 # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
357 restrict default kod nomodify notrap nopeer noquery
358 restrict -6 default kod nomodify notrap nopeer noquery
360 # Yet, allow use of the local 'ntpq'.
365 (plain-file "ntpd.conf" config))
367 (list (shepherd-service
369 (documentation "Run the Network Time Protocol (NTP) daemon.")
370 (requirement '(user-processes networking))
371 (start #~(make-forkexec-constructor
372 (list (string-append #$ntp "/bin/ntpd") "-n"
373 "-c" #$ntpd.conf "-u" "ntpd"
374 #$@(if allow-large-adjustment?
377 (stop #~(make-kill-destructor))))))))
379 (define %ntp-accounts
384 (comment "NTP daemon user")
385 (home-directory "/var/empty")
386 (shell (file-append shadow "/sbin/nologin")))))
389 (define (ntp-service-activation config)
390 "Return the activation gexp for CONFIG."
391 (with-imported-modules '((guix build utils))
393 (use-modules (guix build utils))
397 (let ((directory "/var/run/ntpd"))
399 (chown directory (passwd:uid %user) (passwd:gid %user))))))
401 (define ntp-service-type
402 (service-type (name 'ntp)
404 (list (service-extension shepherd-root-service-type
405 ntp-shepherd-service)
406 (service-extension account-service-type
407 (const %ntp-accounts))
408 (service-extension activation-service-type
409 ntp-service-activation)))))
411 (define* (ntp-service #:key (ntp ntp)
412 (servers %ntp-servers)
413 allow-large-adjustment?)
414 "Return a service that runs the daemon from @var{ntp}, the
415 @uref{http://www.ntp.org, Network Time Protocol package}. The daemon will
416 keep the system clock synchronized with that of @var{servers}.
417 @var{allow-large-adjustment?} determines whether @command{ntpd} is allowed to
418 make an initial adjustment of more than 1,000 seconds."
419 (service ntp-service-type
420 (ntp-configuration (ntp ntp)
422 (allow-large-adjustment?
423 allow-large-adjustment?))))
430 (define-record-type* <tor-configuration>
431 tor-configuration make-tor-configuration
433 (tor tor-configuration-tor
435 (config-file tor-configuration-config-file)
436 (hidden-services tor-configuration-hidden-services
439 (define %tor-accounts
440 ;; User account and groups for Tor.
441 (list (user-group (name "tor") (system? #t))
446 (comment "Tor daemon user")
447 (home-directory "/var/empty")
448 (shell (file-append shadow "/sbin/nologin")))))
450 (define-record-type <hidden-service>
451 (hidden-service name mapping)
453 (name hidden-service-name) ;string
454 (mapping hidden-service-mapping)) ;list of port/address tuples
456 (define (tor-configuration->torrc config)
457 "Return a 'torrc' file for CONFIG."
459 (($ <tor-configuration> tor config-file services)
462 (with-imported-modules '((guix build utils))
464 (use-modules (guix build utils)
467 (call-with-output-file #$output
470 # The beginning was automatically added.
472 DataDirectory /var/lib/tor
473 Log notice syslog\n" port)
475 (for-each (match-lambda
476 ((service (ports hosts) ...)
478 HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
480 (for-each (lambda (tcp-port host)
482 HiddenServicePort ~a ~a~%"
485 '#$(map (match-lambda
486 (($ <hidden-service> name mapping)
487 (cons name mapping)))
490 ;; Append the user's config file.
491 (call-with-input-file #$config-file
493 (dump-port input port)))
496 (define (tor-shepherd-service config)
497 "Return a <shepherd-service> running TOR."
499 (($ <tor-configuration> tor)
500 (let ((torrc (tor-configuration->torrc config)))
501 (list (shepherd-service
504 ;; Tor needs at least one network interface to be up, hence the
505 ;; dependency on 'loopback'.
506 (requirement '(user-processes loopback syslogd))
508 (start #~(make-forkexec-constructor
509 (list (string-append #$tor "/bin/tor") "-f" #$torrc)))
510 (stop #~(make-kill-destructor))
511 (documentation "Run the Tor anonymous network overlay.")))))))
513 (define (tor-hidden-service-activation config)
514 "Return the activation gexp for SERVICES, a list of hidden services."
516 (use-modules (guix build utils))
521 (define (initialize service)
522 (let ((directory (string-append "/var/lib/tor/hidden-services/"
525 (chown directory (passwd:uid %user) (passwd:gid %user))
527 ;; The daemon bails out if we give wider permissions.
528 (chmod directory #o700)))
530 (mkdir-p "/var/lib/tor")
531 (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
532 (chmod "/var/lib/tor" #o700)
534 ;; Make sure /var/lib is accessible to the 'tor' user.
535 (chmod "/var/lib" #o755)
538 '#$(map hidden-service-name
539 (tor-configuration-hidden-services config)))))
541 (define tor-service-type
542 (service-type (name 'tor)
544 (list (service-extension shepherd-root-service-type
545 tor-shepherd-service)
546 (service-extension account-service-type
547 (const %tor-accounts))
548 (service-extension activation-service-type
549 tor-hidden-service-activation)))
551 ;; This can be extended with hidden services.
552 (compose concatenate)
553 (extend (lambda (config services)
557 (append (tor-configuration-hidden-services config)
560 (define* (tor-service #:optional
561 (config-file (plain-file "empty" ""))
563 "Return a service to run the @uref{https://torproject.org, Tor} anonymous
566 The daemon runs as the @code{tor} unprivileged user. It is passed
567 @var{config-file}, a file-like object, with an additional @code{User tor} line
568 and lines for hidden services added via @code{tor-hidden-service}. Run
569 @command{man tor} for information about the configuration file."
570 (service tor-service-type
571 (tor-configuration (tor tor)
572 (config-file config-file))))
574 (define tor-hidden-service-type
575 ;; A type that extends Tor with hidden services.
576 (service-type (name 'tor-hidden-service)
578 (list (service-extension tor-service-type list)))))
580 (define (tor-hidden-service name mapping)
581 "Define a new Tor @dfn{hidden service} called @var{name} and implementing
582 @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
585 '((22 \"127.0.0.1:22\")
586 (80 \"127.0.0.1:8080\"))
589 In this example, port 22 of the hidden service is mapped to local port 22, and
590 port 80 is mapped to local port 8080.
592 This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
593 the @file{hostname} file contains the @code{.onion} host name for the hidden
596 See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
597 project's documentation} for more information."
598 (service tor-hidden-service-type
599 (hidden-service name mapping)))
606 (define-record-type* <bitlbee-configuration>
607 bitlbee-configuration make-bitlbee-configuration
608 bitlbee-configuration?
609 (bitlbee bitlbee-configuration-bitlbee
611 (interface bitlbee-configuration-interface)
612 (port bitlbee-configuration-port)
613 (extra-settings bitlbee-configuration-extra-settings))
615 (define bitlbee-shepherd-service
617 (($ <bitlbee-configuration> bitlbee interface port extra-settings)
618 (let ((conf (plain-file "bitlbee.conf"
622 ConfigDir = /var/lib/bitlbee
623 DaemonInterface = " interface "
624 DaemonPort = " (number->string port) "
627 (list (shepherd-service
628 (provision '(bitlbee))
629 (requirement '(user-processes loopback))
630 (start #~(make-forkexec-constructor
631 (list (string-append #$bitlbee "/sbin/bitlbee")
632 "-n" "-F" "-u" "bitlbee" "-c" #$conf)
633 #:pid-file "/var/run/bitlbee.pid"))
634 (stop #~(make-kill-destructor))))))))
636 (define %bitlbee-accounts
637 ;; User group and account to run BitlBee.
638 (list (user-group (name "bitlbee") (system? #t))
643 (comment "BitlBee daemon user")
644 (home-directory "/var/empty")
645 (shell (file-append shadow "/sbin/nologin")))))
647 (define %bitlbee-activation
648 ;; Activation gexp for BitlBee.
650 (use-modules (guix build utils))
652 ;; This directory is used to store OTR data.
653 (mkdir-p "/var/lib/bitlbee")
654 (let ((user (getpwnam "bitlbee")))
655 (chown "/var/lib/bitlbee"
656 (passwd:uid user) (passwd:gid user)))))
658 (define bitlbee-service-type
659 (service-type (name 'bitlbee)
661 (list (service-extension shepherd-root-service-type
662 bitlbee-shepherd-service)
663 (service-extension account-service-type
664 (const %bitlbee-accounts))
665 (service-extension activation-service-type
666 (const %bitlbee-activation))))))
668 (define* (bitlbee-service #:key (bitlbee bitlbee)
669 (interface "127.0.0.1") (port 6667)
671 "Return a service that runs @url{http://bitlbee.org,BitlBee}, a daemon that
672 acts as a gateway between IRC and chat networks.
674 The daemon will listen to the interface corresponding to the IP address
675 specified in @var{interface}, on @var{port}. @code{127.0.0.1} means that only
676 local clients can connect, whereas @code{0.0.0.0} means that connections can
677 come from any networking interface.
679 In addition, @var{extra-settings} specifies a string to append to the
681 (service bitlbee-service-type
682 (bitlbee-configuration
684 (interface interface) (port port)
685 (extra-settings extra-settings))))
692 (define %wicd-activation
693 ;; Activation gexp for Wicd.
695 (use-modules (guix build utils))
697 (mkdir-p "/etc/wicd")
698 (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
699 (unless (file-exists? file-name)
700 (copy-file (string-append #$wicd file-name)
703 ;; Wicd invokes 'wpa_supplicant', which needs this directory for its
704 ;; named socket files.
705 (mkdir-p "/var/run/wpa_supplicant")
706 (chmod "/var/run/wpa_supplicant" #o750)))
708 (define (wicd-shepherd-service wicd)
709 "Return a shepherd service for WICD."
710 (list (shepherd-service
711 (documentation "Run the Wicd network manager.")
712 (provision '(networking))
713 (requirement '(user-processes dbus-system loopback))
714 (start #~(make-forkexec-constructor
715 (list (string-append #$wicd "/sbin/wicd")
717 (stop #~(make-kill-destructor)))))
719 (define wicd-service-type
720 (service-type (name 'wicd)
722 (list (service-extension shepherd-root-service-type
723 wicd-shepherd-service)
724 (service-extension dbus-root-service-type
726 (service-extension activation-service-type
727 (const %wicd-activation))
729 ;; Add Wicd to the global profile.
730 (service-extension profile-service-type list)))))
732 (define* (wicd-service #:key (wicd wicd))
733 "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
734 management daemon that aims to simplify wired and wireless networking.
736 This service adds the @var{wicd} package to the global profile, providing
737 several commands to interact with the daemon and configure networking:
738 @command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
739 and @command{wicd-curses} user interfaces."
740 (service wicd-service-type wicd))
747 (define-record-type* <network-manager-configuration>
748 network-manager-configuration make-network-manager-configuration
749 network-manager-configuration?
750 (network-manager network-manager-configuration-network-manager
751 (default network-manager))
752 (dns network-manager-configuration-dns
753 (default "default")))
755 (define %network-manager-activation
756 ;; Activation gexp for NetworkManager.
758 (use-modules (guix build utils))
759 (mkdir-p "/etc/NetworkManager/system-connections")))
761 (define network-manager-shepherd-service
763 (($ <network-manager-configuration> network-manager dns)
765 ((conf (plain-file "NetworkManager.conf"
770 (list (shepherd-service
771 (documentation "Run the NetworkManager.")
772 (provision '(networking))
773 (requirement '(user-processes dbus-system wpa-supplicant loopback))
774 (start #~(make-forkexec-constructor
775 (list (string-append #$network-manager
776 "/sbin/NetworkManager")
777 (string-append "--config=" #$conf)
779 (stop #~(make-kill-destructor))))))))
781 (define network-manager-service-type
785 (($ <network-manager-configuration> network-manager)
786 (list network-manager)))))
789 (name 'network-manager)
791 (list (service-extension shepherd-root-service-type
792 network-manager-shepherd-service)
793 (service-extension dbus-root-service-type config->package)
794 (service-extension polkit-service-type config->package)
795 (service-extension activation-service-type
796 (const %network-manager-activation))
797 ;; Add network-manager to the system profile.
798 (service-extension profile-service-type config->package))))))
805 (define %connman-activation
806 ;; Activation gexp for Connman.
808 (use-modules (guix build utils))
809 (mkdir-p "/var/lib/connman/")
810 (mkdir-p "/var/lib/connman-vpn/")))
812 (define (connman-shepherd-service connman)
813 "Return a shepherd service for Connman"
814 (list (shepherd-service
815 (documentation "Run Connman")
816 (provision '(networking))
817 (requirement '(user-processes dbus-system loopback wpa-supplicant))
818 (start #~(make-forkexec-constructor
819 (list (string-append #$connman
822 (stop #~(make-kill-destructor)))))
824 (define connman-service-type
825 (service-type (name 'connman)
827 (list (service-extension shepherd-root-service-type
828 connman-shepherd-service)
829 (service-extension dbus-root-service-type list)
830 (service-extension activation-service-type
831 (const %connman-activation))
832 ;; Add connman to the system profile.
833 (service-extension profile-service-type list)))))
835 (define* (connman-service #:key (connman connman))
836 "Return a service that runs @url{https://01.org/connman,Connman}, a network
839 This service adds the @var{connman} package to the global profile, providing
840 several the @command{connmanctl} command to interact with the daemon and
841 configure networking."
842 (service connman-service-type connman))
851 (define (wpa-supplicant-shepherd-service wpa-supplicant)
852 "Return a shepherd service for wpa_supplicant"
853 (list (shepherd-service
854 (documentation "Run WPA supplicant with dbus interface")
855 (provision '(wpa-supplicant))
856 (requirement '(user-processes dbus-system loopback))
857 (start #~(make-forkexec-constructor
858 (list (string-append #$wpa-supplicant
859 "/sbin/wpa_supplicant")
860 "-u" "-B" "-P/var/run/wpa_supplicant.pid")
861 #:pid-file "/var/run/wpa_supplicant.pid"))
862 (stop #~(make-kill-destructor)))))
864 (define wpa-supplicant-service-type
865 (service-type (name 'wpa-supplicant)
867 (list (service-extension shepherd-root-service-type
868 wpa-supplicant-shepherd-service)
869 (service-extension dbus-root-service-type list)
870 (service-extension profile-service-type list)))))
872 ;;; networking.scm ends here