networking.scm 82 KB

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