networking.scm 78 KB

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