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>
5 ;;; This file is part of GNU Guix.
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.
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.
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/>.
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
48 network-manager-service))
52 ;;; Networking services.
56 (define %facebook-host-aliases
57 ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
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
66 127.0.0.1 www.fbcdn.net
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
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
80 fe80::1%lo0 www.fbcdn.net
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")
90 (define-record-type* <static-networking>
91 static-networking make-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))
100 (define static-networking-service-type
104 (($ <static-networking> interface ip gateway provision
105 name-servers net-tools)
106 (let ((loopback? (memq 'loopback provision)))
108 ;; TODO: Eventually replace 'route' with bindings for the appropriate
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)))
117 "Bring up the networking interface using a static IP address.")
118 (provision provision)
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
129 #~(zero? (system* (string-append #$net-tools
131 "add" "-net" "default"
134 #$(if (pair? name-servers)
135 #~(call-with-output-file "/etc/resolv.conf"
138 "# Generated by 'static-networking-service'.\n"
140 (for-each (lambda (server)
141 (format port "nameserver ~a~%"
146 ;; Return #f is successfully stopped.
147 (let ((sock (socket AF_INET SOCK_STREAM 0)))
148 (set-network-interface-flags sock #$interface 0)
151 #~(system* (string-append #$net-tools
153 "del" "-net" "default")
157 (define* (static-networking-service interface ip
160 (provision '(networking))
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
166 (service static-networking-service-type
167 (static-networking (interface interface) (ip ip)
169 (provision provision)
170 (name-servers name-servers)
171 (net-tools net-tools))))
173 (define dhcp-client-service-type
178 #~(string-append #$dhcp "/sbin/dhclient"))
181 "/var/run/dhclient.pid")
184 (documentation "Set up networking via DHCP.")
185 (requirement '(user-processes udev))
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))
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.
199 (negate loopback-network-interface?))
201 (filter valid? (all-network-interface-names)))
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)
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)))
215 (call-with-input-file #$pid-file read))
217 ;; 'dhclient' returned before PID-FILE was created,
219 (let ((errno (system-error-errno args)))
224 (apply throw args))))))))))
225 (stop #~(make-kill-destructor))))))
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))
233 ;; Default set of NTP servers.
244 (define-record-type* <ntp-configuration>
245 ntp-configuration make-ntp-configuration
247 (ntp ntp-configuration-ntp
249 (servers ntp-configuration-servers))
251 (define ntp-dmd-service
253 (($ <ntp-configuration> ntp servers)
255 ;; TODO: Add authentication support.
257 (string-append "driftfile /var/run/ntp.drift\n"
258 (string-join (map (cut string-append "server " <>)
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
267 # Yet, allow use of the local 'ntpq'.
272 (plain-file "ntpd.conf" config))
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))))))))
283 (define %ntp-accounts
288 (comment "NTP daemon user")
289 (home-directory "/var/empty")
290 (shell #~(string-append #$shadow "/sbin/nologin")))))
292 (define ntp-service-type
293 (service-type (name 'ntp)
295 (list (service-extension dmd-root-service-type
297 (service-extension account-service-type
298 (const %ntp-accounts))))))
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))))
313 (define-record-type* <tor-configuration>
314 tor-configuration make-tor-configuration
316 (tor tor-configuration-tor
318 (config-file tor-configuration-config-file)
319 (hidden-services tor-configuration-hidden-services
322 (define %tor-accounts
323 ;; User account and groups for Tor.
324 (list (user-group (name "tor") (system? #t))
329 (comment "Tor daemon user")
330 (home-directory "/var/empty")
331 (shell #~(string-append #$shadow "/sbin/nologin")))))
333 (define-record-type <hidden-service>
334 (hidden-service name mapping)
336 (name hidden-service-name) ;string
337 (mapping hidden-service-mapping)) ;list of port/address tuples
339 (define (tor-configuration->torrc config)
340 "Return a 'torrc' file for CONFIG."
342 (($ <tor-configuration> tor config-file services)
346 (use-modules (guix build utils)
349 (call-with-output-file #$output
352 # The beginning was automatically added.
354 DataDirectory /var/lib/tor
355 Log notice syslog\n" port)
357 (for-each (match-lambda
358 ((service (ports hosts) ...)
360 HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
362 (for-each (lambda (tcp-port host)
364 HiddenServicePort ~a ~a~%"
367 '#$(map (match-lambda
368 (($ <hidden-service> name mapping)
369 (cons name mapping)))
372 ;; Append the user's config file.
373 (call-with-input-file #$config-file
375 (dump-port input port)))
377 #:modules '((guix build utils))))))
379 (define (tor-dmd-service config)
380 "Return a <dmd-service> running TOR."
382 (($ <tor-configuration> tor)
383 (let ((torrc (tor-configuration->torrc config)))
387 ;; Tor needs at least one network interface to be up, hence the
388 ;; dependency on 'loopback'.
389 (requirement '(user-processes loopback syslogd))
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.")))))))
396 (define (tor-hidden-service-activation config)
397 "Return the activation gexp for SERVICES, a list of hidden services."
399 (use-modules (guix build utils))
404 (define (initialize service)
405 (let ((directory (string-append "/var/lib/tor/hidden-services/"
408 (chown directory (passwd:uid %user) (passwd:gid %user))
410 ;; The daemon bails out if we give wider permissions.
411 (chmod directory #o700)))
413 (mkdir-p "/var/lib/tor")
414 (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
415 (chmod "/var/lib/tor" #o700)
418 '#$(map hidden-service-name
419 (tor-configuration-hidden-services config)))))
421 (define tor-service-type
422 (service-type (name 'tor)
424 (list (service-extension dmd-root-service-type
426 (service-extension account-service-type
427 (const %tor-accounts))
428 (service-extension activation-service-type
429 tor-hidden-service-activation)))
431 ;; This can be extended with hidden services.
432 (compose concatenate)
433 (extend (lambda (config services)
437 (append (tor-configuration-hidden-services config)
440 (define* (tor-service #:optional
441 (config-file (plain-file "empty" ""))
443 "Return a service to run the @uref{https://torproject.org, Tor} anonymous
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))))
454 (define tor-hidden-service-type
455 ;; A type that extends Tor with hidden services.
456 (service-type (name 'tor-hidden-service)
458 (list (service-extension tor-service-type list)))))
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:
465 '((22 \"127.0.0.1:22\")
466 (80 \"127.0.0.1:8080\"))
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.
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
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)))
486 (define-record-type* <bitlbee-configuration>
487 bitlbee-configuration make-bitlbee-configuration
488 bitlbee-configuration?
489 (bitlbee bitlbee-configuration-bitlbee
491 (interface bitlbee-configuration-interface)
492 (port bitlbee-configuration-port)
493 (extra-settings bitlbee-configuration-extra-settings))
495 (define bitlbee-dmd-service
497 (($ <bitlbee-configuration> bitlbee interface port extra-settings)
498 (let ((conf (plain-file "bitlbee.conf"
502 ConfigDir = /var/lib/bitlbee
503 DaemonInterface = " interface "
504 DaemonPort = " (number->string port) "
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))))))))
515 (define %bitlbee-accounts
516 ;; User group and account to run BitlBee.
517 (list (user-group (name "bitlbee") (system? #t))
522 (comment "BitlBee daemon user")
523 (home-directory "/var/empty")
524 (shell #~(string-append #$shadow "/sbin/nologin")))))
526 (define %bitlbee-activation
527 ;; Activation gexp for BitlBee.
529 (use-modules (guix build utils))
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)))))
537 (define bitlbee-service-type
538 (service-type (name 'bitlbee)
540 (list (service-extension dmd-root-service-type
542 (service-extension account-service-type
543 (const %bitlbee-accounts))
544 (service-extension activation-service-type
545 (const %bitlbee-activation))))))
547 (define* (bitlbee-service #:key (bitlbee bitlbee)
548 (interface "127.0.0.1") (port 6667)
550 "Return a service that runs @url{http://bitlbee.org,BitlBee}, a daemon that
551 acts as a gateway between IRC and chat networks.
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.
558 In addition, @var{extra-settings} specifies a string to append to the
560 (service bitlbee-service-type
561 (bitlbee-configuration
563 (interface interface) (port port)
564 (extra-settings extra-settings))))
571 (define %wicd-activation
572 ;; Activation gexp for Wicd.
574 (use-modules (guix build utils))
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)
582 (define (wicd-dmd-service wicd)
583 "Return a dmd service for WICD."
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")
591 (stop #~(make-kill-destructor)))))
593 (define wicd-service-type
594 (service-type (name 'wicd)
596 (list (service-extension dmd-root-service-type
598 (service-extension dbus-root-service-type
600 (service-extension activation-service-type
601 (const %wicd-activation))
603 ;; Add Wicd to the global profile.
604 (service-extension profile-service-type list)))))
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.
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))
621 (define %network-manager-activation
622 ;; Activation gexp for NetworkManager.
624 (use-modules (guix build utils))
625 (mkdir-p "/etc/NetworkManager/system-connections")))
627 (define (network-manager-dmd-service network-manager)
628 "Return a dmd service for NETWORK-MANAGER."
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")
637 (stop #~(make-kill-destructor)))))
639 (define network-manager-service-type
640 (service-type (name 'network-manager)
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)))))
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))
655 ;;; networking.scm ends here