networking.scm 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  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>
  7. ;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be>
  8. ;;;
  9. ;;; This file is part of GNU Guix.
  10. ;;;
  11. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  12. ;;; under the terms of the GNU General Public License as published by
  13. ;;; the Free Software Foundation; either version 3 of the License, or (at
  14. ;;; your option) any later version.
  15. ;;;
  16. ;;; GNU Guix is distributed in the hope that it will be useful, but
  17. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. ;;; GNU General Public License for more details.
  20. ;;;
  21. ;;; You should have received a copy of the GNU General Public License
  22. ;;; 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 services base)
  28. #:use-module (gnu system shadow)
  29. #:use-module (gnu system pam)
  30. #:use-module (gnu packages admin)
  31. #:use-module (gnu packages connman)
  32. #:use-module (gnu packages linux)
  33. #:use-module (gnu packages tor)
  34. #:use-module (gnu packages messaging)
  35. #:use-module (gnu packages networking)
  36. #:use-module (gnu packages ntp)
  37. #:use-module (gnu packages wicd)
  38. #:use-module (gnu packages gnome)
  39. #:use-module (guix gexp)
  40. #:use-module (guix records)
  41. #:use-module (guix modules)
  42. #:use-module (srfi srfi-1)
  43. #:use-module (srfi srfi-9)
  44. #:use-module (srfi srfi-26)
  45. #:use-module (ice-9 match)
  46. #:export (%facebook-host-aliases
  47. static-networking
  48. static-networking?
  49. static-networking-interface
  50. static-networking-ip
  51. static-networking-netmask
  52. static-networking-gateway
  53. static-networking-service
  54. static-networking-service-type
  55. dhcp-client-service
  56. %ntp-servers
  57. ntp-configuration
  58. ntp-configuration?
  59. ntp-service
  60. ntp-service-type
  61. inetd-configuration
  62. inetd-entry
  63. inetd-service-type
  64. tor-configuration
  65. tor-configuration?
  66. tor-hidden-service
  67. tor-service
  68. tor-service-type
  69. bitlbee-configuration
  70. bitlbee-configuration?
  71. bitlbee-service
  72. bitlbee-service-type
  73. wicd-service-type
  74. wicd-service
  75. network-manager-configuration
  76. network-manager-configuration?
  77. network-manager-configuration-dns
  78. network-manager-service-type
  79. connman-configuration
  80. connman-configuration?
  81. connman-service-type
  82. wpa-supplicant-service-type
  83. openvswitch-service-type
  84. openvswitch-configuration))
  85. ;;; Commentary:
  86. ;;;
  87. ;;; Networking services.
  88. ;;;
  89. ;;; Code:
  90. (define %facebook-host-aliases
  91. ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
  92. ;; are to block it.
  93. "\
  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
  99. 127.0.0.1 fbcdn.net
  100. 127.0.0.1 www.fbcdn.net
  101. 127.0.0.1 fbcdn.com
  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
  108. # Block Facebook IPv6.
  109. fe80::1%lo0 facebook.com
  110. fe80::1%lo0 login.facebook.com
  111. fe80::1%lo0 www.login.facebook.com
  112. fe80::1%lo0 fbcdn.net
  113. fe80::1%lo0 www.fbcdn.net
  114. fe80::1%lo0 fbcdn.com
  115. fe80::1%lo0 www.fbcdn.com
  116. fe80::1%lo0 static.ak.fbcdn.net
  117. fe80::1%lo0 static.ak.connect.facebook.com
  118. fe80::1%lo0 connect.facebook.net
  119. fe80::1%lo0 www.connect.facebook.net
  120. fe80::1%lo0 apps.facebook.com\n")
  121. (define-record-type* <static-networking>
  122. static-networking make-static-networking
  123. static-networking?
  124. (interface static-networking-interface)
  125. (ip static-networking-ip)
  126. (netmask static-networking-netmask
  127. (default #f))
  128. (gateway static-networking-gateway ;FIXME: doesn't belong here
  129. (default #f))
  130. (provision static-networking-provision
  131. (default #f))
  132. (name-servers static-networking-name-servers ;FIXME: doesn't belong here
  133. (default '())))
  134. (define static-networking-shepherd-service
  135. (match-lambda
  136. (($ <static-networking> interface ip netmask gateway provision
  137. name-servers)
  138. (let ((loopback? (and provision (memq 'loopback provision))))
  139. (shepherd-service
  140. ;; Unless we're providing the loopback interface, wait for udev to be up
  141. ;; and running so that INTERFACE is actually usable.
  142. (requirement (if loopback? '() '(udev)))
  143. (documentation
  144. "Bring up the networking interface using a static IP address.")
  145. (provision (or provision
  146. (list (symbol-append 'networking-
  147. (string->symbol interface)))))
  148. (start #~(lambda _
  149. ;; Return #t if successfully started.
  150. (let* ((addr (inet-pton AF_INET #$ip))
  151. (sockaddr (make-socket-address AF_INET addr 0))
  152. (mask (and #$netmask
  153. (inet-pton AF_INET #$netmask)))
  154. (maskaddr (and mask
  155. (make-socket-address AF_INET
  156. mask 0)))
  157. (gateway (and #$gateway
  158. (inet-pton AF_INET #$gateway)))
  159. (gatewayaddr (and gateway
  160. (make-socket-address AF_INET
  161. gateway 0))))
  162. (configure-network-interface #$interface sockaddr
  163. (logior IFF_UP
  164. #$(if loopback?
  165. #~IFF_LOOPBACK
  166. 0))
  167. #:netmask maskaddr)
  168. (when gateway
  169. (let ((sock (socket AF_INET SOCK_DGRAM 0)))
  170. (add-network-route/gateway sock gatewayaddr)
  171. (close-port sock))))))
  172. (stop #~(lambda _
  173. ;; Return #f is successfully stopped.
  174. (let ((sock (socket AF_INET SOCK_STREAM 0)))
  175. (when #$gateway
  176. (delete-network-route sock
  177. (make-socket-address
  178. AF_INET INADDR_ANY 0)))
  179. (set-network-interface-flags sock #$interface 0)
  180. (close-port sock)
  181. #f)))
  182. (respawn? #f))))))
  183. (define (static-networking-etc-files interfaces)
  184. "Return a /etc/resolv.conf entry for INTERFACES or the empty list."
  185. (match (delete-duplicates
  186. (append-map static-networking-name-servers
  187. interfaces))
  188. (()
  189. '())
  190. ((name-servers ...)
  191. (let ((content (string-join
  192. (map (cut string-append "nameserver " <>)
  193. name-servers)
  194. "\n" 'suffix)))
  195. `(("resolv.conf"
  196. ,(plain-file "resolv.conf"
  197. (string-append "\
  198. # Generated by 'static-networking-service'.\n"
  199. content))))))))
  200. (define (static-networking-shepherd-services interfaces)
  201. "Return the list of Shepherd services to bring up INTERFACES, a list of
  202. <static-networking> objects."
  203. (define (loopback? service)
  204. (memq 'loopback (shepherd-service-provision service)))
  205. (let ((services (map static-networking-shepherd-service interfaces)))
  206. (match (remove loopback? services)
  207. (()
  208. ;; There's no interface other than 'loopback', so we assume that the
  209. ;; 'networking' service will be provided by dhclient or similar.
  210. services)
  211. ((non-loopback ...)
  212. ;; Assume we're providing all the interfaces, and thus, provide a
  213. ;; 'networking' service.
  214. (cons (shepherd-service
  215. (provision '(networking))
  216. (requirement (append-map shepherd-service-provision
  217. services))
  218. (start #~(const #t))
  219. (stop #~(const #f))
  220. (documentation "Bring up all the networking interfaces."))
  221. services)))))
  222. (define static-networking-service-type
  223. ;; The service type for statically-defined network interfaces.
  224. (service-type (name 'static-networking)
  225. (extensions
  226. (list
  227. (service-extension shepherd-root-service-type
  228. static-networking-shepherd-services)
  229. (service-extension etc-service-type
  230. static-networking-etc-files)))
  231. (compose concatenate)
  232. (extend append)
  233. (description
  234. "Turn up the specified network interfaces upon startup,
  235. with the given IP address, gateway, netmask, and so on. The value for
  236. services of this type is a list of @code{static-networking} objects, one per
  237. network interface.")))
  238. (define* (static-networking-service interface ip
  239. #:key
  240. netmask gateway provision
  241. (name-servers '()))
  242. "Return a service that starts @var{interface} with address @var{ip}. If
  243. @var{netmask} is true, use it as the network mask. If @var{gateway} is true,
  244. it must be a string specifying the default network gateway.
  245. This procedure can be called several times, one for each network
  246. interface of interest. Behind the scenes what it does is extend
  247. @code{static-networking-service-type} with additional network interfaces
  248. to handle."
  249. (simple-service 'static-network-interface
  250. static-networking-service-type
  251. (list (static-networking (interface interface) (ip ip)
  252. (netmask netmask) (gateway gateway)
  253. (provision provision)
  254. (name-servers name-servers)))))
  255. (define dhcp-client-service-type
  256. (shepherd-service-type
  257. 'dhcp-client
  258. (lambda (dhcp)
  259. (define dhclient
  260. (file-append dhcp "/sbin/dhclient"))
  261. (define pid-file
  262. "/var/run/dhclient.pid")
  263. (shepherd-service
  264. (documentation "Set up networking via DHCP.")
  265. (requirement '(user-processes udev))
  266. ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
  267. ;; networking is unavailable, but also means that the interface is not up
  268. ;; yet when 'start' completes. To wait for the interface to be ready, one
  269. ;; should instead monitor udev events.
  270. (provision '(networking))
  271. (start #~(lambda _
  272. ;; When invoked without any arguments, 'dhclient' discovers all
  273. ;; non-loopback interfaces *that are up*. However, the relevant
  274. ;; interfaces are typically down at this point. Thus we perform
  275. ;; our own interface discovery here.
  276. (define valid?
  277. (negate loopback-network-interface?))
  278. (define ifaces
  279. (filter valid? (all-network-interface-names)))
  280. ;; XXX: Make sure the interfaces are up so that 'dhclient' can
  281. ;; actually send/receive over them.
  282. (for-each set-network-interface-up ifaces)
  283. (false-if-exception (delete-file #$pid-file))
  284. (let ((pid (fork+exec-command
  285. (cons* #$dhclient "-nw"
  286. "-pf" #$pid-file ifaces))))
  287. (and (zero? (cdr (waitpid pid)))
  288. (let loop ()
  289. (catch 'system-error
  290. (lambda ()
  291. (call-with-input-file #$pid-file read))
  292. (lambda args
  293. ;; 'dhclient' returned before PID-FILE was created,
  294. ;; so try again.
  295. (let ((errno (system-error-errno args)))
  296. (if (= ENOENT errno)
  297. (begin
  298. (sleep 1)
  299. (loop))
  300. (apply throw args))))))))))
  301. (stop #~(make-kill-destructor))))))
  302. (define* (dhcp-client-service #:key (dhcp isc-dhcp))
  303. "Return a service that runs @var{dhcp}, a Dynamic Host Configuration
  304. Protocol (DHCP) client, on all the non-loopback network interfaces."
  305. (service dhcp-client-service-type dhcp))
  306. (define %ntp-servers
  307. ;; Default set of NTP servers. These URLs are managed by the NTP Pool project.
  308. ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact
  309. ;; for this NTP pool "zone".
  310. '("0.guix.pool.ntp.org"
  311. "1.guix.pool.ntp.org"
  312. "2.guix.pool.ntp.org"
  313. "3.guix.pool.ntp.org"))
  314. ;;;
  315. ;;; NTP.
  316. ;;;
  317. ;; TODO: Export.
  318. (define-record-type* <ntp-configuration>
  319. ntp-configuration make-ntp-configuration
  320. ntp-configuration?
  321. (ntp ntp-configuration-ntp
  322. (default ntp))
  323. (servers ntp-configuration-servers)
  324. (allow-large-adjustment? ntp-allow-large-adjustment?
  325. (default #f)))
  326. (define ntp-shepherd-service
  327. (match-lambda
  328. (($ <ntp-configuration> ntp servers allow-large-adjustment?)
  329. (let ()
  330. ;; TODO: Add authentication support.
  331. (define config
  332. (string-append "driftfile /var/run/ntpd/ntp.drift\n"
  333. (string-join (map (cut string-append "server " <>)
  334. servers)
  335. "\n")
  336. "
  337. # Disable status queries as a workaround for CVE-2013-5211:
  338. # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
  339. restrict default kod nomodify notrap nopeer noquery
  340. restrict -6 default kod nomodify notrap nopeer noquery
  341. # Yet, allow use of the local 'ntpq'.
  342. restrict 127.0.0.1
  343. restrict -6 ::1\n"))
  344. (define ntpd.conf
  345. (plain-file "ntpd.conf" config))
  346. (list (shepherd-service
  347. (provision '(ntpd))
  348. (documentation "Run the Network Time Protocol (NTP) daemon.")
  349. (requirement '(user-processes networking))
  350. (start #~(make-forkexec-constructor
  351. (list (string-append #$ntp "/bin/ntpd") "-n"
  352. "-c" #$ntpd.conf "-u" "ntpd"
  353. #$@(if allow-large-adjustment?
  354. '("-g")
  355. '()))))
  356. (stop #~(make-kill-destructor))))))))
  357. (define %ntp-accounts
  358. (list (user-account
  359. (name "ntpd")
  360. (group "nogroup")
  361. (system? #t)
  362. (comment "NTP daemon user")
  363. (home-directory "/var/empty")
  364. (shell (file-append shadow "/sbin/nologin")))))
  365. (define (ntp-service-activation config)
  366. "Return the activation gexp for CONFIG."
  367. (with-imported-modules '((guix build utils))
  368. #~(begin
  369. (use-modules (guix build utils))
  370. (define %user
  371. (getpw "ntpd"))
  372. (let ((directory "/var/run/ntpd"))
  373. (mkdir-p directory)
  374. (chown directory (passwd:uid %user) (passwd:gid %user))))))
  375. (define ntp-service-type
  376. (service-type (name 'ntp)
  377. (extensions
  378. (list (service-extension shepherd-root-service-type
  379. ntp-shepherd-service)
  380. (service-extension account-service-type
  381. (const %ntp-accounts))
  382. (service-extension activation-service-type
  383. ntp-service-activation)))
  384. (description
  385. "Run the @command{ntpd}, the Network Time Protocol (NTP)
  386. daemon of the @uref{http://www.ntp.org, Network Time Foundation}. The daemon
  387. will keep the system clock synchronized with that of the given servers.")))
  388. (define* (ntp-service #:key (ntp ntp)
  389. (servers %ntp-servers)
  390. allow-large-adjustment?)
  391. "Return a service that runs the daemon from @var{ntp}, the
  392. @uref{http://www.ntp.org, Network Time Protocol package}. The daemon will
  393. keep the system clock synchronized with that of @var{servers}.
  394. @var{allow-large-adjustment?} determines whether @command{ntpd} is allowed to
  395. make an initial adjustment of more than 1,000 seconds."
  396. (service ntp-service-type
  397. (ntp-configuration (ntp ntp)
  398. (servers servers)
  399. (allow-large-adjustment?
  400. allow-large-adjustment?))))
  401. ;;;
  402. ;;; Inetd.
  403. ;;;
  404. (define-record-type* <inetd-configuration> inetd-configuration
  405. make-inetd-configuration
  406. inetd-configuration?
  407. (program inetd-configuration-program ;file-like
  408. (default (file-append inetutils "/libexec/inetd")))
  409. (entries inetd-configuration-entries ;list of <inetd-entry>
  410. (default '())))
  411. (define-record-type* <inetd-entry> inetd-entry make-inetd-entry
  412. inetd-entry?
  413. (node inetd-entry-node ;string or #f
  414. (default #f))
  415. (name inetd-entry-name) ;string, from /etc/services
  416. (socket-type inetd-entry-socket-type) ;stream | dgram | raw |
  417. ;rdm | seqpacket
  418. (protocol inetd-entry-protocol) ;string, from /etc/protocols
  419. (wait? inetd-entry-wait? ;Boolean
  420. (default #t))
  421. (user inetd-entry-user) ;string
  422. (program inetd-entry-program ;string or file-like object
  423. (default "internal"))
  424. (arguments inetd-entry-arguments ;list of strings or file-like objects
  425. (default '())))
  426. (define (inetd-config-file entries)
  427. (apply mixed-text-file "inetd.conf"
  428. (map
  429. (lambda (entry)
  430. (let* ((node (inetd-entry-node entry))
  431. (name (inetd-entry-name entry))
  432. (socket
  433. (if node (string-append node ":" name) name))
  434. (type
  435. (match (inetd-entry-socket-type entry)
  436. ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
  437. (symbol->string (inetd-entry-socket-type entry)))))
  438. (protocol (inetd-entry-protocol entry))
  439. (wait (if (inetd-entry-wait? entry) "wait" "nowait"))
  440. (user (inetd-entry-user entry))
  441. (program (inetd-entry-program entry))
  442. (args (inetd-entry-arguments entry)))
  443. #~(string-append
  444. (string-join
  445. (list #$@(list socket type protocol wait user program) #$@args)
  446. " ") "\n")))
  447. entries)))
  448. (define inetd-shepherd-service
  449. (match-lambda
  450. (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing
  451. (($ <inetd-configuration> program entries)
  452. (list
  453. (shepherd-service
  454. (documentation "Run inetd.")
  455. (provision '(inetd))
  456. (requirement '(user-processes networking syslogd))
  457. (start #~(make-forkexec-constructor
  458. (list #$program #$(inetd-config-file entries))
  459. #:pid-file "/var/run/inetd.pid"))
  460. (stop #~(make-kill-destructor)))))))
  461. (define-public inetd-service-type
  462. (service-type
  463. (name 'inetd)
  464. (extensions
  465. (list (service-extension shepherd-root-service-type
  466. inetd-shepherd-service)))
  467. ;; The service can be extended with additional lists of entries.
  468. (compose concatenate)
  469. (extend (lambda (config entries)
  470. (inetd-configuration
  471. (inherit config)
  472. (entries (append (inetd-configuration-entries config)
  473. entries)))))
  474. (description
  475. "Start @command{inetd}, the @dfn{Internet superserver}. It is responsible
  476. for listening on Internet sockets and spawning the corresponding services on
  477. demand.")))
  478. ;;;
  479. ;;; Tor.
  480. ;;;
  481. (define-record-type* <tor-configuration>
  482. tor-configuration make-tor-configuration
  483. tor-configuration?
  484. (tor tor-configuration-tor
  485. (default tor))
  486. (config-file tor-configuration-config-file
  487. (default (plain-file "empty" "")))
  488. (hidden-services tor-configuration-hidden-services
  489. (default '())))
  490. (define %tor-accounts
  491. ;; User account and groups for Tor.
  492. (list (user-group (name "tor") (system? #t))
  493. (user-account
  494. (name "tor")
  495. (group "tor")
  496. (system? #t)
  497. (comment "Tor daemon user")
  498. (home-directory "/var/empty")
  499. (shell (file-append shadow "/sbin/nologin")))))
  500. (define-record-type <hidden-service>
  501. (hidden-service name mapping)
  502. hidden-service?
  503. (name hidden-service-name) ;string
  504. (mapping hidden-service-mapping)) ;list of port/address tuples
  505. (define (tor-configuration->torrc config)
  506. "Return a 'torrc' file for CONFIG."
  507. (match config
  508. (($ <tor-configuration> tor config-file services)
  509. (computed-file
  510. "torrc"
  511. (with-imported-modules '((guix build utils))
  512. #~(begin
  513. (use-modules (guix build utils)
  514. (ice-9 match))
  515. (call-with-output-file #$output
  516. (lambda (port)
  517. (display "\
  518. # The beginning was automatically added.
  519. User tor
  520. DataDirectory /var/lib/tor
  521. Log notice syslog\n" port)
  522. (for-each (match-lambda
  523. ((service (ports hosts) ...)
  524. (format port "\
  525. HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
  526. service)
  527. (for-each (lambda (tcp-port host)
  528. (format port "\
  529. HiddenServicePort ~a ~a~%"
  530. tcp-port host))
  531. ports hosts)))
  532. '#$(map (match-lambda
  533. (($ <hidden-service> name mapping)
  534. (cons name mapping)))
  535. services))
  536. ;; Append the user's config file.
  537. (call-with-input-file #$config-file
  538. (lambda (input)
  539. (dump-port input port)))
  540. #t))))))))
  541. (define (tor-shepherd-service config)
  542. "Return a <shepherd-service> running TOR."
  543. (match config
  544. (($ <tor-configuration> tor)
  545. (let ((torrc (tor-configuration->torrc config)))
  546. (with-imported-modules (source-module-closure
  547. '((gnu build shepherd)
  548. (gnu system file-systems)))
  549. (list (shepherd-service
  550. (provision '(tor))
  551. ;; Tor needs at least one network interface to be up, hence the
  552. ;; dependency on 'loopback'.
  553. (requirement '(user-processes loopback syslogd))
  554. (modules '((gnu build shepherd)
  555. (gnu system file-systems)))
  556. (start #~(make-forkexec-constructor/container
  557. (list #$(file-append tor "/bin/tor") "-f" #$torrc)
  558. #:mappings (list (file-system-mapping
  559. (source "/var/lib/tor")
  560. (target source)
  561. (writable? #t))
  562. (file-system-mapping
  563. (source "/dev/log") ;for syslog
  564. (target source)))))
  565. (stop #~(make-kill-destructor))
  566. (documentation "Run the Tor anonymous network overlay."))))))))
  567. (define (tor-hidden-service-activation config)
  568. "Return the activation gexp for SERVICES, a list of hidden services."
  569. #~(begin
  570. (use-modules (guix build utils))
  571. (define %user
  572. (getpw "tor"))
  573. (define (initialize service)
  574. (let ((directory (string-append "/var/lib/tor/hidden-services/"
  575. service)))
  576. (mkdir-p directory)
  577. (chown directory (passwd:uid %user) (passwd:gid %user))
  578. ;; The daemon bails out if we give wider permissions.
  579. (chmod directory #o700)))
  580. (mkdir-p "/var/lib/tor")
  581. (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
  582. (chmod "/var/lib/tor" #o700)
  583. ;; Make sure /var/lib is accessible to the 'tor' user.
  584. (chmod "/var/lib" #o755)
  585. (for-each initialize
  586. '#$(map hidden-service-name
  587. (tor-configuration-hidden-services config)))))
  588. (define tor-service-type
  589. (service-type (name 'tor)
  590. (extensions
  591. (list (service-extension shepherd-root-service-type
  592. tor-shepherd-service)
  593. (service-extension account-service-type
  594. (const %tor-accounts))
  595. (service-extension activation-service-type
  596. tor-hidden-service-activation)))
  597. ;; This can be extended with hidden services.
  598. (compose concatenate)
  599. (extend (lambda (config services)
  600. (tor-configuration
  601. (inherit config)
  602. (hidden-services
  603. (append (tor-configuration-hidden-services config)
  604. services)))))
  605. (default-value (tor-configuration))
  606. (description
  607. "Run the @uref{https://torproject.org, Tor} anonymous
  608. networking daemon.")))
  609. (define* (tor-service #:optional
  610. (config-file (plain-file "empty" ""))
  611. #:key (tor tor))
  612. "Return a service to run the @uref{https://torproject.org, Tor} anonymous
  613. networking daemon.
  614. The daemon runs as the @code{tor} unprivileged user. It is passed
  615. @var{config-file}, a file-like object, with an additional @code{User tor} line
  616. and lines for hidden services added via @code{tor-hidden-service}. Run
  617. @command{man tor} for information about the configuration file."
  618. (service tor-service-type
  619. (tor-configuration (tor tor)
  620. (config-file config-file))))
  621. (define tor-hidden-service-type
  622. ;; A type that extends Tor with hidden services.
  623. (service-type (name 'tor-hidden-service)
  624. (extensions
  625. (list (service-extension tor-service-type list)))
  626. (description
  627. "Define a new Tor @dfn{hidden service}.")))
  628. (define (tor-hidden-service name mapping)
  629. "Define a new Tor @dfn{hidden service} called @var{name} and implementing
  630. @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
  631. @example
  632. '((22 \"127.0.0.1:22\")
  633. (80 \"127.0.0.1:8080\"))
  634. @end example
  635. In this example, port 22 of the hidden service is mapped to local port 22, and
  636. port 80 is mapped to local port 8080.
  637. This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
  638. the @file{hostname} file contains the @code{.onion} host name for the hidden
  639. service.
  640. See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
  641. project's documentation} for more information."
  642. (service tor-hidden-service-type
  643. (hidden-service name mapping)))
  644. ;;;
  645. ;;; BitlBee.
  646. ;;;
  647. (define-record-type* <bitlbee-configuration>
  648. bitlbee-configuration make-bitlbee-configuration
  649. bitlbee-configuration?
  650. (bitlbee bitlbee-configuration-bitlbee
  651. (default bitlbee))
  652. (interface bitlbee-configuration-interface
  653. (default "127.0.0.1"))
  654. (port bitlbee-configuration-port
  655. (default 6667))
  656. (extra-settings bitlbee-configuration-extra-settings
  657. (default "")))
  658. (define bitlbee-shepherd-service
  659. (match-lambda
  660. (($ <bitlbee-configuration> bitlbee interface port extra-settings)
  661. (let ((conf (plain-file "bitlbee.conf"
  662. (string-append "
  663. [settings]
  664. User = bitlbee
  665. ConfigDir = /var/lib/bitlbee
  666. DaemonInterface = " interface "
  667. DaemonPort = " (number->string port) "
  668. " extra-settings))))
  669. (with-imported-modules (source-module-closure
  670. '((gnu build shepherd)
  671. (gnu system file-systems)))
  672. (list (shepherd-service
  673. (provision '(bitlbee))
  674. ;; Note: If networking is not up, then /etc/resolv.conf
  675. ;; doesn't get mapped in the container, hence the dependency
  676. ;; on 'networking'.
  677. (requirement '(user-processes networking))
  678. (modules '((gnu build shepherd)
  679. (gnu system file-systems)))
  680. (start #~(make-forkexec-constructor/container
  681. (list #$(file-append bitlbee "/sbin/bitlbee")
  682. "-n" "-F" "-u" "bitlbee" "-c" #$conf)
  683. #:pid-file "/var/run/bitlbee.pid"
  684. #:mappings (list (file-system-mapping
  685. (source "/var/lib/bitlbee")
  686. (target source)
  687. (writable? #t)))))
  688. (stop #~(make-kill-destructor)))))))))
  689. (define %bitlbee-accounts
  690. ;; User group and account to run BitlBee.
  691. (list (user-group (name "bitlbee") (system? #t))
  692. (user-account
  693. (name "bitlbee")
  694. (group "bitlbee")
  695. (system? #t)
  696. (comment "BitlBee daemon user")
  697. (home-directory "/var/empty")
  698. (shell (file-append shadow "/sbin/nologin")))))
  699. (define %bitlbee-activation
  700. ;; Activation gexp for BitlBee.
  701. #~(begin
  702. (use-modules (guix build utils))
  703. ;; This directory is used to store OTR data.
  704. (mkdir-p "/var/lib/bitlbee")
  705. (let ((user (getpwnam "bitlbee")))
  706. (chown "/var/lib/bitlbee"
  707. (passwd:uid user) (passwd:gid user)))))
  708. (define bitlbee-service-type
  709. (service-type (name 'bitlbee)
  710. (extensions
  711. (list (service-extension shepherd-root-service-type
  712. bitlbee-shepherd-service)
  713. (service-extension account-service-type
  714. (const %bitlbee-accounts))
  715. (service-extension activation-service-type
  716. (const %bitlbee-activation))))
  717. (default-value (bitlbee-configuration))
  718. (description
  719. "Run @url{http://bitlbee.org,BitlBee}, a daemon that acts as
  720. a gateway between IRC and chat networks.")))
  721. (define* (bitlbee-service #:key (bitlbee bitlbee)
  722. (interface "127.0.0.1") (port 6667)
  723. (extra-settings ""))
  724. "Return a service that runs @url{http://bitlbee.org,BitlBee}, a daemon that
  725. acts as a gateway between IRC and chat networks.
  726. The daemon will listen to the interface corresponding to the IP address
  727. specified in @var{interface}, on @var{port}. @code{127.0.0.1} means that only
  728. local clients can connect, whereas @code{0.0.0.0} means that connections can
  729. come from any networking interface.
  730. In addition, @var{extra-settings} specifies a string to append to the
  731. configuration file."
  732. (service bitlbee-service-type
  733. (bitlbee-configuration
  734. (bitlbee bitlbee)
  735. (interface interface) (port port)
  736. (extra-settings extra-settings))))
  737. ;;;
  738. ;;; Wicd.
  739. ;;;
  740. (define %wicd-activation
  741. ;; Activation gexp for Wicd.
  742. #~(begin
  743. (use-modules (guix build utils))
  744. (mkdir-p "/etc/wicd")
  745. (let ((file-name "/etc/wicd/dhclient.conf.template.default"))
  746. (unless (file-exists? file-name)
  747. (copy-file (string-append #$wicd file-name)
  748. file-name)))
  749. ;; Wicd invokes 'wpa_supplicant', which needs this directory for its
  750. ;; named socket files.
  751. (mkdir-p "/var/run/wpa_supplicant")
  752. (chmod "/var/run/wpa_supplicant" #o750)))
  753. (define (wicd-shepherd-service wicd)
  754. "Return a shepherd service for WICD."
  755. (list (shepherd-service
  756. (documentation "Run the Wicd network manager.")
  757. (provision '(networking))
  758. (requirement '(user-processes dbus-system loopback))
  759. (start #~(make-forkexec-constructor
  760. (list (string-append #$wicd "/sbin/wicd")
  761. "--no-daemon")))
  762. (stop #~(make-kill-destructor)))))
  763. (define wicd-service-type
  764. (service-type (name 'wicd)
  765. (extensions
  766. (list (service-extension shepherd-root-service-type
  767. wicd-shepherd-service)
  768. (service-extension dbus-root-service-type
  769. list)
  770. (service-extension activation-service-type
  771. (const %wicd-activation))
  772. ;; Add Wicd to the global profile.
  773. (service-extension profile-service-type list)))
  774. (description
  775. "Run @url{https://launchpad.net/wicd,Wicd}, a network
  776. management daemon that aims to simplify wired and wireless networking.")))
  777. (define* (wicd-service #:key (wicd wicd))
  778. "Return a service that runs @url{https://launchpad.net/wicd,Wicd}, a network
  779. management daemon that aims to simplify wired and wireless networking.
  780. This service adds the @var{wicd} package to the global profile, providing
  781. several commands to interact with the daemon and configure networking:
  782. @command{wicd-client}, a graphical user interface, and the @command{wicd-cli}
  783. and @command{wicd-curses} user interfaces."
  784. (service wicd-service-type wicd))
  785. ;;;
  786. ;;; NetworkManager
  787. ;;;
  788. (define-record-type* <network-manager-configuration>
  789. network-manager-configuration make-network-manager-configuration
  790. network-manager-configuration?
  791. (network-manager network-manager-configuration-network-manager
  792. (default network-manager))
  793. (dns network-manager-configuration-dns
  794. (default "default"))
  795. (vpn-plugins network-manager-vpn-plugins ;list of <package>
  796. (default '())))
  797. (define %network-manager-activation
  798. ;; Activation gexp for NetworkManager.
  799. #~(begin
  800. (use-modules (guix build utils))
  801. (mkdir-p "/etc/NetworkManager/system-connections")))
  802. (define (vpn-plugin-directory plugins)
  803. "Return a directory containing PLUGINS, the NM VPN plugins."
  804. (directory-union "network-manager-vpn-plugins" plugins))
  805. (define network-manager-environment
  806. (match-lambda
  807. (($ <network-manager-configuration> network-manager dns vpn-plugins)
  808. ;; Define this variable in the global environment such that
  809. ;; "nmcli connection import type openvpn file foo.ovpn" works.
  810. `(("NM_VPN_PLUGIN_DIR"
  811. . ,(file-append (vpn-plugin-directory vpn-plugins)
  812. "/lib/NetworkManager/VPN"))))))
  813. (define network-manager-shepherd-service
  814. (match-lambda
  815. (($ <network-manager-configuration> network-manager dns vpn-plugins)
  816. (let ((conf (plain-file "NetworkManager.conf"
  817. (string-append "[main]\ndns=" dns "\n")))
  818. (vpn (vpn-plugin-directory vpn-plugins)))
  819. (list (shepherd-service
  820. (documentation "Run the NetworkManager.")
  821. (provision '(networking))
  822. (requirement '(user-processes dbus-system wpa-supplicant loopback))
  823. (start #~(make-forkexec-constructor
  824. (list (string-append #$network-manager
  825. "/sbin/NetworkManager")
  826. (string-append "--config=" #$conf)
  827. "--no-daemon")
  828. #:environment-variables
  829. (list (string-append "NM_VPN_PLUGIN_DIR=" #$vpn
  830. "/lib/NetworkManager/VPN"))))
  831. (stop #~(make-kill-destructor))))))))
  832. (define network-manager-service-type
  833. (let
  834. ((config->package
  835. (match-lambda
  836. (($ <network-manager-configuration> network-manager)
  837. (list network-manager)))))
  838. (service-type
  839. (name 'network-manager)
  840. (extensions
  841. (list (service-extension shepherd-root-service-type
  842. network-manager-shepherd-service)
  843. (service-extension dbus-root-service-type config->package)
  844. (service-extension polkit-service-type config->package)
  845. (service-extension activation-service-type
  846. (const %network-manager-activation))
  847. (service-extension session-environment-service-type
  848. network-manager-environment)
  849. ;; Add network-manager to the system profile.
  850. (service-extension profile-service-type config->package)))
  851. (default-value (network-manager-configuration))
  852. (description
  853. "Run @uref{https://wiki.gnome.org/Projects/NetworkManager,
  854. NetworkManager}, a network management daemon that aims to simplify wired and
  855. wireless networking."))))
  856. ;;;
  857. ;;; Connman
  858. ;;;
  859. (define-record-type* <connman-configuration>
  860. connman-configuration make-connman-configuration
  861. connman-configuration?
  862. (connman connman-configuration-connman
  863. (default connman))
  864. (disable-vpn? connman-configuration-disable-vpn?
  865. (default #f)))
  866. (define (connman-activation config)
  867. (let ((disable-vpn? (connman-configuration-disable-vpn? config)))
  868. (with-imported-modules '((guix build utils))
  869. #~(begin
  870. (use-modules (guix build utils))
  871. (mkdir-p "/var/lib/connman/")
  872. (unless #$disable-vpn?
  873. (mkdir-p "/var/lib/connman-vpn/"))))))
  874. (define (connman-shepherd-service config)
  875. "Return a shepherd service for Connman"
  876. (and
  877. (connman-configuration? config)
  878. (let ((connman (connman-configuration-connman config))
  879. (disable-vpn? (connman-configuration-disable-vpn? config)))
  880. (list (shepherd-service
  881. (documentation "Run Connman")
  882. (provision '(networking))
  883. (requirement
  884. '(user-processes dbus-system loopback wpa-supplicant))
  885. (start #~(make-forkexec-constructor
  886. (list (string-append #$connman
  887. "/sbin/connmand")
  888. "-n" "-r"
  889. #$@(if disable-vpn? '("--noplugin=vpn") '()))))
  890. (stop #~(make-kill-destructor)))))))
  891. (define connman-service-type
  892. (let ((connman-package (compose list connman-configuration-connman)))
  893. (service-type (name 'connman)
  894. (extensions
  895. (list (service-extension shepherd-root-service-type
  896. connman-shepherd-service)
  897. (service-extension dbus-root-service-type
  898. connman-package)
  899. (service-extension activation-service-type
  900. connman-activation)
  901. ;; Add connman to the system profile.
  902. (service-extension profile-service-type
  903. connman-package)))
  904. (description
  905. "Run @url{https://01.org/connman,Connman},
  906. a network connection manager."))))
  907. ;;;
  908. ;;; WPA supplicant
  909. ;;;
  910. (define (wpa-supplicant-shepherd-service wpa-supplicant)
  911. "Return a shepherd service for wpa_supplicant"
  912. (list (shepherd-service
  913. (documentation "Run WPA supplicant with dbus interface")
  914. (provision '(wpa-supplicant))
  915. (requirement '(user-processes dbus-system loopback))
  916. (start #~(make-forkexec-constructor
  917. (list (string-append #$wpa-supplicant
  918. "/sbin/wpa_supplicant")
  919. "-u" "-B" "-P/var/run/wpa_supplicant.pid")
  920. #:pid-file "/var/run/wpa_supplicant.pid"))
  921. (stop #~(make-kill-destructor)))))
  922. (define wpa-supplicant-service-type
  923. (service-type (name 'wpa-supplicant)
  924. (extensions
  925. (list (service-extension shepherd-root-service-type
  926. wpa-supplicant-shepherd-service)
  927. (service-extension dbus-root-service-type list)
  928. (service-extension profile-service-type list)))
  929. (default-value wpa-supplicant)))
  930. ;;;
  931. ;;; Open vSwitch
  932. ;;;
  933. (define-record-type* <openvswitch-configuration>
  934. openvswitch-configuration make-openvswitch-configuration
  935. openvswitch-configuration?
  936. (package openvswitch-configuration-package
  937. (default openvswitch)))
  938. (define openvswitch-activation
  939. (match-lambda
  940. (($ <openvswitch-configuration> package)
  941. (let ((ovsdb-tool (file-append package "/bin/ovsdb-tool")))
  942. (with-imported-modules '((guix build utils))
  943. #~(begin
  944. (use-modules (guix build utils))
  945. (mkdir-p "/var/run/openvswitch")
  946. (mkdir-p "/var/lib/openvswitch")
  947. (let ((conf.db "/var/lib/openvswitch/conf.db"))
  948. (unless (file-exists? conf.db)
  949. (system* #$ovsdb-tool "create" conf.db)))))))))
  950. (define openvswitch-shepherd-service
  951. (match-lambda
  952. (($ <openvswitch-configuration> package)
  953. (let ((ovsdb-server (file-append package "/sbin/ovsdb-server"))
  954. (ovs-vswitchd (file-append package "/sbin/ovs-vswitchd")))
  955. (list
  956. (shepherd-service
  957. (provision '(ovsdb))
  958. (documentation "Run the Open vSwitch database server.")
  959. (start #~(make-forkexec-constructor
  960. (list #$ovsdb-server "--pidfile"
  961. "--remote=punix:/var/run/openvswitch/db.sock")
  962. #:pid-file "/var/run/openvswitch/ovsdb-server.pid"))
  963. (stop #~(make-kill-destructor)))
  964. (shepherd-service
  965. (provision '(vswitchd))
  966. (requirement '(ovsdb))
  967. (documentation "Run the Open vSwitch daemon.")
  968. (start #~(make-forkexec-constructor
  969. (list #$ovs-vswitchd "--pidfile")
  970. #:pid-file "/var/run/openvswitch/ovs-vswitchd.pid"))
  971. (stop #~(make-kill-destructor))))))))
  972. (define openvswitch-service-type
  973. (service-type
  974. (name 'openvswitch)
  975. (extensions
  976. (list (service-extension activation-service-type
  977. openvswitch-activation)
  978. (service-extension profile-service-type
  979. (compose list openvswitch-configuration-package))
  980. (service-extension shepherd-root-service-type
  981. openvswitch-shepherd-service)))
  982. (description
  983. "Run @uref{http://www.openvswitch.org, Open vSwitch}, a multilayer virtual
  984. switch designed to enable massive network automation through programmatic
  985. extension.")))
  986. ;;; networking.scm ends here