networking.scm 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2013-2022 Ludovic Courtès <ludo@gnu.org>
  3. ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
  4. ;;; Copyright © 2016, 2018, 2020 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. ;;; Copyright © 2017, 2018 Marius Bakke <mbakke@fastmail.com>
  9. ;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
  10. ;;; Copyright © 2018 Chris Marusich <cmmarusich@gmail.com>
  11. ;;; Copyright © 2018 Arun Isaac <arunisaac@systemreboot.net>
  12. ;;; Copyright © 2019 Florian Pelz <pelzflorian@pelzflorian.de>
  13. ;;; Copyright © 2019, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
  14. ;;; Copyright © 2019 Sou Bunnbu <iyzsong@member.fsf.org>
  15. ;;; Copyright © 2019 Alex Griffin <a@ajgrf.com>
  16. ;;; Copyright © 2020 Brice Waegeneire <brice@waegenei.re>
  17. ;;; Copyright © 2021 Oleg Pykhalov <go.wigust@gmail.com>
  18. ;;; Copyright © 2021 Christine Lemmer-Webber <cwebber@dustycloud.org>
  19. ;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
  20. ;;; Copyright © 2021 Guillaume Le Vaillant <glv@posteo.net>
  21. ;;;
  22. ;;; This file is part of GNU Guix.
  23. ;;;
  24. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  25. ;;; under the terms of the GNU General Public License as published by
  26. ;;; the Free Software Foundation; either version 3 of the License, or (at
  27. ;;; your option) any later version.
  28. ;;;
  29. ;;; GNU Guix is distributed in the hope that it will be useful, but
  30. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  31. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  32. ;;; GNU General Public License for more details.
  33. ;;;
  34. ;;; You should have received a copy of the GNU General Public License
  35. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  36. (define-module (gnu services networking)
  37. #:use-module (gnu services)
  38. #:use-module (gnu services base)
  39. #:use-module (gnu services configuration)
  40. #:use-module (gnu services linux)
  41. #:use-module (gnu services shepherd)
  42. #:use-module (gnu services dbus)
  43. #:use-module (gnu services admin)
  44. #:use-module (gnu system shadow)
  45. #:use-module (gnu system pam)
  46. #:use-module ((gnu system file-systems) #:select (file-system-mapping))
  47. #:use-module (gnu packages admin)
  48. #:use-module (gnu packages base)
  49. #:use-module (gnu packages bash)
  50. #:use-module (gnu packages cluster)
  51. #:use-module (gnu packages connman)
  52. #:use-module (gnu packages freedesktop)
  53. #:use-module (gnu packages linux)
  54. #:use-module (gnu packages tor)
  55. #:use-module (gnu packages usb-modeswitch)
  56. #:use-module (gnu packages messaging)
  57. #:use-module (gnu packages networking)
  58. #:use-module (gnu packages ntp)
  59. #:use-module (gnu packages gnome)
  60. #:use-module (gnu packages ipfs)
  61. #:use-module (gnu build linux-container)
  62. #:autoload (guix least-authority) (least-authority-wrapper)
  63. #:use-module (guix gexp)
  64. #:use-module (guix records)
  65. #:use-module (guix modules)
  66. #:use-module (guix packages)
  67. #:use-module (guix deprecation)
  68. #:use-module (rnrs enums)
  69. #:use-module (srfi srfi-1)
  70. #:use-module (srfi srfi-9)
  71. #:use-module (srfi srfi-26)
  72. #:use-module (srfi srfi-43)
  73. #:use-module (ice-9 match)
  74. #:use-module (json)
  75. #:re-export (static-networking-service
  76. static-networking-service-type)
  77. #:export (%facebook-host-aliases
  78. dhcp-client-service-type
  79. dhcpd-service-type
  80. dhcpd-configuration
  81. dhcpd-configuration?
  82. dhcpd-configuration-package
  83. dhcpd-configuration-config-file
  84. dhcpd-configuration-version
  85. dhcpd-configuration-run-directory
  86. dhcpd-configuration-lease-file
  87. dhcpd-configuration-pid-file
  88. dhcpd-configuration-interfaces
  89. ntp-configuration
  90. ntp-configuration?
  91. ntp-configuration-ntp
  92. ntp-configuration-servers
  93. ntp-allow-large-adjustment?
  94. %ntp-servers
  95. ntp-server
  96. ntp-server-type
  97. ntp-server-address
  98. ntp-server-options
  99. ntp-service-type
  100. %openntpd-servers
  101. openntpd-configuration
  102. openntpd-configuration?
  103. openntpd-service-type
  104. inetd-configuration
  105. inetd-entry
  106. inetd-service-type
  107. opendht-configuration
  108. opendht-configuration-peer-discovery?
  109. opendht-configuration-verbose?
  110. opendht-configuration-bootstrap-host
  111. opendht-configuration-port
  112. opendht-configuration-proxy-server-port
  113. opendht-configuration-proxy-server-port-tls
  114. opendht-configuration->command-line-arguments
  115. opendht-shepherd-service
  116. opendht-service-type
  117. tor-configuration
  118. tor-configuration?
  119. tor-hidden-service
  120. tor-service-type
  121. network-manager-configuration
  122. network-manager-configuration?
  123. network-manager-configuration-dns
  124. network-manager-configuration-vpn-plugins
  125. network-manager-service-type
  126. connman-configuration
  127. connman-configuration?
  128. connman-service-type
  129. modem-manager-configuration
  130. modem-manager-configuration?
  131. modem-manager-service-type
  132. usb-modeswitch-configuration
  133. usb-modeswitch-configuration?
  134. usb-modeswitch-configuration-usb-modeswitch
  135. usb-modeswitch-configuration-usb-modeswitch-data
  136. usb-modeswitch-service-type
  137. wpa-supplicant-configuration
  138. wpa-supplicant-configuration?
  139. wpa-supplicant-configuration-wpa-supplicant
  140. wpa-supplicant-configuration-requirement
  141. wpa-supplicant-configuration-pid-file
  142. wpa-supplicant-configuration-dbus?
  143. wpa-supplicant-configuration-interface
  144. wpa-supplicant-configuration-config-file
  145. wpa-supplicant-configuration-extra-options
  146. wpa-supplicant-service-type
  147. hostapd-configuration
  148. hostapd-configuration?
  149. hostapd-configuration-package
  150. hostapd-configuration-interface
  151. hostapd-configuration-ssid
  152. hostapd-configuration-broadcast-ssid?
  153. hostapd-configuration-channel
  154. hostapd-configuration-driver
  155. hostapd-service-type
  156. simulated-wifi-service-type
  157. openvswitch-service-type
  158. openvswitch-configuration
  159. iptables-configuration
  160. iptables-configuration?
  161. iptables-configuration-iptables
  162. iptables-configuration-ipv4-rules
  163. iptables-configuration-ipv6-rules
  164. iptables-service-type
  165. nftables-service-type
  166. nftables-configuration
  167. nftables-configuration?
  168. nftables-configuration-package
  169. nftables-configuration-ruleset
  170. %default-nftables-ruleset
  171. pagekite-service-type
  172. pagekite-configuration
  173. pagekite-configuration?
  174. pagekite-configuration-package
  175. pagekite-configuration-kitename
  176. pagekite-configuration-kitesecret
  177. pagekite-configuration-frontend
  178. pagekite-configuration-kites
  179. pagekite-configuration-extra-file
  180. yggdrasil-service-type
  181. yggdrasil-configuration
  182. yggdrasil-configuration?
  183. yggdrasil-configuration-autoconf?
  184. yggdrasil-configuration-config-file
  185. yggdrasil-configuration-log-level
  186. yggdrasil-configuration-log-to
  187. yggdrasil-configuration-json-config
  188. yggdrasil-configuration-package
  189. ipfs-service-type
  190. ipfs-configuration
  191. ipfs-configuration?
  192. ipfs-configuration-package
  193. ipfs-configuration-gateway
  194. ipfs-configuration-api
  195. keepalived-configuration
  196. keepalived-configuration?
  197. keepalived-service-type))
  198. ;;; Commentary:
  199. ;;;
  200. ;;; Networking services.
  201. ;;;
  202. ;;; Code:
  203. (define %facebook-host-aliases
  204. ;; This is the list of known Facebook hosts to be added to /etc/hosts if you
  205. ;; are to block it.
  206. "\
  207. # Block Facebook IPv4.
  208. 127.0.0.1 www.facebook.com
  209. 127.0.0.1 facebook.com
  210. 127.0.0.1 login.facebook.com
  211. 127.0.0.1 www.login.facebook.com
  212. 127.0.0.1 fbcdn.net
  213. 127.0.0.1 www.fbcdn.net
  214. 127.0.0.1 fbcdn.com
  215. 127.0.0.1 www.fbcdn.com
  216. 127.0.0.1 static.ak.fbcdn.net
  217. 127.0.0.1 static.ak.connect.facebook.com
  218. 127.0.0.1 connect.facebook.net
  219. 127.0.0.1 www.connect.facebook.net
  220. 127.0.0.1 apps.facebook.com
  221. # Block Facebook IPv6.
  222. fe80::1%lo0 facebook.com
  223. fe80::1%lo0 login.facebook.com
  224. fe80::1%lo0 www.login.facebook.com
  225. fe80::1%lo0 fbcdn.net
  226. fe80::1%lo0 www.fbcdn.net
  227. fe80::1%lo0 fbcdn.com
  228. fe80::1%lo0 www.fbcdn.com
  229. fe80::1%lo0 static.ak.fbcdn.net
  230. fe80::1%lo0 static.ak.connect.facebook.com
  231. fe80::1%lo0 connect.facebook.net
  232. fe80::1%lo0 www.connect.facebook.net
  233. fe80::1%lo0 apps.facebook.com\n")
  234. (define dhcp-client-service-type
  235. (shepherd-service-type
  236. 'dhcp-client
  237. (lambda (dhcp)
  238. (define dhclient
  239. (file-append dhcp "/sbin/dhclient"))
  240. (define pid-file
  241. "/var/run/dhclient.pid")
  242. (shepherd-service
  243. (documentation "Set up networking via DHCP.")
  244. (requirement '(user-processes udev))
  245. ;; XXX: Running with '-nw' ("no wait") avoids blocking for a minute when
  246. ;; networking is unavailable, but also means that the interface is not up
  247. ;; yet when 'start' completes. To wait for the interface to be ready, one
  248. ;; should instead monitor udev events.
  249. (provision '(networking))
  250. (start #~(lambda _
  251. ;; When invoked without any arguments, 'dhclient' discovers all
  252. ;; non-loopback interfaces *that are up*. However, the relevant
  253. ;; interfaces are typically down at this point. Thus we perform
  254. ;; our own interface discovery here.
  255. (define valid?
  256. (lambda (interface)
  257. (and (arp-network-interface? interface)
  258. (not (loopback-network-interface? interface))
  259. ;; XXX: Make sure the interfaces are up so that
  260. ;; 'dhclient' can actually send/receive over them.
  261. ;; Ignore those that cannot be activated.
  262. (false-if-exception
  263. (set-network-interface-up interface)))))
  264. (define ifaces
  265. (filter valid? (all-network-interface-names)))
  266. (false-if-exception (delete-file #$pid-file))
  267. (let ((pid (fork+exec-command
  268. (cons* #$dhclient "-nw"
  269. "-pf" #$pid-file ifaces))))
  270. (and (zero? (cdr (waitpid pid)))
  271. (read-pid-file #$pid-file)))))
  272. (stop #~(make-kill-destructor))))
  273. isc-dhcp
  274. (description "Run @command{dhcp}, a Dynamic Host Configuration
  275. Protocol (DHCP) client, on all the non-loopback network interfaces.")))
  276. (define-record-type* <dhcpd-configuration>
  277. dhcpd-configuration make-dhcpd-configuration
  278. dhcpd-configuration?
  279. (package dhcpd-configuration-package ;file-like
  280. (default isc-dhcp))
  281. (config-file dhcpd-configuration-config-file ;file-like
  282. (default #f))
  283. (version dhcpd-configuration-version ;"4", "6", or "4o6"
  284. (default "4"))
  285. (run-directory dhcpd-configuration-run-directory
  286. (default "/run/dhcpd"))
  287. (lease-file dhcpd-configuration-lease-file
  288. (default "/var/db/dhcpd.leases"))
  289. (pid-file dhcpd-configuration-pid-file
  290. (default "/run/dhcpd/dhcpd.pid"))
  291. ;; list of strings, e.g. (list "enp0s25")
  292. (interfaces dhcpd-configuration-interfaces
  293. (default '())))
  294. (define dhcpd-shepherd-service
  295. (match-lambda
  296. (($ <dhcpd-configuration> package config-file version run-directory
  297. lease-file pid-file interfaces)
  298. (unless config-file
  299. (error "Must supply a config-file"))
  300. (list (shepherd-service
  301. ;; Allow users to easily run multiple versions simultaneously.
  302. (provision (list (string->symbol
  303. (string-append "dhcpv" version "-daemon"))))
  304. (documentation (string-append "Run the DHCPv" version " daemon"))
  305. (requirement '(networking))
  306. (start #~(make-forkexec-constructor
  307. '(#$(file-append package "/sbin/dhcpd")
  308. #$(string-append "-" version)
  309. "-lf" #$lease-file
  310. "-pf" #$pid-file
  311. "-cf" #$config-file
  312. #$@interfaces)
  313. #:pid-file #$pid-file))
  314. (stop #~(make-kill-destructor)))))))
  315. (define dhcpd-activation
  316. (match-lambda
  317. (($ <dhcpd-configuration> package config-file version run-directory
  318. lease-file pid-file interfaces)
  319. (with-imported-modules '((guix build utils))
  320. #~(begin
  321. (unless (file-exists? #$run-directory)
  322. (mkdir #$run-directory))
  323. ;; According to the DHCP manual (man dhcpd.leases), the lease
  324. ;; database must be present for dhcpd to start successfully.
  325. (unless (file-exists? #$lease-file)
  326. (with-output-to-file #$lease-file
  327. (lambda _ (display ""))))
  328. ;; Validate the config.
  329. (invoke/quiet
  330. #$(file-append package "/sbin/dhcpd")
  331. #$(string-append "-" version)
  332. "-t" "-cf" #$config-file))))))
  333. (define dhcpd-service-type
  334. (service-type
  335. (name 'dhcpd)
  336. (extensions
  337. (list (service-extension shepherd-root-service-type dhcpd-shepherd-service)
  338. (service-extension activation-service-type dhcpd-activation)))
  339. (description "Run a DHCP (Dynamic Host Configuration Protocol) daemon. The
  340. daemon is responsible for allocating IP addresses to its client.")))
  341. ;;;
  342. ;;; NTP.
  343. ;;;
  344. (define %ntp-log-rotation
  345. (list (log-rotation
  346. (files '("/var/log/ntpd.log")))))
  347. (define ntp-server-types (make-enumeration
  348. '(pool
  349. server
  350. peer
  351. broadcast
  352. manycastclient)))
  353. (define-record-type* <ntp-server>
  354. ntp-server make-ntp-server
  355. ntp-server?
  356. ;; The type can be one of the symbols of the NTP-SERVER-TYPE? enumeration.
  357. (type ntp-server-type
  358. (default 'server))
  359. (address ntp-server-address) ; a string
  360. ;; The list of options can contain single option names or tuples in the form
  361. ;; '(name value).
  362. (options ntp-server-options
  363. (default '())))
  364. (define (ntp-server->string ntp-server)
  365. ;; Serialize the NTP server object as a string, ready to use in the NTP
  366. ;; configuration file.
  367. (define (flatten lst)
  368. (reverse
  369. (let loop ((x lst)
  370. (res '()))
  371. (if (list? x)
  372. (fold loop res x)
  373. (cons (format #f "~a" x) res)))))
  374. (match ntp-server
  375. (($ <ntp-server> type address options)
  376. ;; XXX: It'd be neater if fields were validated at the syntax level (for
  377. ;; static ones at least). Perhaps the Guix record type could support a
  378. ;; predicate property on a field?
  379. (unless (enum-set-member? type ntp-server-types)
  380. (error "Invalid NTP server type" type))
  381. (string-join (cons* (symbol->string type)
  382. address
  383. (flatten options))))))
  384. (define %ntp-servers
  385. ;; Default set of NTP servers. These URLs are managed by the NTP Pool project.
  386. ;; Within Guix, Leo Famulari <leo@famulari.name> is the administrative contact
  387. ;; for this NTP pool "zone".
  388. ;; The full list of available URLs are 0.guix.pool.ntp.org,
  389. ;; 1.guix.pool.ntp.org, 2.guix.pool.ntp.org, and 3.guix.pool.ntp.org.
  390. (list
  391. (ntp-server
  392. (type 'pool)
  393. (address "0.guix.pool.ntp.org")
  394. (options '("iburst"))))) ;as recommended in the ntpd manual
  395. (define-record-type* <ntp-configuration>
  396. ntp-configuration make-ntp-configuration
  397. ntp-configuration?
  398. (ntp ntp-configuration-ntp
  399. (default ntp))
  400. (servers %ntp-configuration-servers ;list of <ntp-server> objects
  401. (default %ntp-servers))
  402. (allow-large-adjustment? ntp-allow-large-adjustment?
  403. (default #t))) ;as recommended in the ntpd manual
  404. (define (ntp-configuration-servers ntp-configuration)
  405. ;; A wrapper to support the deprecated form of this field.
  406. (let ((ntp-servers (%ntp-configuration-servers ntp-configuration)))
  407. (match ntp-servers
  408. (((? string?) (? string?) ...)
  409. (format (current-error-port) "warning: Defining NTP servers as strings is \
  410. deprecated. Please use <ntp-server> records instead.\n")
  411. (map (lambda (addr)
  412. (ntp-server
  413. (type 'server)
  414. (address addr)
  415. (options '()))) ntp-servers))
  416. ((($ <ntp-server>) ($ <ntp-server>) ...)
  417. ntp-servers))))
  418. (define ntp-shepherd-service
  419. (lambda (config)
  420. (match config
  421. (($ <ntp-configuration> ntp servers allow-large-adjustment?)
  422. (let ((servers (ntp-configuration-servers config)))
  423. ;; TODO: Add authentication support.
  424. (define config
  425. (string-append "driftfile /var/run/ntpd/ntp.drift\n"
  426. (string-join (map ntp-server->string servers)
  427. "\n")
  428. "
  429. # Disable status queries as a workaround for CVE-2013-5211:
  430. # <http://support.ntp.org/bin/view/Main/SecurityNotice#DRDoS_Amplification_Attack_using>.
  431. restrict default kod nomodify notrap nopeer noquery limited
  432. restrict -6 default kod nomodify notrap nopeer noquery limited
  433. # Yet, allow use of the local 'ntpq'.
  434. restrict 127.0.0.1
  435. restrict -6 ::1
  436. # This is required to use servers from a pool directive when using the 'nopeer'
  437. # option by default, as documented in the 'ntp.conf' manual.
  438. restrict source notrap nomodify noquery\n"))
  439. (define ntpd.conf
  440. (plain-file "ntpd.conf" config))
  441. (list (shepherd-service
  442. (provision '(ntpd))
  443. (documentation "Run the Network Time Protocol (NTP) daemon.")
  444. (requirement '(user-processes networking))
  445. (start #~(make-forkexec-constructor
  446. (list (string-append #$ntp "/bin/ntpd") "-n"
  447. "-c" #$ntpd.conf "-u" "ntpd"
  448. #$@(if allow-large-adjustment?
  449. '("-g")
  450. '()))
  451. #:log-file "/var/log/ntpd.log"))
  452. (stop #~(make-kill-destructor)))))))))
  453. (define %ntp-accounts
  454. (list (user-account
  455. (name "ntpd")
  456. (group "nogroup")
  457. (system? #t)
  458. (comment "NTP daemon user")
  459. (home-directory "/var/empty")
  460. (shell (file-append shadow "/sbin/nologin")))))
  461. (define (ntp-service-activation config)
  462. "Return the activation gexp for CONFIG."
  463. (with-imported-modules '((guix build utils))
  464. #~(begin
  465. (use-modules (guix build utils))
  466. (define %user
  467. (getpw "ntpd"))
  468. (let ((directory "/var/run/ntpd"))
  469. (mkdir-p directory)
  470. (chown directory (passwd:uid %user) (passwd:gid %user))))))
  471. (define ntp-service-type
  472. (service-type (name 'ntp)
  473. (extensions
  474. (list (service-extension shepherd-root-service-type
  475. ntp-shepherd-service)
  476. (service-extension account-service-type
  477. (const %ntp-accounts))
  478. (service-extension activation-service-type
  479. ntp-service-activation)
  480. (service-extension rottlog-service-type
  481. (const %ntp-log-rotation))))
  482. (description
  483. "Run the @command{ntpd}, the Network Time Protocol (NTP)
  484. daemon of the @uref{http://www.ntp.org, Network Time Foundation}. The daemon
  485. will keep the system clock synchronized with that of the given servers.")
  486. (default-value (ntp-configuration))))
  487. ;;;
  488. ;;; OpenNTPD.
  489. ;;;
  490. (define %openntpd-servers
  491. (map ntp-server-address %ntp-servers))
  492. (define-record-type* <openntpd-configuration>
  493. openntpd-configuration make-openntpd-configuration
  494. openntpd-configuration?
  495. (openntpd openntpd-configuration-openntpd
  496. (default openntpd))
  497. (listen-on openntpd-listen-on
  498. (default '("127.0.0.1"
  499. "::1")))
  500. (query-from openntpd-query-from
  501. (default '()))
  502. (sensor openntpd-sensor
  503. (default '()))
  504. (server openntpd-server
  505. (default '()))
  506. (servers openntpd-servers
  507. (default %openntpd-servers))
  508. (constraint-from openntpd-constraint-from
  509. (default '()))
  510. (constraints-from openntpd-constraints-from
  511. (default '())))
  512. (define (openntpd-configuration->string config)
  513. (define (quote-field? name)
  514. (member name '("constraints from")))
  515. (match-record config <openntpd-configuration>
  516. (listen-on query-from sensor server servers constraint-from
  517. constraints-from)
  518. (string-append
  519. (string-join
  520. (concatenate
  521. (filter-map (lambda (field values)
  522. (match values
  523. (() #f) ;discard entry with filter-map
  524. ((val ...) ;validate value type
  525. (map (lambda (value)
  526. (if (quote-field? field)
  527. (format #f "~a \"~a\"" field value)
  528. (format #f "~a ~a" field value)))
  529. values))))
  530. ;; The entry names.
  531. '("listen on" "query from" "sensor" "server" "servers"
  532. "constraint from" "constraints from")
  533. ;; The corresponding entry values.
  534. (list listen-on query-from sensor server servers
  535. constraint-from constraints-from)))
  536. "\n")
  537. "\n"))) ;add a trailing newline
  538. (define (openntpd-shepherd-service config)
  539. (let ((openntpd (openntpd-configuration-openntpd config)))
  540. (define ntpd.conf
  541. (plain-file "ntpd.conf" (openntpd-configuration->string config)))
  542. (list (shepherd-service
  543. (provision '(ntpd))
  544. (documentation "Run the Network Time Protocol (NTP) daemon.")
  545. (requirement '(user-processes networking))
  546. (start #~(make-forkexec-constructor
  547. (list (string-append #$openntpd "/sbin/ntpd")
  548. "-f" #$ntpd.conf
  549. "-d") ;; don't daemonize
  550. ;; When ntpd is daemonized it repeatedly tries to respawn
  551. ;; while running, leading shepherd to disable it. To
  552. ;; prevent spamming stderr, redirect output to logfile.
  553. #:log-file "/var/log/ntpd.log"))
  554. (stop #~(make-kill-destructor))))))
  555. (define (openntpd-service-activation config)
  556. "Return the activation gexp for CONFIG."
  557. (with-imported-modules '((guix build utils))
  558. #~(begin
  559. (use-modules (guix build utils))
  560. (mkdir-p "/var/db")
  561. (mkdir-p "/var/run")
  562. (unless (file-exists? "/var/db/ntpd.drift")
  563. (with-output-to-file "/var/db/ntpd.drift"
  564. (lambda _
  565. (format #t "0.0")))))))
  566. (define openntpd-service-type
  567. (service-type (name 'openntpd)
  568. (extensions
  569. (list (service-extension shepherd-root-service-type
  570. openntpd-shepherd-service)
  571. (service-extension account-service-type
  572. (const %ntp-accounts))
  573. (service-extension profile-service-type
  574. (compose list openntpd-configuration-openntpd))
  575. (service-extension activation-service-type
  576. openntpd-service-activation)
  577. (service-extension rottlog-service-type
  578. (const %ntp-log-rotation))))
  579. (default-value (openntpd-configuration))
  580. (description
  581. "Run the @command{ntpd}, the Network Time Protocol (NTP)
  582. daemon, as implemented by @uref{http://www.openntpd.org, OpenNTPD}. The
  583. daemon will keep the system clock synchronized with that of the given servers.")))
  584. ;;;
  585. ;;; Inetd.
  586. ;;;
  587. (define-record-type* <inetd-configuration> inetd-configuration
  588. make-inetd-configuration
  589. inetd-configuration?
  590. (program inetd-configuration-program ;file-like
  591. (default (file-append inetutils "/libexec/inetd")))
  592. (entries inetd-configuration-entries ;list of <inetd-entry>
  593. (default '())))
  594. (define-record-type* <inetd-entry> inetd-entry make-inetd-entry
  595. inetd-entry?
  596. (node inetd-entry-node ;string or #f
  597. (default #f))
  598. (name inetd-entry-name) ;string, from /etc/services
  599. (socket-type inetd-entry-socket-type) ;stream | dgram | raw |
  600. ;rdm | seqpacket
  601. (protocol inetd-entry-protocol) ;string, from /etc/protocols
  602. (wait? inetd-entry-wait? ;Boolean
  603. (default #t))
  604. (user inetd-entry-user) ;string
  605. (program inetd-entry-program ;string or file-like object
  606. (default "internal"))
  607. (arguments inetd-entry-arguments ;list of strings or file-like objects
  608. (default '())))
  609. (define (inetd-config-file entries)
  610. (apply mixed-text-file "inetd.conf"
  611. (map
  612. (lambda (entry)
  613. (let* ((node (inetd-entry-node entry))
  614. (name (inetd-entry-name entry))
  615. (socket
  616. (if node (string-append node ":" name) name))
  617. (type
  618. (match (inetd-entry-socket-type entry)
  619. ((or 'stream 'dgram 'raw 'rdm 'seqpacket)
  620. (symbol->string (inetd-entry-socket-type entry)))))
  621. (protocol (inetd-entry-protocol entry))
  622. (wait (if (inetd-entry-wait? entry) "wait" "nowait"))
  623. (user (inetd-entry-user entry))
  624. (program (inetd-entry-program entry))
  625. (args (inetd-entry-arguments entry)))
  626. #~(string-append
  627. (string-join
  628. (list #$@(list socket type protocol wait user program) #$@args)
  629. " ") "\n")))
  630. entries)))
  631. (define inetd-shepherd-service
  632. (match-lambda
  633. (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing
  634. (($ <inetd-configuration> program entries)
  635. (list
  636. (shepherd-service
  637. (documentation "Run inetd.")
  638. (provision '(inetd))
  639. (requirement '(user-processes networking syslogd))
  640. (start #~(make-forkexec-constructor
  641. (list #$program #$(inetd-config-file entries))
  642. #:pid-file "/var/run/inetd.pid"))
  643. (stop #~(make-kill-destructor)))))))
  644. (define-public inetd-service-type
  645. (service-type
  646. (name 'inetd)
  647. (extensions
  648. (list (service-extension shepherd-root-service-type
  649. inetd-shepherd-service)))
  650. ;; The service can be extended with additional lists of entries.
  651. (compose concatenate)
  652. (extend (lambda (config entries)
  653. (inetd-configuration
  654. (inherit config)
  655. (entries (append (inetd-configuration-entries config)
  656. entries)))))
  657. (description
  658. "Start @command{inetd}, the @dfn{Internet superserver}. It is responsible
  659. for listening on Internet sockets and spawning the corresponding services on
  660. demand.")))
  661. ;;;
  662. ;;; OpenDHT, the distributed hash table network used by Jami
  663. ;;;
  664. (define-maybe/no-serialization number)
  665. (define-maybe/no-serialization string)
  666. ;;; To generate the documentation of the following configuration record, you
  667. ;;; can evaluate: (configuration->documentation 'opendht-configuration)
  668. (define-configuration/no-serialization opendht-configuration
  669. (opendht
  670. (file-like opendht)
  671. "The @code{opendht} package to use.")
  672. (peer-discovery?
  673. (boolean #false)
  674. "Whether to enable the multicast local peer discovery mechanism.")
  675. (enable-logging?
  676. (boolean #false)
  677. "Whether to enable logging messages to syslog. It is disabled by default
  678. as it is rather verbose.")
  679. (debug?
  680. (boolean #false)
  681. "Whether to enable debug-level logging messages. This has no effect if
  682. logging is disabled.")
  683. (bootstrap-host
  684. (maybe-string "bootstrap.jami.net:4222")
  685. "The node host name that is used to make the first connection to the
  686. network. A specific port value can be provided by appending the @code{:PORT}
  687. suffix. By default, it uses the Jami bootstrap nodes, but any host can be
  688. specified here. It's also possible to disable bootstrapping by explicitly
  689. setting this field to @code{%unset-value}.")
  690. (port
  691. (maybe-number 4222)
  692. "The UDP port to bind to. When left unspecified, an available port is
  693. automatically selected.")
  694. (proxy-server-port
  695. maybe-number
  696. "Spawn a proxy server listening on the specified port.")
  697. (proxy-server-port-tls
  698. maybe-number
  699. "Spawn a proxy server listening to TLS connections on the specified
  700. port."))
  701. (define %opendht-accounts
  702. ;; User account and groups for Tor.
  703. (list (user-group (name "opendht") (system? #t))
  704. (user-account
  705. (name "opendht")
  706. (group "opendht")
  707. (system? #t)
  708. (comment "OpenDHT daemon user")
  709. (home-directory "/var/empty")
  710. (shell (file-append shadow "/sbin/nologin")))))
  711. (define (opendht-configuration->command-line-arguments config)
  712. "Derive the command line arguments used to launch the OpenDHT daemon from
  713. CONFIG, an <opendht-configuration> object."
  714. (match-record config <opendht-configuration>
  715. (opendht bootstrap-host enable-logging? port debug? peer-discovery?
  716. proxy-server-port proxy-server-port-tls)
  717. (let ((dhtnode (least-authority-wrapper
  718. ;; XXX: Work around lack of support for multiple outputs
  719. ;; in 'file-append'.
  720. (computed-file "dhtnode"
  721. #~(symlink
  722. (string-append #$opendht:tools
  723. "/bin/dhtnode")
  724. #$output))
  725. #:name "dhtnode"
  726. #:mappings (list (file-system-mapping
  727. (source "/dev/log") ;for syslog
  728. (target source)))
  729. #:namespaces (delq 'net %namespaces))))
  730. `(,dhtnode
  731. "--service" ;non-forking mode
  732. ,@(if (string? bootstrap-host)
  733. (list "--bootstrap" bootstrap-host))
  734. ,@(if enable-logging?
  735. (list "--syslog")
  736. '())
  737. ,@(if (number? port)
  738. (list "--port" (number->string port))
  739. '())
  740. ,@(if debug?
  741. (list "--verbose")
  742. '())
  743. ,@(if peer-discovery?
  744. (list "--peer-discovery")
  745. '())
  746. ,@(if (number? proxy-server-port)
  747. (list "--proxyserver" (number->string proxy-server-port))
  748. '())
  749. ,@(if (number? proxy-server-port-tls)
  750. (list "--proxyserverssl" (number->string proxy-server-port-tls))
  751. '())))))
  752. (define (opendht-shepherd-service config)
  753. "Return a <shepherd-service> running OpenDHT."
  754. (shepherd-service
  755. (documentation "Run an OpenDHT node.")
  756. (provision '(opendht dhtnode dhtproxy))
  757. (requirement '(networking syslogd))
  758. (start #~(make-forkexec-constructor
  759. (list #$@(opendht-configuration->command-line-arguments config))
  760. #:user "opendht"
  761. #:group "opendht"))
  762. (stop #~(make-kill-destructor))))
  763. (define opendht-service-type
  764. (service-type
  765. (name 'opendht)
  766. (default-value (opendht-configuration))
  767. (extensions
  768. (list (service-extension shepherd-root-service-type
  769. (compose list opendht-shepherd-service))
  770. (service-extension account-service-type
  771. (const %opendht-accounts))))
  772. (description "Run the OpenDHT @command{dhtnode} command that allows
  773. participating in the distributed hash table based OpenDHT network. The
  774. service can be configured to act as a proxy to the distributed network, which
  775. can be useful for portable devices where minimizing energy consumption is
  776. paramount. OpenDHT was originally based on Kademlia and adapted for
  777. applications in communication. It is used by Jami, for example.")))
  778. ;;;
  779. ;;; Tor.
  780. ;;;
  781. (define-record-type* <tor-configuration>
  782. tor-configuration make-tor-configuration
  783. tor-configuration?
  784. (tor tor-configuration-tor
  785. (default tor))
  786. (config-file tor-configuration-config-file
  787. (default (plain-file "empty" "")))
  788. (hidden-services tor-configuration-hidden-services
  789. (default '()))
  790. (socks-socket-type tor-configuration-socks-socket-type ; 'tcp or 'unix
  791. (default 'tcp))
  792. (control-socket? tor-control-socket-path
  793. (default #f)))
  794. (define %tor-accounts
  795. ;; User account and groups for Tor.
  796. (list (user-group (name "tor") (system? #t))
  797. (user-account
  798. (name "tor")
  799. (group "tor")
  800. (system? #t)
  801. (comment "Tor daemon user")
  802. (home-directory "/var/empty")
  803. (shell (file-append shadow "/sbin/nologin")))))
  804. (define-record-type <hidden-service>
  805. (hidden-service name mapping)
  806. hidden-service?
  807. (name hidden-service-name) ;string
  808. (mapping hidden-service-mapping)) ;list of port/address tuples
  809. (define (tor-configuration->torrc config)
  810. "Return a 'torrc' file for CONFIG."
  811. (match config
  812. (($ <tor-configuration> tor config-file services
  813. socks-socket-type control-socket?)
  814. (computed-file
  815. "torrc"
  816. (with-imported-modules '((guix build utils))
  817. #~(begin
  818. (use-modules (guix build utils)
  819. (ice-9 match))
  820. (call-with-output-file #$output
  821. (lambda (port)
  822. (display "\
  823. ### These lines were generated from your system configuration:
  824. DataDirectory /var/lib/tor
  825. Log notice syslog\n" port)
  826. (when (eq? 'unix '#$socks-socket-type)
  827. (display "\
  828. SocksPort unix:/var/run/tor/socks-sock
  829. UnixSocksGroupWritable 1\n" port))
  830. (when #$control-socket?
  831. (display "\
  832. ControlSocket unix:/var/run/tor/control-sock GroupWritable RelaxDirModeCheck
  833. ControlSocketsGroupWritable 1\n"
  834. port))
  835. (for-each (match-lambda
  836. ((service (ports hosts) ...)
  837. (format port "\
  838. HiddenServiceDir /var/lib/tor/hidden-services/~a~%"
  839. service)
  840. (for-each (lambda (tcp-port host)
  841. (format port "\
  842. HiddenServicePort ~a ~a~%"
  843. tcp-port host))
  844. ports hosts)))
  845. '#$(map (match-lambda
  846. (($ <hidden-service> name mapping)
  847. (cons name mapping)))
  848. services))
  849. (display "\
  850. ### End of automatically generated lines.\n\n" port)
  851. ;; Append the user's config file.
  852. (call-with-input-file #$config-file
  853. (lambda (input)
  854. (dump-port input port)))
  855. #t))))))))
  856. (define (tor-shepherd-service config)
  857. "Return a <shepherd-service> running Tor."
  858. (match config
  859. (($ <tor-configuration> tor)
  860. (let* ((torrc (tor-configuration->torrc config))
  861. (tor (least-authority-wrapper
  862. (file-append tor "/bin/tor")
  863. #:name "tor"
  864. #:mappings (list (file-system-mapping
  865. (source "/var/lib/tor")
  866. (target source)
  867. (writable? #t))
  868. (file-system-mapping
  869. (source "/dev/log") ;for syslog
  870. (target source))
  871. (file-system-mapping
  872. (source "/var/run/tor")
  873. (target source)
  874. (writable? #t))
  875. (file-system-mapping
  876. (source torrc)
  877. (target source)))
  878. #:namespaces (delq 'net %namespaces))))
  879. (with-imported-modules (source-module-closure
  880. '((gnu build shepherd)
  881. (gnu system file-systems)))
  882. (list (shepherd-service
  883. (provision '(tor))
  884. ;; Tor needs at least one network interface to be up, hence the
  885. ;; dependency on 'loopback'.
  886. (requirement '(user-processes loopback syslogd))
  887. (modules '((gnu build shepherd)
  888. (gnu system file-systems)))
  889. ;; XXX: #:pid-file won't work because the wrapped 'tor'
  890. ;; program would print its PID within the user namespace
  891. ;; instead of its actual PID outside. There's no inetd or
  892. ;; systemd socket activation support either (there's
  893. ;; 'sd_notify' though), so we're stuck with that.
  894. (start #~(make-forkexec-constructor
  895. (list #$tor "-f" #$torrc)
  896. #:user "tor" #:group "tor"))
  897. (stop #~(make-kill-destructor))
  898. (documentation "Run the Tor anonymous network overlay."))))))))
  899. (define (tor-activation config)
  900. "Set up directories for Tor and its hidden services, if any."
  901. #~(begin
  902. (use-modules (guix build utils))
  903. (define %user
  904. (getpw "tor"))
  905. (define (initialize service)
  906. (let ((directory (string-append "/var/lib/tor/hidden-services/"
  907. service)))
  908. (mkdir-p directory)
  909. (chown directory (passwd:uid %user) (passwd:gid %user))
  910. ;; The daemon bails out if we give wider permissions.
  911. (chmod directory #o700)))
  912. ;; Allow Tor to write its PID file.
  913. (mkdir-p "/var/run/tor")
  914. (chown "/var/run/tor" (passwd:uid %user) (passwd:gid %user))
  915. ;; Set the group permissions to rw so that if the system administrator
  916. ;; has specified UnixSocksGroupWritable=1 in their torrc file, members
  917. ;; of the "tor" group will be able to use the SOCKS socket.
  918. (chmod "/var/run/tor" #o750)
  919. ;; Allow Tor to access the hidden services' directories.
  920. (mkdir-p "/var/lib/tor")
  921. (chown "/var/lib/tor" (passwd:uid %user) (passwd:gid %user))
  922. (chmod "/var/lib/tor" #o700)
  923. ;; Make sure /var/lib is accessible to the 'tor' user.
  924. (chmod "/var/lib" #o755)
  925. (for-each initialize
  926. '#$(map hidden-service-name
  927. (tor-configuration-hidden-services config)))))
  928. (define tor-service-type
  929. (service-type (name 'tor)
  930. (extensions
  931. (list (service-extension shepherd-root-service-type
  932. tor-shepherd-service)
  933. (service-extension account-service-type
  934. (const %tor-accounts))
  935. (service-extension activation-service-type
  936. tor-activation)))
  937. ;; This can be extended with hidden services.
  938. (compose concatenate)
  939. (extend (lambda (config services)
  940. (tor-configuration
  941. (inherit config)
  942. (hidden-services
  943. (append (tor-configuration-hidden-services config)
  944. services)))))
  945. (default-value (tor-configuration))
  946. (description
  947. "Run the @uref{https://torproject.org, Tor} anonymous
  948. networking daemon.")))
  949. (define tor-hidden-service-type
  950. ;; A type that extends Tor with hidden services.
  951. (service-type (name 'tor-hidden-service)
  952. (extensions
  953. (list (service-extension tor-service-type list)))
  954. (description
  955. "Define a new Tor @dfn{hidden service}.")))
  956. (define (tor-hidden-service name mapping)
  957. "Define a new Tor @dfn{hidden service} called @var{name} and implementing
  958. @var{mapping}. @var{mapping} is a list of port/host tuples, such as:
  959. @example
  960. '((22 \"127.0.0.1:22\")
  961. (80 \"127.0.0.1:8080\"))
  962. @end example
  963. In this example, port 22 of the hidden service is mapped to local port 22, and
  964. port 80 is mapped to local port 8080.
  965. This creates a @file{/var/lib/tor/hidden-services/@var{name}} directory, where
  966. the @file{hostname} file contains the @code{.onion} host name for the hidden
  967. service.
  968. See @uref{https://www.torproject.org/docs/tor-hidden-service.html.en, the Tor
  969. project's documentation} for more information."
  970. (service tor-hidden-service-type
  971. (hidden-service name mapping)))
  972. ;;;
  973. ;;; ModemManager
  974. ;;;
  975. (define-record-type* <modem-manager-configuration>
  976. modem-manager-configuration make-modem-manager-configuration
  977. modem-manager-configuration?
  978. (modem-manager modem-manager-configuration-modem-manager
  979. (default modem-manager)))
  980. ;;;
  981. ;;; NetworkManager
  982. ;;;
  983. (define-record-type* <network-manager-configuration>
  984. network-manager-configuration make-network-manager-configuration
  985. network-manager-configuration?
  986. (network-manager network-manager-configuration-network-manager
  987. (default network-manager))
  988. (dns network-manager-configuration-dns
  989. (default "default"))
  990. (vpn-plugins network-manager-configuration-vpn-plugins ;list of file-like
  991. (default '())))
  992. (define network-manager-activation
  993. ;; Activation gexp for NetworkManager
  994. (match-lambda
  995. (($ <network-manager-configuration> network-manager dns vpn-plugins)
  996. #~(begin
  997. (use-modules (guix build utils))
  998. (mkdir-p "/etc/NetworkManager/system-connections")
  999. #$@(if (equal? dns "dnsmasq")
  1000. ;; create directory to store dnsmasq lease file
  1001. '((mkdir-p "/var/lib/misc"))
  1002. '())))))
  1003. (define (vpn-plugin-directory plugins)
  1004. "Return a directory containing PLUGINS, the NM VPN plugins."
  1005. (directory-union "network-manager-vpn-plugins" plugins))
  1006. (define (network-manager-accounts config)
  1007. "Return the list of <user-account> and <user-group> for CONFIG."
  1008. (define nologin
  1009. (file-append shadow "/sbin/nologin"))
  1010. (define accounts
  1011. (append-map (lambda (package)
  1012. (map (lambda (name)
  1013. (user-account (system? #t)
  1014. (name name)
  1015. (group "network-manager")
  1016. (comment "NetworkManager helper")
  1017. (home-directory "/var/empty")
  1018. (create-home-directory? #f)
  1019. (shell nologin)))
  1020. (or (assoc-ref (package-properties package)
  1021. 'user-accounts)
  1022. '())))
  1023. (network-manager-configuration-vpn-plugins config)))
  1024. (match accounts
  1025. (()
  1026. '())
  1027. (_
  1028. (cons (user-group (name "network-manager") (system? #t))
  1029. accounts))))
  1030. (define network-manager-environment
  1031. (match-lambda
  1032. (($ <network-manager-configuration> network-manager dns vpn-plugins)
  1033. ;; Define this variable in the global environment such that
  1034. ;; "nmcli connection import type openvpn file foo.ovpn" works.
  1035. `(("NM_VPN_PLUGIN_DIR"
  1036. . ,(file-append (vpn-plugin-directory vpn-plugins)
  1037. "/lib/NetworkManager/VPN"))))))
  1038. (define network-manager-shepherd-service
  1039. (match-lambda
  1040. (($ <network-manager-configuration> network-manager dns vpn-plugins)
  1041. (let ((conf (plain-file "NetworkManager.conf"
  1042. (string-append "[main]\ndns=" dns "\n")))
  1043. (vpn (vpn-plugin-directory vpn-plugins)))
  1044. (list (shepherd-service
  1045. (documentation "Run the NetworkManager.")
  1046. (provision '(networking))
  1047. (requirement '(user-processes dbus-system wpa-supplicant loopback))
  1048. (start #~(make-forkexec-constructor
  1049. (list (string-append #$network-manager
  1050. "/sbin/NetworkManager")
  1051. (string-append "--config=" #$conf)
  1052. "--no-daemon")
  1053. #:environment-variables
  1054. (list (string-append "NM_VPN_PLUGIN_DIR=" #$vpn
  1055. "/lib/NetworkManager/VPN")
  1056. ;; Override non-existent default users
  1057. "NM_OPENVPN_USER="
  1058. "NM_OPENVPN_GROUP=")))
  1059. (stop #~(make-kill-destructor))))))))
  1060. (define network-manager-service-type
  1061. (let
  1062. ((config->packages
  1063. (match-lambda
  1064. (($ <network-manager-configuration> network-manager _ vpn-plugins)
  1065. `(,network-manager ,@vpn-plugins)))))
  1066. (service-type
  1067. (name 'network-manager)
  1068. (extensions
  1069. (list (service-extension shepherd-root-service-type
  1070. network-manager-shepherd-service)
  1071. (service-extension dbus-root-service-type config->packages)
  1072. (service-extension polkit-service-type
  1073. (compose
  1074. list
  1075. network-manager-configuration-network-manager))
  1076. (service-extension account-service-type
  1077. network-manager-accounts)
  1078. (service-extension activation-service-type
  1079. network-manager-activation)
  1080. (service-extension session-environment-service-type
  1081. network-manager-environment)
  1082. ;; Add network-manager to the system profile.
  1083. (service-extension profile-service-type config->packages)))
  1084. (default-value (network-manager-configuration))
  1085. (description
  1086. "Run @uref{https://wiki.gnome.org/Projects/NetworkManager,
  1087. NetworkManager}, a network management daemon that aims to simplify wired and
  1088. wireless networking."))))
  1089. ;;;
  1090. ;;; Connman
  1091. ;;;
  1092. (define-record-type* <connman-configuration>
  1093. connman-configuration make-connman-configuration
  1094. connman-configuration?
  1095. (connman connman-configuration-connman
  1096. (default connman))
  1097. (disable-vpn? connman-configuration-disable-vpn?
  1098. (default #f)))
  1099. (define (connman-activation config)
  1100. (let ((disable-vpn? (connman-configuration-disable-vpn? config)))
  1101. (with-imported-modules '((guix build utils))
  1102. #~(begin
  1103. (use-modules (guix build utils))
  1104. (mkdir-p "/var/lib/connman/")
  1105. (unless #$disable-vpn?
  1106. (mkdir-p "/var/lib/connman-vpn/"))))))
  1107. (define (connman-shepherd-service config)
  1108. "Return a shepherd service for Connman"
  1109. (and
  1110. (connman-configuration? config)
  1111. (let ((connman (connman-configuration-connman config))
  1112. (disable-vpn? (connman-configuration-disable-vpn? config)))
  1113. (list (shepherd-service
  1114. (documentation "Run Connman")
  1115. (provision '(networking))
  1116. (requirement
  1117. '(user-processes dbus-system loopback wpa-supplicant))
  1118. (start #~(make-forkexec-constructor
  1119. (list (string-append #$connman
  1120. "/sbin/connmand")
  1121. "--nodaemon"
  1122. "--nodnsproxy"
  1123. #$@(if disable-vpn? '("--noplugin=vpn") '()))
  1124. ;; As connman(8) notes, when passing '-n', connman
  1125. ;; "directs log output to the controlling terminal in
  1126. ;; addition to syslog." Redirect stdout and stderr
  1127. ;; to avoid spamming the console (XXX: for some reason
  1128. ;; redirecting to /dev/null doesn't work.)
  1129. #:log-file "/var/log/connman.log"))
  1130. (stop #~(make-kill-destructor)))))))
  1131. (define %connman-log-rotation
  1132. (list (log-rotation
  1133. (files '("/var/log/connman.log")))))
  1134. (define connman-service-type
  1135. (let ((connman-package (compose list connman-configuration-connman)))
  1136. (service-type (name 'connman)
  1137. (extensions
  1138. (list (service-extension shepherd-root-service-type
  1139. connman-shepherd-service)
  1140. (service-extension polkit-service-type
  1141. connman-package)
  1142. (service-extension dbus-root-service-type
  1143. connman-package)
  1144. (service-extension activation-service-type
  1145. connman-activation)
  1146. ;; Add connman to the system profile.
  1147. (service-extension profile-service-type
  1148. connman-package)
  1149. (service-extension rottlog-service-type
  1150. (const %connman-log-rotation))))
  1151. (default-value (connman-configuration))
  1152. (description
  1153. "Run @url{https://01.org/connman,Connman},
  1154. a network connection manager."))))
  1155. ;;;
  1156. ;;; Modem manager
  1157. ;;;
  1158. (define modem-manager-service-type
  1159. (let ((config->package
  1160. (match-lambda
  1161. (($ <modem-manager-configuration> modem-manager)
  1162. (list modem-manager)))))
  1163. (service-type (name 'modem-manager)
  1164. (extensions
  1165. (list (service-extension dbus-root-service-type
  1166. config->package)
  1167. (service-extension udev-service-type
  1168. config->package)
  1169. (service-extension polkit-service-type
  1170. config->package)))
  1171. (default-value (modem-manager-configuration))
  1172. (description
  1173. "Run @uref{https://wiki.gnome.org/Projects/ModemManager,
  1174. ModemManager}, a modem management daemon that aims to simplify dialup
  1175. networking."))))
  1176. ;;;
  1177. ;;; USB_ModeSwitch
  1178. ;;;
  1179. (define-record-type* <usb-modeswitch-configuration>
  1180. usb-modeswitch-configuration make-usb-modeswitch-configuration
  1181. usb-modeswitch-configuration?
  1182. (usb-modeswitch usb-modeswitch-configuration-usb-modeswitch
  1183. (default usb-modeswitch))
  1184. (usb-modeswitch-data usb-modeswitch-configuration-usb-modeswitch-data
  1185. (default usb-modeswitch-data))
  1186. (config-file usb-modeswitch-configuration-config-file
  1187. (default #~(string-append #$usb-modeswitch:dispatcher
  1188. "/etc/usb_modeswitch.conf"))))
  1189. (define (usb-modeswitch-sh usb-modeswitch config-file)
  1190. "Build a copy of usb_modeswitch.sh located in package USB-MODESWITCH,
  1191. modified to pass the CONFIG-FILE in its calls to usb_modeswitch_dispatcher,
  1192. and wrap it to actually find the dispatcher in USB-MODESWITCH. The script
  1193. will be run by USB_ModeSwitch’s udev rules file when a modeswitchable USB
  1194. device is detected."
  1195. (computed-file
  1196. "usb_modeswitch-sh"
  1197. (with-imported-modules '((guix build utils))
  1198. #~(begin
  1199. (use-modules (guix build utils))
  1200. (let ((cfg-param
  1201. #$(if config-file
  1202. #~(string-append " --config-file=" #$config-file)
  1203. "")))
  1204. (mkdir #$output)
  1205. (install-file (string-append #$usb-modeswitch:dispatcher
  1206. "/lib/udev/usb_modeswitch")
  1207. #$output)
  1208. ;; insert CFG-PARAM into usb_modeswitch_dispatcher command-lines
  1209. (substitute* (string-append #$output "/usb_modeswitch")
  1210. (("(exec usb_modeswitch_dispatcher .*)( 2>>)" _ left right)
  1211. (string-append left cfg-param right))
  1212. (("(exec usb_modeswitch_dispatcher .*)( &)" _ left right)
  1213. (string-append left cfg-param right)))
  1214. ;; wrap-program needs bash in PATH:
  1215. (putenv (string-append "PATH=" #$bash "/bin"))
  1216. (wrap-program (string-append #$output "/usb_modeswitch")
  1217. `("PATH" ":" = (,(string-append #$coreutils "/bin")
  1218. ,(string-append
  1219. #$usb-modeswitch:dispatcher
  1220. "/bin")))))))))
  1221. (define (usb-modeswitch-configuration->udev-rules config)
  1222. "Build a rules file for extending udev-service-type from the rules in the
  1223. usb-modeswitch package specified in CONFIG. The rules file will invoke
  1224. usb_modeswitch.sh from the usb-modeswitch package, modified to pass the right
  1225. config file."
  1226. (match config
  1227. (($ <usb-modeswitch-configuration> usb-modeswitch data config-file)
  1228. (computed-file
  1229. "usb_modeswitch.rules"
  1230. (with-imported-modules '((guix build utils))
  1231. #~(begin
  1232. (use-modules (guix build utils))
  1233. (let ((in (string-append #$data "/udev/40-usb_modeswitch.rules"))
  1234. (out (string-append #$output "/lib/udev/rules.d"))
  1235. (script #$(usb-modeswitch-sh usb-modeswitch config-file)))
  1236. (mkdir-p out)
  1237. (chdir out)
  1238. (install-file in out)
  1239. (substitute* "40-usb_modeswitch.rules"
  1240. (("PROGRAM=\"usb_modeswitch")
  1241. (string-append "PROGRAM=\"" script "/usb_modeswitch"))
  1242. (("RUN\\+=\"usb_modeswitch")
  1243. (string-append "RUN+=\"" script "/usb_modeswitch"))))))))))
  1244. (define usb-modeswitch-service-type
  1245. (service-type
  1246. (name 'usb-modeswitch)
  1247. (extensions
  1248. (list
  1249. (service-extension
  1250. udev-service-type
  1251. (lambda (config)
  1252. (let ((rules (usb-modeswitch-configuration->udev-rules config)))
  1253. (list rules))))))
  1254. (default-value (usb-modeswitch-configuration))
  1255. (description "Run @uref{http://www.draisberghof.de/usb_modeswitch/,
  1256. USB_ModeSwitch}, a mode switching tool for controlling USB devices with
  1257. multiple @dfn{modes}. When plugged in for the first time many USB
  1258. devices (primarily high-speed WAN modems) act like a flash storage containing
  1259. installers for Windows drivers. USB_ModeSwitch replays the sequence the
  1260. Windows drivers would send to switch their mode from storage to modem (or
  1261. whatever the thing is supposed to do).")))
  1262. ;;;
  1263. ;;; WPA supplicant
  1264. ;;;
  1265. (define-record-type* <wpa-supplicant-configuration>
  1266. wpa-supplicant-configuration make-wpa-supplicant-configuration
  1267. wpa-supplicant-configuration?
  1268. (wpa-supplicant wpa-supplicant-configuration-wpa-supplicant ;file-like
  1269. (default wpa-supplicant))
  1270. (requirement wpa-supplicant-configuration-requirement ;list of symbols
  1271. (default '(user-processes loopback syslogd)))
  1272. (pid-file wpa-supplicant-configuration-pid-file ;string
  1273. (default "/var/run/wpa_supplicant.pid"))
  1274. (dbus? wpa-supplicant-configuration-dbus? ;Boolean
  1275. (default #t))
  1276. (interface wpa-supplicant-configuration-interface ;#f | string
  1277. (default #f))
  1278. (config-file wpa-supplicant-configuration-config-file ;#f | <file-like>
  1279. (default #f))
  1280. (extra-options wpa-supplicant-configuration-extra-options ;list of strings
  1281. (default '())))
  1282. (define wpa-supplicant-shepherd-service
  1283. (match-lambda
  1284. (($ <wpa-supplicant-configuration> wpa-supplicant requirement pid-file dbus?
  1285. interface config-file extra-options)
  1286. (list (shepherd-service
  1287. (documentation "Run the WPA supplicant daemon")
  1288. (provision '(wpa-supplicant))
  1289. (requirement (if dbus?
  1290. (cons 'dbus-system requirement)
  1291. requirement))
  1292. (start #~(make-forkexec-constructor
  1293. (list (string-append #$wpa-supplicant
  1294. "/sbin/wpa_supplicant")
  1295. (string-append "-P" #$pid-file)
  1296. "-B" ;run in background
  1297. "-s" ;log to syslogd
  1298. #$@(if dbus?
  1299. #~("-u")
  1300. #~())
  1301. #$@(if interface
  1302. #~((string-append "-i" #$interface))
  1303. #~())
  1304. #$@(if config-file
  1305. #~((string-append "-c" #$config-file))
  1306. #~())
  1307. #$@extra-options)
  1308. #:pid-file #$pid-file))
  1309. (stop #~(make-kill-destructor)))))))
  1310. (define wpa-supplicant-service-type
  1311. (let ((config->package
  1312. (match-lambda
  1313. (($ <wpa-supplicant-configuration> wpa-supplicant)
  1314. (list wpa-supplicant)))))
  1315. (service-type (name 'wpa-supplicant)
  1316. (extensions
  1317. (list (service-extension shepherd-root-service-type
  1318. wpa-supplicant-shepherd-service)
  1319. (service-extension dbus-root-service-type config->package)
  1320. (service-extension profile-service-type config->package)))
  1321. (description "Run the WPA Supplicant daemon, a service that
  1322. implements authentication, key negotiation and more for wireless networks.")
  1323. (default-value (wpa-supplicant-configuration)))))
  1324. ;;;
  1325. ;;; Hostapd.
  1326. ;;;
  1327. (define-record-type* <hostapd-configuration>
  1328. hostapd-configuration make-hostapd-configuration
  1329. hostapd-configuration?
  1330. (package hostapd-configuration-package
  1331. (default hostapd))
  1332. (interface hostapd-configuration-interface ;string
  1333. (default "wlan0"))
  1334. (ssid hostapd-configuration-ssid) ;string
  1335. (broadcast-ssid? hostapd-configuration-broadcast-ssid? ;Boolean
  1336. (default #t))
  1337. (channel hostapd-configuration-channel ;integer
  1338. (default 1))
  1339. (driver hostapd-configuration-driver ;string
  1340. (default "nl80211"))
  1341. ;; See <https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf> for a list of
  1342. ;; additional options we could add.
  1343. (extra-settings hostapd-configuration-extra-settings ;string
  1344. (default "")))
  1345. (define (hostapd-configuration-file config)
  1346. "Return the configuration file for CONFIG, a <hostapd-configuration>."
  1347. (match-record config <hostapd-configuration>
  1348. (interface ssid broadcast-ssid? channel driver extra-settings)
  1349. (plain-file "hostapd.conf"
  1350. (string-append "\
  1351. # Generated from your Guix configuration.
  1352. interface=" interface "
  1353. ssid=" ssid "
  1354. ignore_broadcast_ssid=" (if broadcast-ssid? "0" "1") "
  1355. channel=" (number->string channel) "\n"
  1356. extra-settings "\n"))))
  1357. (define* (hostapd-shepherd-services config #:key (requirement '()))
  1358. "Return Shepherd services for hostapd."
  1359. (list (shepherd-service
  1360. (provision '(hostapd))
  1361. (requirement `(user-processes ,@requirement))
  1362. (documentation "Run the hostapd WiFi access point daemon.")
  1363. (start #~(make-forkexec-constructor
  1364. (list #$(file-append (hostapd-configuration-package config)
  1365. "/sbin/hostapd")
  1366. #$(hostapd-configuration-file config))
  1367. #:log-file "/var/log/hostapd.log"))
  1368. (stop #~(make-kill-destructor)))))
  1369. (define %hostapd-log-rotation
  1370. (list (log-rotation
  1371. (files '("/var/log/hostapd.log")))))
  1372. (define hostapd-service-type
  1373. (service-type
  1374. (name 'hostapd)
  1375. (extensions
  1376. (list (service-extension shepherd-root-service-type
  1377. hostapd-shepherd-services)
  1378. (service-extension rottlog-service-type
  1379. (const %hostapd-log-rotation))))
  1380. (description
  1381. "Run the @uref{https://w1.fi/hostapd/, hostapd} daemon for Wi-Fi access
  1382. points and authentication servers.")))
  1383. (define (simulated-wifi-shepherd-services config)
  1384. "Return Shepherd services to run hostapd with CONFIG, a
  1385. <hostapd-configuration>, as well as services to set up WiFi hardware
  1386. simulation."
  1387. (append (hostapd-shepherd-services config
  1388. #:requirement
  1389. '(unblocked-wifi
  1390. kernel-module-loader))
  1391. (list (shepherd-service
  1392. (provision '(unblocked-wifi))
  1393. (requirement '(file-systems kernel-module-loader))
  1394. (documentation
  1395. "Unblock WiFi devices for use by mac80211_hwsim.")
  1396. (start #~(lambda _
  1397. (invoke #$(file-append util-linux "/sbin/rfkill")
  1398. "unblock" "0")
  1399. (invoke #$(file-append util-linux "/sbin/rfkill")
  1400. "unblock" "1")))
  1401. (one-shot? #t)))))
  1402. (define simulated-wifi-service-type
  1403. (service-type
  1404. (name 'simulated-wifi)
  1405. (extensions
  1406. (list (service-extension shepherd-root-service-type
  1407. simulated-wifi-shepherd-services)
  1408. (service-extension kernel-module-loader-service-type
  1409. (const '("mac80211_hwsim")))))
  1410. (default-value (hostapd-configuration
  1411. (interface "wlan1")
  1412. (ssid "Test Network")))
  1413. (description "Run hostapd to simulate WiFi connectivity.")))
  1414. ;;;
  1415. ;;; Open vSwitch
  1416. ;;;
  1417. (define-record-type* <openvswitch-configuration>
  1418. openvswitch-configuration make-openvswitch-configuration
  1419. openvswitch-configuration?
  1420. (package openvswitch-configuration-package
  1421. (default openvswitch)))
  1422. (define openvswitch-activation
  1423. (match-lambda
  1424. (($ <openvswitch-configuration> package)
  1425. (let ((ovsdb-tool (file-append package "/bin/ovsdb-tool")))
  1426. (with-imported-modules '((guix build utils))
  1427. #~(begin
  1428. (use-modules (guix build utils))
  1429. (mkdir-p "/var/run/openvswitch")
  1430. (mkdir-p "/var/lib/openvswitch")
  1431. (let ((conf.db "/var/lib/openvswitch/conf.db"))
  1432. (unless (file-exists? conf.db)
  1433. (system* #$ovsdb-tool "create" conf.db)))))))))
  1434. (define openvswitch-shepherd-service
  1435. (match-lambda
  1436. (($ <openvswitch-configuration> package)
  1437. (let ((ovsdb-server (file-append package "/sbin/ovsdb-server"))
  1438. (ovs-vswitchd (file-append package "/sbin/ovs-vswitchd")))
  1439. (list
  1440. (shepherd-service
  1441. (provision '(ovsdb))
  1442. (documentation "Run the Open vSwitch database server.")
  1443. (start #~(make-forkexec-constructor
  1444. (list #$ovsdb-server "--pidfile"
  1445. "--remote=punix:/var/run/openvswitch/db.sock")
  1446. #:pid-file "/var/run/openvswitch/ovsdb-server.pid"))
  1447. (stop #~(make-kill-destructor)))
  1448. (shepherd-service
  1449. (provision '(vswitchd))
  1450. (requirement '(ovsdb))
  1451. (documentation "Run the Open vSwitch daemon.")
  1452. (start #~(make-forkexec-constructor
  1453. (list #$ovs-vswitchd "--pidfile")
  1454. #:pid-file "/var/run/openvswitch/ovs-vswitchd.pid"))
  1455. (stop #~(make-kill-destructor))))))))
  1456. (define openvswitch-service-type
  1457. (service-type
  1458. (name 'openvswitch)
  1459. (extensions
  1460. (list (service-extension activation-service-type
  1461. openvswitch-activation)
  1462. (service-extension profile-service-type
  1463. (compose list openvswitch-configuration-package))
  1464. (service-extension shepherd-root-service-type
  1465. openvswitch-shepherd-service)))
  1466. (description
  1467. "Run @uref{http://www.openvswitch.org, Open vSwitch}, a multilayer virtual
  1468. switch designed to enable massive network automation through programmatic
  1469. extension.")
  1470. (default-value (openvswitch-configuration))))
  1471. ;;;
  1472. ;;; iptables
  1473. ;;;
  1474. (define %iptables-accept-all-rules
  1475. (plain-file "iptables-accept-all.rules"
  1476. "*filter
  1477. :INPUT ACCEPT
  1478. :FORWARD ACCEPT
  1479. :OUTPUT ACCEPT
  1480. COMMIT
  1481. "))
  1482. (define-record-type* <iptables-configuration>
  1483. iptables-configuration make-iptables-configuration iptables-configuration?
  1484. (iptables iptables-configuration-iptables
  1485. (default iptables))
  1486. (ipv4-rules iptables-configuration-ipv4-rules
  1487. (default %iptables-accept-all-rules))
  1488. (ipv6-rules iptables-configuration-ipv6-rules
  1489. (default %iptables-accept-all-rules)))
  1490. (define iptables-shepherd-service
  1491. (match-lambda
  1492. (($ <iptables-configuration> iptables ipv4-rules ipv6-rules)
  1493. (let ((iptables-restore (file-append iptables "/sbin/iptables-restore"))
  1494. (ip6tables-restore (file-append iptables "/sbin/ip6tables-restore")))
  1495. (shepherd-service
  1496. (documentation "Packet filtering framework")
  1497. (provision '(iptables))
  1498. (start #~(lambda _
  1499. (invoke #$iptables-restore #$ipv4-rules)
  1500. (invoke #$ip6tables-restore #$ipv6-rules)))
  1501. (stop #~(lambda _
  1502. (invoke #$iptables-restore #$%iptables-accept-all-rules)
  1503. (invoke #$ip6tables-restore #$%iptables-accept-all-rules))))))))
  1504. (define iptables-service-type
  1505. (service-type
  1506. (name 'iptables)
  1507. (description
  1508. "Run @command{iptables-restore}, setting up the specified rules.")
  1509. (extensions
  1510. (list (service-extension shepherd-root-service-type
  1511. (compose list iptables-shepherd-service))))))
  1512. ;;;
  1513. ;;; nftables
  1514. ;;;
  1515. (define %default-nftables-ruleset
  1516. (plain-file "nftables.conf"
  1517. "# A simple and safe firewall
  1518. table inet filter {
  1519. chain input {
  1520. type filter hook input priority 0; policy drop;
  1521. # early drop of invalid connections
  1522. ct state invalid drop
  1523. # allow established/related connections
  1524. ct state { established, related } accept
  1525. # allow from loopback
  1526. iifname lo accept
  1527. # allow icmp
  1528. ip protocol icmp accept
  1529. ip6 nexthdr icmpv6 accept
  1530. # allow ssh
  1531. tcp dport ssh accept
  1532. # reject everything else
  1533. reject with icmpx type port-unreachable
  1534. }
  1535. chain forward {
  1536. type filter hook forward priority 0; policy drop;
  1537. }
  1538. chain output {
  1539. type filter hook output priority 0; policy accept;
  1540. }
  1541. }
  1542. "))
  1543. (define-record-type* <nftables-configuration>
  1544. nftables-configuration
  1545. make-nftables-configuration
  1546. nftables-configuration?
  1547. (package nftables-configuration-package
  1548. (default nftables))
  1549. (ruleset nftables-configuration-ruleset ; file-like object
  1550. (default %default-nftables-ruleset)))
  1551. (define nftables-shepherd-service
  1552. (match-lambda
  1553. (($ <nftables-configuration> package ruleset)
  1554. (let ((nft (file-append package "/sbin/nft")))
  1555. (shepherd-service
  1556. (documentation "Packet filtering and classification")
  1557. (provision '(nftables))
  1558. (start #~(lambda _
  1559. (invoke #$nft "--file" #$ruleset)))
  1560. (stop #~(lambda _
  1561. (invoke #$nft "flush" "ruleset"))))))))
  1562. (define nftables-service-type
  1563. (service-type
  1564. (name 'nftables)
  1565. (description
  1566. "Run @command{nft}, setting up the specified ruleset.")
  1567. (extensions
  1568. (list (service-extension shepherd-root-service-type
  1569. (compose list nftables-shepherd-service))
  1570. (service-extension profile-service-type
  1571. (compose list nftables-configuration-package))))
  1572. (default-value (nftables-configuration))))
  1573. ;;;
  1574. ;;; PageKite
  1575. ;;;
  1576. (define-record-type* <pagekite-configuration>
  1577. pagekite-configuration
  1578. make-pagekite-configuration
  1579. pagekite-configuration?
  1580. (package pagekite-configuration-package
  1581. (default pagekite))
  1582. (kitename pagekite-configuration-kitename
  1583. (default #f))
  1584. (kitesecret pagekite-configuration-kitesecret
  1585. (default #f))
  1586. (frontend pagekite-configuration-frontend
  1587. (default #f))
  1588. (kites pagekite-configuration-kites
  1589. (default '("http:@kitename:localhost:80:@kitesecret")))
  1590. (extra-file pagekite-configuration-extra-file
  1591. (default #f)))
  1592. (define (pagekite-configuration-file config)
  1593. (match-record config <pagekite-configuration>
  1594. (package kitename kitesecret frontend kites extra-file)
  1595. (mixed-text-file "pagekite.rc"
  1596. (if extra-file
  1597. (string-append "optfile = " extra-file "\n")
  1598. "")
  1599. (if kitename
  1600. (string-append "kitename = " kitename "\n")
  1601. "")
  1602. (if kitesecret
  1603. (string-append "kitesecret = " kitesecret "\n")
  1604. "")
  1605. (if frontend
  1606. (string-append "frontend = " frontend "\n")
  1607. "defaults\n")
  1608. (string-join (map (lambda (kite)
  1609. (string-append "service_on = " kite))
  1610. kites)
  1611. "\n"
  1612. 'suffix))))
  1613. (define (pagekite-shepherd-service config)
  1614. (match-record config <pagekite-configuration>
  1615. (package kitename kitesecret frontend kites extra-file)
  1616. (with-imported-modules (source-module-closure
  1617. '((gnu build shepherd)
  1618. (gnu system file-systems)))
  1619. (shepherd-service
  1620. (documentation "Run the PageKite service.")
  1621. (provision '(pagekite))
  1622. (requirement '(networking))
  1623. (modules '((gnu build shepherd)
  1624. (gnu system file-systems)))
  1625. (start #~(make-forkexec-constructor/container
  1626. (list #$(file-append package "/bin/pagekite")
  1627. "--clean"
  1628. "--nullui"
  1629. "--nocrashreport"
  1630. "--runas=pagekite:pagekite"
  1631. (string-append "--optfile="
  1632. #$(pagekite-configuration-file config)))
  1633. #:log-file "/var/log/pagekite.log"
  1634. #:mappings #$(if extra-file
  1635. #~(list (file-system-mapping
  1636. (source #$extra-file)
  1637. (target source)))
  1638. #~'())))
  1639. ;; SIGTERM doesn't always work for some reason.
  1640. (stop #~(make-kill-destructor SIGINT))))))
  1641. (define %pagekite-log-rotation
  1642. (list (log-rotation
  1643. (files '("/var/log/pagekite.log")))))
  1644. (define %pagekite-accounts
  1645. (list (user-group (name "pagekite") (system? #t))
  1646. (user-account
  1647. (name "pagekite")
  1648. (group "pagekite")
  1649. (system? #t)
  1650. (comment "PageKite user")
  1651. (home-directory "/var/empty")
  1652. (shell (file-append shadow "/sbin/nologin")))))
  1653. (define pagekite-service-type
  1654. (service-type
  1655. (name 'pagekite)
  1656. (default-value (pagekite-configuration))
  1657. (extensions
  1658. (list (service-extension shepherd-root-service-type
  1659. (compose list pagekite-shepherd-service))
  1660. (service-extension account-service-type
  1661. (const %pagekite-accounts))
  1662. (service-extension rottlog-service-type
  1663. (const %pagekite-log-rotation))))
  1664. (description
  1665. "Run @url{https://pagekite.net/,PageKite}, a tunneling solution to make
  1666. local servers publicly accessible on the web, even behind NATs and firewalls.")))
  1667. ;;;
  1668. ;;; Yggdrasil
  1669. ;;;
  1670. (define-record-type* <yggdrasil-configuration>
  1671. yggdrasil-configuration
  1672. make-yggdrasil-configuration
  1673. yggdrasil-configuration?
  1674. (package yggdrasil-configuration-package
  1675. (default yggdrasil))
  1676. (json-config yggdrasil-configuration-json-config
  1677. (default '()))
  1678. (config-file yggdrasil-config-file
  1679. (default "/etc/yggdrasil-private.conf"))
  1680. (autoconf? yggdrasil-configuration-autoconf?
  1681. (default #f))
  1682. (log-level yggdrasil-configuration-log-level
  1683. (default 'info))
  1684. (log-to yggdrasil-configuration-log-to
  1685. (default 'stdout)))
  1686. (define (yggdrasil-configuration-file config)
  1687. (define (scm->yggdrasil-json x)
  1688. (define key-value?
  1689. dotted-list?)
  1690. (define (param->camel str)
  1691. (string-concatenate
  1692. (map
  1693. string-capitalize
  1694. (string-split str (cut eqv? <> #\-)))))
  1695. (cond
  1696. ((key-value? x)
  1697. (let ((k (car x))
  1698. (v (cdr x)))
  1699. (cons
  1700. (if (symbol? k)
  1701. (param->camel (symbol->string k))
  1702. k)
  1703. v)))
  1704. ((list? x) (map scm->yggdrasil-json x))
  1705. ((vector? x) (vector-map scm->yggdrasil-json x))
  1706. (else x)))
  1707. (computed-file
  1708. "yggdrasil.conf"
  1709. #~(call-with-output-file #$output
  1710. (lambda (port)
  1711. ;; it's HJSON, so comments are a-okay
  1712. (display "# Generated by yggdrasil-service\n" port)
  1713. (display #$(scm->json-string
  1714. (scm->yggdrasil-json
  1715. (yggdrasil-configuration-json-config config)))
  1716. port)))))
  1717. (define (yggdrasil-shepherd-service config)
  1718. "Return a <shepherd-service> for yggdrasil with CONFIG."
  1719. (define yggdrasil-command
  1720. #~(append
  1721. (list (string-append
  1722. #$(yggdrasil-configuration-package config)
  1723. "/bin/yggdrasil")
  1724. "-useconffile"
  1725. #$(yggdrasil-configuration-file config))
  1726. (if #$(yggdrasil-configuration-autoconf? config)
  1727. '("-autoconf")
  1728. '())
  1729. (let ((extraconf #$(yggdrasil-config-file config)))
  1730. (if extraconf
  1731. (list "-extraconffile" extraconf)
  1732. '()))
  1733. (list "-loglevel"
  1734. #$(symbol->string
  1735. (yggdrasil-configuration-log-level config))
  1736. "-logto"
  1737. #$(symbol->string
  1738. (yggdrasil-configuration-log-to config)))))
  1739. (list (shepherd-service
  1740. (documentation "Connect to the Yggdrasil mesh network")
  1741. (provision '(yggdrasil))
  1742. (requirement '(networking))
  1743. (start #~(make-forkexec-constructor
  1744. #$yggdrasil-command
  1745. #:log-file "/var/log/yggdrasil.log"
  1746. #:group "yggdrasil"))
  1747. (stop #~(make-kill-destructor)))))
  1748. (define %yggdrasil-log-rotation
  1749. (list (log-rotation
  1750. (files '("/var/log/yggdrasil.log")))))
  1751. (define %yggdrasil-accounts
  1752. (list (user-group (name "yggdrasil") (system? #t))))
  1753. (define yggdrasil-service-type
  1754. (service-type
  1755. (name 'yggdrasil)
  1756. (description
  1757. "Connect to the Yggdrasil mesh network.
  1758. See @command{yggdrasil -genconf} for config options.")
  1759. (extensions
  1760. (list (service-extension shepherd-root-service-type
  1761. yggdrasil-shepherd-service)
  1762. (service-extension account-service-type
  1763. (const %yggdrasil-accounts))
  1764. (service-extension profile-service-type
  1765. (compose list yggdrasil-configuration-package))
  1766. (service-extension rottlog-service-type
  1767. (const %yggdrasil-log-rotation))))))
  1768. ;;;
  1769. ;;; IPFS
  1770. ;;;
  1771. (define-record-type* <ipfs-configuration>
  1772. ipfs-configuration
  1773. make-ipfs-configuration
  1774. ipfs-configuration?
  1775. (package ipfs-configuration-package
  1776. (default go-ipfs))
  1777. (gateway ipfs-configuration-gateway
  1778. (default "/ip4/127.0.0.1/tcp/8082"))
  1779. (api ipfs-configuration-api
  1780. (default "/ip4/127.0.0.1/tcp/5001")))
  1781. (define %ipfs-home "/var/lib/ipfs")
  1782. (define %ipfs-accounts
  1783. (list (user-account
  1784. (name "ipfs")
  1785. (group "ipfs")
  1786. (system? #t)
  1787. (comment "IPFS daemon user")
  1788. (home-directory "/var/lib/ipfs")
  1789. (shell (file-append shadow "/sbin/nologin")))
  1790. (user-group
  1791. (name "ipfs")
  1792. (system? #t))))
  1793. (define (ipfs-binary config)
  1794. (define command
  1795. (file-append (ipfs-configuration-package config) "/bin/ipfs"))
  1796. (least-authority-wrapper
  1797. command
  1798. #:name "ipfs"
  1799. #:mappings (list %ipfs-home-mapping)
  1800. #:namespaces (delq 'net %namespaces)))
  1801. (define %ipfs-home-mapping
  1802. (file-system-mapping
  1803. (source %ipfs-home)
  1804. (target %ipfs-home)
  1805. (writable? #t)))
  1806. (define %ipfs-environment
  1807. #~(list #$(string-append "HOME=" %ipfs-home)))
  1808. (define (ipfs-shepherd-service config)
  1809. "Return a <shepherd-service> for IPFS with CONFIG."
  1810. (define ipfs-daemon-command
  1811. #~(list #$(ipfs-binary config) "daemon"))
  1812. (list (shepherd-service
  1813. (provision '(ipfs))
  1814. ;; While IPFS is most useful when the machine is connected
  1815. ;; to the network, only loopback is required for starting
  1816. ;; the service.
  1817. (requirement '(loopback))
  1818. (documentation "Connect to the IPFS network")
  1819. (start #~(make-forkexec-constructor
  1820. #$ipfs-daemon-command
  1821. #:log-file "/var/log/ipfs.log"
  1822. #:user "ipfs" #:group "ipfs"
  1823. #:environment-variables #$%ipfs-environment))
  1824. (stop #~(make-kill-destructor)))))
  1825. (define %ipfs-log-rotation
  1826. (list (log-rotation
  1827. (files '("/var/log/ipfs.log")))))
  1828. (define (%ipfs-activation config)
  1829. "Return an activation gexp for IPFS with CONFIG"
  1830. (define (exec-command . args)
  1831. ;; Exec the given ifps command with the right authority.
  1832. #~(let ((pid (primitive-fork)))
  1833. (if (zero? pid)
  1834. (dynamic-wind
  1835. (const #t)
  1836. (lambda ()
  1837. ;; Run ipfs init and ipfs config from a container,
  1838. ;; in case the IPFS daemon was compromised at some point
  1839. ;; and ~/.ipfs is now a symlink to somewhere outside
  1840. ;; %ipfs-home.
  1841. (let ((pw (getpwnam "ipfs")))
  1842. (setgroups '#())
  1843. (setgid (passwd:gid pw))
  1844. (setuid (passwd:uid pw))
  1845. (environ #$%ipfs-environment)
  1846. (execl #$(ipfs-binary config) #$@args)))
  1847. (lambda ()
  1848. (primitive-exit 127)))
  1849. (waitpid pid))))
  1850. (define settings
  1851. `(("Addresses.API" ,(ipfs-configuration-api config))
  1852. ("Addresses.Gateway" ,(ipfs-configuration-gateway config))))
  1853. (define inner-gexp
  1854. #~(begin
  1855. (umask #o077)
  1856. ;; Create $HOME/.ipfs structure
  1857. #$(exec-command "ipfs" "init")
  1858. ;; Apply settings
  1859. #$@(map (match-lambda
  1860. ((setting value)
  1861. (exec-command "ipfs" "config" setting value)))
  1862. settings)))
  1863. (define inner-script
  1864. (program-file "ipfs-activation-inner" inner-gexp))
  1865. ;; The activation may happen from the initrd, which uses
  1866. ;; a statically-linked guile, while the guix container
  1867. ;; procedures require a working dynamic-link.
  1868. #~(system* #$inner-script))
  1869. (define ipfs-service-type
  1870. (service-type
  1871. (name 'ipfs)
  1872. (extensions
  1873. (list (service-extension account-service-type
  1874. (const %ipfs-accounts))
  1875. (service-extension activation-service-type
  1876. %ipfs-activation)
  1877. (service-extension shepherd-root-service-type
  1878. ipfs-shepherd-service)
  1879. (service-extension rottlog-service-type
  1880. (const %ipfs-log-rotation))))
  1881. (default-value (ipfs-configuration))
  1882. (description
  1883. "Run @command{ipfs daemon}, the reference implementation
  1884. of the IPFS peer-to-peer storage network.")))
  1885. ;;;
  1886. ;;; Keepalived
  1887. ;;;
  1888. (define-record-type* <keepalived-configuration>
  1889. keepalived-configuration make-keepalived-configuration
  1890. keepalived-configuration?
  1891. (keepalived keepalived-configuration-keepalived ;file-like
  1892. (default keepalived))
  1893. (config-file keepalived-configuration-config-file ;file-like
  1894. (default #f)))
  1895. (define keepalived-shepherd-service
  1896. (match-lambda
  1897. (($ <keepalived-configuration> keepalived config-file)
  1898. (list
  1899. (shepherd-service
  1900. (provision '(keepalived))
  1901. (documentation "Run keepalived.")
  1902. (requirement '(loopback))
  1903. (start #~(make-forkexec-constructor
  1904. (list (string-append #$keepalived "/sbin/keepalived")
  1905. "--dont-fork" "--log-console" "--log-detail"
  1906. "--pid=/var/run/keepalived.pid"
  1907. (string-append "--use-file=" #$config-file))
  1908. #:pid-file "/var/run/keepalived.pid"
  1909. #:log-file "/var/log/keepalived.log"))
  1910. (respawn? #f)
  1911. (stop #~(make-kill-destructor)))))))
  1912. (define %keepalived-log-rotation
  1913. (list (log-rotation
  1914. (files '("/var/log/keepalived.log")))))
  1915. (define keepalived-service-type
  1916. (service-type (name 'keepalived)
  1917. (extensions (list (service-extension shepherd-root-service-type
  1918. keepalived-shepherd-service)
  1919. (service-extension rottlog-service-type
  1920. (const %keepalived-log-rotation))))
  1921. (description
  1922. "Run @uref{https://www.keepalived.org/, Keepalived}
  1923. routing software.")))
  1924. ;;; networking.scm ends here