networking.scm 88 KB

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