aboutsummaryrefslogtreecommitdiff
path: root/doc/whispers.texi
diff options
context:
space:
mode:
authorRunciter2024-10-27 23:35:13 +0800
committerRunciter2024-10-27 23:35:13 +0800
commit2a76cd88aa9f2ee182ec059870fde832bf182d33 (patch)
tree58e8193235df4a889c776fe04600ea06e9a6fdf9 /doc/whispers.texi
downloadwhispers-doc-2a76cd88aa9f2ee182ec059870fde832bf182d33.tar.gz
A AUTHORS A COPYING A ChangeLog A INSTALL A Makefile.am A Makefile.in A NEWS A README A aclocal.m4 A configure A configure.ac A doc/Makefile.am A doc/Makefile.in A doc/fdl-1.3.texi A doc/texinfo.tex A doc/whispers.texi A install-sh A missing
Diffstat (limited to 'doc/whispers.texi')
-rw-r--r--doc/whispers.texi1312
1 files changed, 1312 insertions, 0 deletions
diff --git a/doc/whispers.texi b/doc/whispers.texi
new file mode 100644
index 0000000..8e44f2a
--- /dev/null
+++ b/doc/whispers.texi
@@ -0,0 +1,1312 @@
+\input texinfo
+@c -*-texinfo-*-
+
+@c %**start of header
+@setfilename whispers.info
+@documentencoding UTF-8
+@settitle Whispers Reference Manual
+@c %**end of header
+
+@set UPDATED 10 October 2024
+@set UPDATED-MONTH October 2024
+@set EDITION 0.1.0
+@set VERSION 0.1.0
+
+@copying
+Copyright @copyright{} 2024 Runciter <runciter@@whispers-vpn.org>@*
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.3 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
+copy of the license is included in the section entitled ``GNU Free
+Documentation License''.
+@end copying
+
+@dircategory System administration
+@direntry
+* Whispers: (whispers). Tree of shepherd processes
+@end direntry
+
+@titlepage
+@title Whispers Reference Manual
+@subtitle Shepherd process tree for GNU Guix
+@author Runciter
+
+@page
+@vskip 0pt plus 1filll
+Edition @value{EDITION} @*
+@value{UPDATED} @*
+
+@insertcopying
+@end titlepage
+
+@contents
+
+@node Top, Definitions, (dir), (dir)
+@top Whispers
+
+This manual documents Whispers version @value{VERSION}.
+
+@insertcopying
+
+@menu
+* Definitions::
+* Purpose::
+* The whispers service::
+* Service extensions::
+* Whispers services::
+* The whispers command::
+* Caveats::
+* Bugs::
+* GNU Free Documentation License::
+* Concept Index::
+* Programming Index::
+@end menu
+
+@node Definitions, Purpose, Top, Top
+@chapter Definitions
+
+Whispers is a multi-user process tree of shepherd processes and their
+services, @xref{Top,,,shepherd,The GNU Shepherd Manual}.
+
+Within this manual, shepherd processes run by whispers and their
+relationships between themselves and with their services are referred to
+using the following terminology:
+
+@table @code
+
+@cindex hierarchy
+@item Hierarchy
+The part of the whispers process tree constituted of shepherd processes
+proper is referred to as the whispers @code{hierarchy}. Non-shepherd
+processes of the whispers process tree are also shepherd services
+provided by whispers through its hierarchy, although they are not
+themselves part of the hierarchy.
+
+@cindex superior
+@item Superior
+The parent process of a process running inside the whispers process tree
+is called its @code{superior}, unless that parent is just the PID 1
+shepherd, in which case the child is the shepherd process which lies at
+the top of the hierarchy.
+
+@cindex lieutenant
+@item Lieutenant
+A child process and service of a shepherd running inside the hierarchy
+is called a @code{lieutenant} of that shepherd process. While
+non-shepherd processes of the whispers tree are also lieutenants, they
+cannot have lieutenants themselves.
+
+@end table
+
+@node Purpose, The whispers service, Definitions, Top
+@chapter Purpose
+
+Whispers provides a sandboxing facility, since all processes controlled
+as shepherd services by the hierarchy can be stopped or started as an
+action of their service in their superior or the PID 1 shepherd. They
+can also be given actions independently from each other. The command
+@command{whispers} is a simple wrapper around @command{herd} providing a
+convenience switch to control all services in the hierarchy, @xref{The
+whispers command}.
+
+As a Guix service, whispers provides configuration handles so that
+actions can be performed by any controlling shepherd before starting
+shepherd lieutenants of the hierarchy, or after stopping them. While
+this facility is mostly intended for developers adding easily
+configurable extensions to whispers, they can also be employed by users
+should they decide to expand the hierarchy by using the low-level
+configuration of the whispers Guix service itself, @xref{The whispers
+service}.
+
+Additionally, the whispers hierarchy can be configured to operate
+daemons run by unprivileged users of the system, including when those
+have to make use of unprivileged sockets. An important difference
+between unprivileged lieutenants of the whispers hierarchy and Guix home
+shepherd services is that the latter are typically (always?) running
+only when their controlling user has a login session on the machine,
+while the former are running permanently and restarted automatically
+according to the configuration of their controlling lieutenant
+shepherd. Incidentally, services of unprivileged whispers lieutenants do
+not depend on @command{elogind}, its dependencies or the facilities it
+provides.
+
+A directory tree of imbricated tmpfs file systems is also deployed
+on-demand under @code{/run/whispers} whenever processes are started
+inside the hierarchy proper. These directories hold UNIX sockets and PID
+files necessary to the operation of the hierarchy and the other services
+it provides. When a hierarchy process is stopped by its superior or by
+PID 1, its dedicated tmpfs file system is unmounted after lieutenant
+tmpfs file systems are recursively unmounted within the hierarchy,
+leaving a ``clean slate'' with no leftover PID or socket files.
+
+Whispers itself can be fully stopped in this way by using @command{herd}
+to trigger the stop action of its service in PID 1, namely by using the
+command @command{herd stop whispers}. In a similar fashion, this will
+recursively unmount all tmpfs files systems created by whispers,
+hopefully and normally leaving behind an empty @code{/run/whispers}
+directory.
+
+Log files of the whispers hierarchy and its shepherd services are all
+stored under the path @code{/var/log/whispers}, with a sub-directory
+tree mimicking the hierarchy in its current and past states.
+
+Various Scheme sub-modules of @code{(whispers packages whispers)}
+provide Guix services that deploy daemons running inside the whispers
+hierarchy. Those modules also export configuration records for their
+services; they can be configured through semi-digestible Guix service
+instanciations in a machine's system configuration, @xref{Whispers
+services}. This is in any case simpler than deploying all the system's
+whispers lieutenants and their services ``by hand'' using the low-level
+whispers service configuration record, @ref{The whispers service}.
+
+@node The whispers service, Service extensions, Purpose, Top
+@chapter The whispers service
+
+The @code{(whispers services whispers)} scheme module provides a Guix
+shepherd service which extends a multi-user process tree of shepherd
+services.
+
+@defvar whispers-service-type
+This is the type for the service extending the shepherd with a whispers
+process tree. Its value must be an @code{whispers-configuration} record.
+
+@end defvar
+
+@deftp {Data Type} whispers-configuration
+
+@table @asis
+
+@item @code{coreutils-package} (default @code{coreutils})
+A file-like-object. The coreutils package to use.
+
+@item @code{util-linux-package} (default @code{util-linux})
+A file-like-object. the util-linux package to use.
+
+@item @code{whispers-package} (default @code{whispers})
+A file-like-object. the whispers package to use, @xref{The whispers
+command}.
+
+@item @code{name} (default @code{'whispers})
+A symbol. The shepherd provision of this whispers service in its
+superior or PID 1.
+
+@item @code{lieutenants} (default @code{'()})
+A list of Guix service objects. The lieutenants of this whispers
+service.
+
+@item @code{requires} (default @code{'()})
+A list of symbols. The list of shepherd provisions that this service
+requires in its superior or PID 1, a.k.a its dependencies.
+
+@item @code{user} (default @code{"root"})
+A string. The name of the user running this whispers service.
+
+@item @code{extend-user?} (default @code{#f})
+A boolean value. Whether @code{user} should be extended by Guix system
+when the system is reconfigured. Set this switch when and only when the
+group will not be explicitly declared in the system configuration Scheme
+file.
+
+@item @code{group} (default @code{"root"})
+A string. The name of the group this whispers service is run as.
+
+@item @code{extend-group?} (default @code{#f})
+A boolean value. Whether @code{group} should be extended by Guix system
+when the system is reconfigured. Set this switch when and only when the
+group will not be explicitly declared in the system configuration Scheme
+file.
+
+@item @code{timeout} (default @code{'(default-pid-file-timeout)})
+A string. The PID file timeout when starting this service. Its default
+value is defined in the shepherd's program Scheme code.
+
+@item @code{extra-packages} (default @code{(list)})
+A list of Guix records of type @code{package}. A list of extra packages
+to include in the profile that this service extends the Guix service of
+type @code{guix-profile-service-type} with.
+
+@item @code{extra-actions} (default @code{(list)})
+A list of shepherd-action records. Extra actions that are provided for
+this service in its superior or PID 1.
+
+@item @code{pre-start-action?} (default @code{#f})
+A boolean value. Whether this service performs a shepherd action named
+@code{pre-start} in its superior of PID 1, as part of its @code{start}
+action, immediately before its shepherd process is run by its superior
+or PID 1. If this flag is set, the @code{pre-start} action must be
+defined within the @code{extra-actions} field of this record.
+
+@item @code{post-stop-action?} (default @code{#f})
+A boolean value. Whether this service performs a shepherd action named
+@code{post-stop} in its superior of PID 1, as part of its @code{stop}
+action, immediately after its shepherd process is terminated by its
+superior or PID 1. If this flag is set, the @code{pre-start} action must
+be defined within the @code{extra-actions} field of this record.
+
+@item @code{%auto-start?} (default @code{#t})
+A boolean value. Whether this service's superior or PID 1 should
+automatically start this service when it is started itself.
+
+@end table
+
+@end deftp
+
+@node Service extensions, Whispers services, The whispers service, Top
+@chapter Service extension relationships
+
+The service of type @code{whispers-service-type} (@xref{The whispers
+service}) extends multiple other services (@xref{Service Types and
+Services,,,Guix,GNU guix}):
+
+@table @code
+
+@item rottlog-service-type
+@xref{Log Rotation,,,Guix,GNU guix}.
+
+@item account-service-type
+
+@item shepherd-root-service-type
+@xref{Shepherd Services,,,Guix,GNU guix}.
+
+@item mcron-service-type
+@xref{Scheduled Job Execution,,,Guix,GNU guix}.
+
+@item profile-service-type
+@xref{Service Reference,,,Guix,GNU guix}.
+
+@end table
+
+Only the shepherd at the top of the hierarchy extends the root
+shepherd. Hierarchy shepherd services themselves can be pseudo-extended
+by other services which have a @code{service-extension} targeting the
+service of type @code{shepherd-root-service-type}. That is to say,
+Whispers hijacks the shepherd extensions of services within its service
+tree so that those services ``extend'' their superior shepherd's
+pseudo-Guix service instead of extending the root shepherd Guix service.
+
+Services of the service tree which have a @code{service-extension}
+targeting the services of type @code{profile-service-type},
+@code{mcron-service-type} and/or @code{account-service-type} simply have
+their declared extensions recursively collected by whispers and passed
+down the extension graph by whisper's own extensions of other Guix
+services at system-reconfiguration time, as if they were direct Guix
+service extensions.
+
+The same functionality is intended and included in the code for services
+of the service tree which have a @code{service-extension} targeting the
+service of type @code{rottlog-service-type}. At the time of writing, it
+does not seems to be working, no log rotation happens inside the path
+@code{/var/log/whispers}.
+
+Other service extensions of services within the whispers service tree
+should be silently ignored.
+
+On the hand, the service of type @code{whispers-service-type} can be
+extended, in the strict sense of the word, by other services extending
+it with a nested list of lieutenants to be added one level below the top
+of the hierarchy. Sub-modules of the @code{whispers services whispers}
+module make use of this mechanism, @xref{Whispers services}.
+
+@node Whispers services, The whispers command, Service extensions, Top
+@chapter Whispers services
+
+This section documents whispers service types for various applications,
+for which service types and configuration bindings are offered by the
+whispers channel in scheme sub-modules of @code{whispers services
+whispers}. The facilities offered make configuration simpler than if
+they were done by hand using general whispers records (@xref{The
+whispers service} about those).
+
+Most of the services described in this section can be run either as root
+or as an unprivileged user, independently from @command{elogind} and
+from the existence of an interactive login session, as it is often
+desired and sometimes completely necessary. The services can however
+only be configured with root permissions, because they are deployed by
+system reconfiguration, @xref{System Configuration,,,Guix,GNU guix}.
+
+For the services documented here, typically, a hierarchy is extended
+below the whispers service of PID 1 for a service type or a themed group
+of service types. Each of these first-level hierarchies is documented by
+a sub-section of the present section. Those first level lieutenants
+extend in turn one lieutenant for each individual user which will make
+use of the services under their umbrella. Those per-user lieutenants are
+the superiors of individual (non-shepherd process) shepherd services.
+
+The resulting hierarchies are of the form:
+``/<hierarchy-theme>/<user>/<service>''. The ``<user>'' lieutenant(s) of
+``<hierarchy-type>'' each extend a shepherd process running as the user,
+so that the sockets and PID files of ``<service>'' and their parent
+directories hopefully exhibit correct permissions.
+
+For unprivileged users, the ``<user>'' lieutenant name is the same as
+their UNIX handle, and their service within their superior provisions a
+symbol converted from this name. For root, the lieutenant name is
+``root-user'' and the shepherd provision is the symbol
+@code{root-user}. This is done to avoid conflicts, because every
+shepherd daemon has a built-in service which provisions the symbol
+@code{root}.
+
+@menu
+* The finance hierarchy::
+* The gps hierarchy::
+* The mail hierarchy::
+* The ssh hierarchy::
+* The vpn hierarchy::
+* The xdg hierarchy::
+* Unprivileged services::
+@end menu
+
+@node The finance hierarchy, The gps hierarchy, Whispers services, Whispers services
+@section The finance hierarchy
+
+A bitcoin (BTC) node and/or a monero (XMR) can be deployed as shepherd
+services run by an unprivileged user within the @code{finance}
+hierarchy. Those features are provided by the @code{whispers services
+whispers finance} module.
+
+@menu
+* Configuring the finance hierarchy and services::
+* Configuration examples (whispers finance)::
+@end menu
+
+@node Configuring the finance hierarchy and services, Configuration examples (whispers finance), The finance hierarchy, The finance hierarchy
+@subsection Configuring the finance hierachy and services
+
+@defvar whispers-finance-service-type
+This is the type for the service extending whispers with a finance
+hierarchy and its associated services. Its value must be a
+@code{whispers-finance-configuration} record.
+
+@end defvar
+
+@deftp {Data Type} whispers-finance-configuration
+
+@table @asis
+
+@item @code{users-groups-nodes} (default @code{()})
+A list of @code{crypto-user-group-nodes} records configuring the finance
+hierarchy and its services, containing one member for each user making
+use of the hierarchy, be they root or unprivileged users.
+
+@end table
+
+@end deftp
+
+A record of type @code{crypto-user-group-nodes} configures the
+hierarchy and its services for a single user of the system.
+
+@deftp {Data Type} crypto-user-group-nodes
+
+@table @asis
+
+@item @code{user-and-group} (default @code{(whispers-user-group)})
+A record of the @code{whispers-user-group} type, @xref{Unprivileged
+services}. Its default is the record type's default record.
+
+@item @code{nodes} (default @code{(nodes-configuration})
+A record of the @code{nodes-configuration} type. Its default is the
+record type's default record.
+
+@end table
+
+@end deftp
+
+A record of type @code{nodes-configuration} type configures whether
+individual crypto services are wanted for a single user at the tip of
+the finance hierarchy, and stores their configuration for this user.
+
+@deftp {Data Type} nodes-configuration
+
+@table @asis
+
+@item @code{(bitcoin?} (default @code{#f})
+A boolean value, whether to extend a bitcoin node as a service.
+
+@item @code{(btc-node} (default @code{(bitcoin-node-configuration)})
+A record of the @code{bitcoin-node-configuration} type. Its default is
+the record type's default record.
+
+@item @code{(monero?} (default @code{#f})
+A boolean value
+
+@item @code{(xmr-node} (default @code{(monero-node-configuration)})
+A record of the @code{monero-node-configuration} type. Its default is
+the record type's default record.
+
+@end table
+
+@end deftp
+
+When the finance hierarchy extends a bitcoin node, the node is
+configured by a record of type @code{bitcoin-node-configuration} .
+
+@deftp {Data Type} bitcoin-node-configuration
+
+@table @asis
+
+@item @code{bitcoin-package} (default @code{bitcoin-core})
+A file-like object. The bitcoin package to use.
+
+@item @code{walletdir-opt?} (default @code{#f})
+A boolean value. Whether to set the @command{-walletdir} option
+explicitly for the service.
+
+@item @code{walletdir} (default @code{""})
+A string. The value for the @command{-walletdir} option when it is
+explicitly set.
+
+@item @code{proxy-opt?} (default @code{#f})
+A boolean value. Whether to set the @command{-proxy} option explicitly
+for the service.
+
+@item @code{proxy} (default @code{""})
+A string. The value for the @command{-proxy} option when it is
+explicitly set.
+
+@item @code{%auto-start?} (default @code{#t})
+A boolean value. Whether the service should be started automatically
+when its superior starts.
+
+@end table
+
+@end deftp
+
+When the finance hierarchy extends a monero node, the node is
+configured by a record of type @code{monero-node-configuration} .
+
+@deftp {Data Type} monero-node-configuration
+
+@table @asis
+
+@item @code{bitcoin-package} (default @code{bitcoin-core})
+A file-like object. The bitcoin package to use.
+
+@item @code{proxy-opt?} (default @code{#f})
+A boolean value. Whether to set the @command{--proxy} option explicitly
+for the service.
+
+@item @code{proxy} (default @code{""})
+A string. The value for the @command{--proxy} option when it is
+explicitly set.
+
+@item @code{proxy-opt?} (default @code{#f})
+A boolean value. Whether to set the @command{--tx-proxy} option explicitly
+for the service.
+
+@item @code{proxy} (default @code{""})
+A string. The value for the @command{--tx-proxy} option when it is
+explicitly set.
+
+@item @code{prune-blockchain-opt?} (default @code{#f})
+A boolean value. Whether to use the @command{--prune-blockchain} option
+for the service.
+
+@item @code{%auto-start?} (default @code{#t})
+A boolean value. Whether the service should be started automatically
+when its superior starts.
+
+@end table
+
+@end deftp
+
+@node Configuration examples (whispers finance), , Configuring the finance hierarchy and services, The finance hierarchy
+@subsection Configuration examples (whispers finance)
+
+This example extends a hierarchy with both a BTC and an XMR node.
+
+The nodes contact initiate contacts with other nodes through a SOCKSv5
+proxy exposed on localhost port 7777. The
+@code{whispers-finance-service-type} does not take care of extending
+this proxy automatically; it can be done for example using a service of
+type @code{whispers-ssh-service-type}, @pxref{The ssh hierarchy}.
+Incidentally, should it be desirable or necessary, a service of type
+@code{whispers-ssh-service-type} can also take care of extending
+persistent reverse forwardings to open ports as necessary to be
+accessible for other nodes on the network; by default, port 8333 for
+bitcoin, and port 18080 for monero.
+
+@cindex ssh forwarding, example
+@lisp
+(service whispers-finance-service-type
+ (whispers-finance-configuration
+ (users-groups-nodes
+ (list
+ (crypto-user-group-nodes
+ (nodes
+ (nodes-configuration
+ (bitcoin? #t)
+ (btc-node
+ (bitcoin-node-configuration (proxy-opt? #t)
+ (proxy "localhost:7777")))
+ (monero? #t)
+ (xmr-node
+ (monero-node-configuration (proxy-opt? #t)
+ (proxy "127.0.0.1:7777")
+ (tx-proxy-opt? #f)
+ (tx-proxy "127.0.0.1:7777")
+ (prune-blockchain-opt? #t)))))
+ (user-and-group
+ (whispers-user-group (user "joe-chip")
+ (group "joe-chip"))))))))
+@end lisp
+
+@node The gps hierarchy, The mail hierarchy, The finance hierarchy, Whispers services
+@section The gps hierarchy
+
+A @command{gpsd} service can be deployed as shepherd services run by an
+unprivileged user within the @code{gps} hierarchy. Those features are
+provided by the @code{whispers services whispers gps} module.
+
+@menu
+* Configuring the gps hierarchy and services::
+* Configuration examples (whispers gps)::
+@end menu
+
+@node Configuring the gps hierarchy and services, Configuration examples (whispers gps), The gps hierarchy, The gps hierarchy
+@subsection Configuring the gps hierarchy and services
+
+@defvar whispers-gps-service-type
+This is the type for the service extending whispers with a gps hierarchy
+and its associated services. Its value must be a list of
+@code{gps-user-group-configs} records.
+
+@end defvar
+
+@deftp {Data Type} gps-user-group-configs
+
+@table @asis
+
+@item @code{user-and-group} (default @code{(whispers-user-group)})
+A record of the @code{whispers-user-group} type, @xref{Unprivileged
+services}. Its default is the record type's default record.
+
+@item @code{gpsd?} (default @code{#t})
+A boolean value. Whether to extend gpsd(s) as service(s) for this
+user in the hierarchy.
+
+@item @code{gpsd-configs} (default @code{(list (gpsd-configuration))})
+A list of records of the @code{gpsd-configuration} type. The default is
+a list whose single member is the default value of a
+@code{gpsd-configuration} record.
+
+@end table
+
+@end deftp
+
+The @code{whispers services gps} module exports the
+@code{gpsd-configuration} record type which is used to configure a
+single gpsd service for a user in the hierarchy.
+
+@deftp {Data Type} gpsd-configuration
+
+@table @asis
+
+@item @code{gpsd-package} (default @code{gpsd})
+A file-like object. The gpsd package to use.
+
+@item @code{provision} (default special, see text)
+A symbol. The shepherd provision of the service within its superior. The
+default is computed at system-reconfiguration time as the concatenation
+of @code{gpsd-} and the value of @code{port} field of this record.
+
+@item @code{source} (default @code{"/dev/ttyUSB0})
+A string. The source from which gpsd receives gps data input.
+
+@item @code{port} (default @code{2947})
+An integer. The port on which gpsd serves GPS data for other programs.
+
+@item @code{listen-any?} (default @code{#f})
+A boolean value. Whether gpsd should listen on any interface, as opposed
+to just listening on loopback.
+
+@item @code{%auto-start?} (default @code{#t})
+A boolean value. Whether the service should be started automatically
+when its superior starts.
+
+@end table
+
+@end deftp
+
+@node Configuration examples (whispers gps), , Configuring the gps hierarchy and services, The gps hierarchy
+@subsection Configuration examples (whispers gps)
+
+In this example, a gpsd service is extended which retrieves location
+information from another gpsd at IP 1.2.3.4 and makes it available on
+gpsd's default port 2947 on localhost. The gpsd process belongs to user
+named joe-chip.
+
+@cindex gpsd, example
+@lisp
+(service whispers-gps-service-type
+ (list
+ (gps-user-group-configs
+ (user-and-group
+ (whispers-user-group
+ (user "joe-chip")
+ (group "users")))
+ (gpsd-configs
+ (list
+ (gpsd-configuration (source "tcp://1.2.3.4:2947")))))))
+@end lisp
+
+@node The mail hierarchy, The ssh hierarchy, The gps hierarchy, Whispers services
+@section The mail hierarchy
+
+An @command{hydroxide} service allowing the local handling of emails
+from proton mail server can be deployed as shepherd services run of an
+unprivileged user are provided by the @code{whispers services whispers
+mail} module.
+
+@menu
+* Configuring the mail hierarchy and services::
+* Configuration examples (whispers mail)::
+@end menu
+
+@node Configuring the mail hierarchy and services, Configuration examples (whispers mail), The mail hierarchy, The mail hierarchy
+@subsection Configuring the mail hierarchy and services
+
+@defvar whispers-mail-service-type
+This is the type for the service extending whispers with a mail hierarchy
+and its associated services. Its value must be a
+@code{whispers-mail-configuration} record.
+
+@end defvar
+
+@deftp {Data Type} whispers-mail-configuration
+
+@table @asis
+
+@item @code{users-groups-services} (default @code{()})
+A list of @code{user-group-services} records configuring the
+mail hierarchy and its services, containing one member for each user
+making use of the hierarchy, be they root or unprivileged users.
+
+@end table
+
+@end deftp
+
+@deftp {Data Type} user-group-services
+
+@table @asis
+
+@item @code{user-and-group} (default @code{(whispers-user-group)})
+A record of the @code{whispers-user-group} type, @xref{Unprivileged
+services}. Its default is the record type's default record.
+
+@item @code{services} (default @code{(mail-services-configuration)})
+A record of the @code{mail-services-configuration} type. The default is
+the default value of a @code{mail-services-configuration} record.
+
+@end table
+
+@end deftp
+
+A record of type @code{mail-services-configuration} configures mail
+services for a single user in the hierarchy.
+
+@deftp {Data Type} mail-services-configuration
+
+@table @asis
+
+@item @code{user-and-group} (default @code{#f})
+A boolean value, whether an hydroxide service should be deployed for
+this user in the hierarchy.
+
+@item @code{hydroxide-service} (default @code{(hydroxide-service-configuration)})
+A record of the @code{hydroxide-configuration} type. The default is the
+default value of a @code{hydroxide-service-configuration} record.
+
+@end table
+
+@end deftp
+
+A record of type @code{hydroxide-service-configuration} configures the
+hydroxide service for a single user in the hierarchy.
+
+@deftp {Data Type} hydroxide-service-configuration
+
+@table @asis
+
+@item @code{hydroxide-package} (default @code{hydroxide})
+A file-like object. The hydroxide package to use.
+
+@item @code{https-proxy?} (default @code{#f})
+A boolean value. Whether hydroxide should connect to the proton mail
+servers behind a proxy.
+
+@item @code{https-proxy} (default @code{"socks5://localhost:8971"})
+A string specifying the proxy that hydroxide will use, when applicable
+per the provision of the @code{https-proxy?} field. The proxy is set
+using this string by exporting it as the value of an @code{https_proxy}
+variable into @command{hydroxide}'s environment.
+
+@item @code{imap?} (default @code{#t})
+A boolean value. Whether hydroxide should listen to IMAP protocol
+requests from the loopback interface.
+
+@item @code{smtp?} (default @code{#t})
+A boolean value. Whether hydroxide should listen to IMAP protocol
+requests from the loopback interface.
+
+@item @code{carddav?} (default @code{#t})
+A boolean value. Whether hydroxide should listen to IMAP protocol
+requests from the loopback interface.
+
+@item @code{%auto-start?} (default @code{#t})
+A boolean value. Whether the service should be started automatically
+when its superior starts.
+
+@end table
+
+@end deftp
+
+@node Configuration examples (whispers mail), , Configuring the mail hierarchy and services, The mail hierarchy
+@subsection Configuration examples (whispers mail)
+
+With this example hierarchy, an hydroxide service is extended for the
+user named joe-chip, allowing the programs on localhost to access the
+Proton mail servers on localhost through the SMTP and IMAP protocols,
+but not carddav.
+
+Hydroxide contacts the Proton mail servers through a SOCKSv5 proxy
+exposed on localhost port 7777. The @code{whispers-mail-service-type}
+does not take care of extending this proxy automatically, it can be done
+for example using a service of type @code{whispers-ssh-service-type},
+@pxref{The ssh hierarchy}.
+
+The hierarchy cannot take care of initially authenticating hydroxide to
+the Proton mail servers, and provides no facility to authenticate the
+user to the hydroxide servers on localhost.
+
+@cindex mail, example
+@lisp
+(service whispers-mail-service-type
+ (whispers-mail-configuration
+ (users-groups-services
+ (list
+ (mail-user-group-services
+ (services
+ (mail-services-configuration (hydroxide? #t)
+ (hydroxide-service
+ (hydroxide-service-configuration
+ (https-proxy? #t)
+ (https-proxy "socks5://localhost:7777")
+ (carddav? #f)))))
+ (user-and-group
+ (whispers-user-group (user "joe-chip")
+ (group "users"))))))))
+@end lisp
+
+@node The ssh hierarchy, The vpn hierarchy, The mail hierarchy, Whispers services
+@section The ssh hierarchy
+
+The facilities in the @code{whispers services whispers ssh} module
+provide ssh-related features to a system and its users:
+
+@table @code
+
+@item ssh forwarding
+A wrapper around the @code{whispers services ssh-tunneler} module,
+providing services for permanent ssh dynamic, tunnel, port and reverse
+port forwardings, including proxying them and re-enabling and restarting
+them through cron jobs in case their connection drops,
+@xref{Top,,,ssh-tunneler,SSH Tunneler Reference Manual}. While not as
+general as the baseline ssh tunneler Guix service, configuration through
+whispers is probably simpler in some aspects.
+
+@item ssh agent
+Run any of the system's users ssh agent as a permanent service in
+whispers, including automatically adding user-configured keys into the
+agent.
+
+@end table
+
+@menu
+* Configuring the ssh hierarchy and services::
+* Configuration example (whispers ssh)::
+@end menu
+
+@node Configuring the ssh hierarchy and services, Configuration example (whispers ssh), The ssh hierarchy, The ssh hierarchy
+@subsection Configuring the ssh hierarchy and services
+
+@defvar whispers-ssh-service-type
+This is the type for the service extending whispers with a ssh hierarchy
+and its associated services. Its value must be a
+@code{whispers-ssh-configuration} record.
+
+@end defvar
+
+@deftp {Data Type} whispers-ssh-configuration
+
+@table @asis
+
+@item @code{ssh-package} (default @code{openssh})
+A file-like object. The ssh package to use.
+
+@item @code{users-groups-keys-forwards} (default @code{()})
+A list of @code{ssh-user-group-keys-forwards} records configuring the
+ssh hierarchy and its services, containing one member for each user
+making use of the hierarchy, be they root or unprivileged users.
+
+@end table
+
+@end deftp
+
+A record of type @code{ssh-user-group-keys-forwards} configures the
+hierarchy and its services for a single user of the system.
+
+@deftp {Data Type} ssh-user-group-keys-forwards
+
+@table @asis
+
+@item @code{user-and-group} (default @code{(whispers-user-group)})
+A record of the @code{whispers-user-group} type, @xref{Unprivileged
+services}. Its default is the record type's default record.
+
+@item @code{agent?} (default @code{#t})
+A boolean value. Whether to extend an ssh agent as a service for this
+user in the hierarchy.
+
+@item @code{keys} (default @code{()})
+A list of strings. Paths to ssh keys to load into the agent
+automatically.
+
+@item @code{tunneler?} (default @code{#f})
+A boolean value. Whether to extend ssh tunneling/forwarding as a service
+for this user in the hierarchy.
+
+@item @code{forwardings} (default @code{()})
+A list of of records of the @code{whispers-forwarding} type. Each member
+of the list configures one ssh connection with forwarding(s).
+
+@end table
+
+@end deftp
+
+A record of type @code{whispers-forwarding} configures a service which
+daemonizes a single ssh connection.
+
+@deftp {Data Type} whispers-forwarding
+
+@table @asis
+
+@item @code{forwards} (default @code{()})
+A list of records of type @code{ssh-forward-configuration}, @xref{Client
+system configuration,,,ssh-tunneler,SSH Tunneler Reference Manual}. Each
+member of this list configures one forwarding of the connection.
+
+@item @code{name-prefix} (default @code{"ssh-forwards"})
+A string used to name the service. This gets cast into a symbol forming
+part or all of the shepherd provision for the service.
+
+@item @code{suffix-name?} (default @code{#t})
+A boolean value. Whether to add a computed suffix that describes the
+forwardings to @code{stealth-name-prefix}.
+
+@item @code{use-agent?} (default @code{#t})
+A boolean value. Whether the connection should use the keys loaded into
+a running ssh agent.
+
+@item @code{clear-password?} (default @code{#f})
+A boolean value. Whether to wrap the connection in
+@command{sshpass}. This is strictly discouraged for security and privacy
+in general, and this should probably @emph{never} be used on a
+multi-user computer. Toggling this field in a system configuration is
+even worse than using @command{sshpass} directly from command-line, see
+the @code{clear-password} field documentation for why.
+
+@item @code{clear-password} (default @code{""})
+A string. The password that @command{sshpass} will use, when configured
+to do so. Be advised that this password goes into the Guix store in
+clear-text.
+
+@item @code{sshd-user} (default @code{"root"})
+A string. The user for ssh to connect as on the @code{sshd-host}.
+
+@item @code{sshd-host} (default @code{"127.0.0.1"})
+A string. The sshd host to connect to.
+
+@item @code{sshd-port} (default @code{22})
+An integer. The port used to connect to the sshd on @code{sshd-host}.
+
+@item @code{strict-check} (default @code{"yes"})
+A string. Whether ssh will perform strict key checking of the presented
+host keys when connecting.
+
+@item @code{known-hosts-files} (default @code{("~/.ssh/known_hosts" "~/.ssh/known_hosts2")})
+A list of strings. Files where ssh will look for known hosts in order to
+perform its host key checking.
+
+@item @code{server-alive-interval} (default @code{30})
+An integer, which is passed as the value for the corresponding options
+of @command{ssh}.
+
+@item @code{server-alive-count-max} (default @code{6})
+An integer, which is passed as the value for the corresponding options
+of @command{ssh}.
+
+@item @code{resurrect?} (default @code{#t})
+A boolean value. Whether the superior shepherd of the connection service
+should perform a @code{resurrect} action on the service through an
+extended @command{mcron} job, @pxref{Shepherd actions,,,ssh-tunneler,SSH
+Tunneler Reference Manual}.
+
+@item @code{resurrect-time-spec} (default @code{''(next-minute '(47))})
+A quoted cron time job specification, @pxref{Guile
+Syntax,,,mcron,mcron}, defining the time at which the service and, when
+applicable, its proxy service are resurrected if stopped or disabled,
+when configured to do so through the @code{resurrect?} field of this
+record.
+
+@item @code{force-resurrect?} (default @code{#t})
+A boolean value. Whether the superior shepherd of the connection service
+should perform a @code{force-resurrect} action on the service through an
+extended @command{mcron} job, @pxref{Shepherd actions,,,ssh-tunneler,SSH
+Tunneler Reference Manual}.
+
+@item @code{force-resurrect-time-spec} (default @code{''(next-hour '(3))})
+A quoted cron time job specification, @pxref{Guile
+Syntax,,,mcron,mcron}, defining the time at which the service and, when
+applicable, its proxy service are force-resurrected, when configured to
+do so through the @code{force-resurrect?} field of this record.
+
+@item @code{timeout} (default @code{5})
+An integer. The timeout in seconds for starting the service.
+
+@item @code{stealth?} (default @code{#t})
+A boolean value. Whether to extend a second ssh connection as a proxy,
+for stealth and/or to avoid detection of tunnel forwardings by packet
+scanning from hostile firewalls. This connection used for proxying opens
+a dynamic forward to a proxy of your choice, through a dedicated
+lieutenant service of type @code{persistent-ssh-service-type}
+(@pxref{Client system configuration,,,ssh-tunneler,SSH Tunneler
+Reference Manual}) and is also configured by fields of this record (see
+below).
+
+@item @code{stealth-name-prefix} (default @code{"ssh-forwards"})
+A string used to name the stealth service. This gets cast into a symbol
+forming part or all of the shepherd provision for this service.
+
+@item @code{stealth-suffix-name?} (default @code{#t})
+A boolean value. Whether to add a computed suffix that describes the
+forwarding used for proxying to @code{stealth-name-prefix}.
+
+@item @code{stealth-use-agent?} (default @code{#t})
+A boolean value. Whether the proxy connection should use the keys loaded
+into a running ssh agent, when the @code{stealth?}
+field of this record is toggled.
+
+@item @code{stealth-clear-password?} (default @code{#f})
+A boolean value. Whether to wrap the proxy connection in
+@command{sshpass}. This is strictly discouraged for security and privacy
+in general, and this should probably @emph{never} be used on a
+multi-user computer. Toggling this field in a system configuration is
+even worse than using @command{sshpass} directly from command-line, see
+the @code{stealth-clear-password} field documentation for why.
+
+@item @code{stealth-clear-password} (default @code{""})
+A string. The password that @command{sshpass} will use, when the
+@code{stealth?} field of this record is toggled and configured to do
+so. Be advised that this password goes into the Guix store in
+clear-text.
+
+@item @code{stealth-sshd-user} (default @code{"root"})
+A string. The user for ssh to connect as on the @code{stealth
+sshd-host}, when the @code{stealth?} field of this record is toggled.
+
+@item @code{stealth-sshd-host} (default @code{"127.0.0.1"})
+A string. The sshd host to connect to for the proxy connection, when the
+@code{stealth?} field of this record is toggled.
+
+@item @code{stealth-sshd-port} (default @code{22})
+An integer. The port used to connect to the sshd on @code{sshd-host},
+when the @code{stealth?} field of this record is toggled.
+
+@item @code{stealth-strict-check} (default @code{"yes"})
+A string. Whether ssh will perform strict key checking of the presented
+host keys when connecting the proxy connection, when the @code{stealth?}
+field of this record is toggled.
+
+@item @code{stealth-known-hosts-files} (default @code{("~/.ssh/known_hosts" "~/.ssh/known_hosts2")})
+A list of strings. Files where ssh will look for known hosts in order to
+perform its host key checking when establishing the proxy connection,
+when the @code{stealth?} field of this record is toggled.
+
+@item @code{stealth-server-alive-interval} (default @code{30})
+An integer, which is passed as the value for the corresponding options
+of @command{ssh} for the proxy connection, when the @code{stealth?}
+field of this record is toggled.
+
+@item @code{stealth-server-alive-count-max} (default @code{6})
+An integer, which is passed as the value for the corresponding options
+of @command{ssh} for the proxy connection, when the @code{stealth?}
+field of this record is toggled.
+
+@item @code{stealth-timeout} (default @code{5})
+An integer. The timeout in seconds for starting the proxy connection
+service, when the @code{stealth?} field of this record is toggled.
+
+@item @code{stealth-proxy-port} (default @code{8585})
+An integer. The port that the proxy connection exposes on localhost as
+part of the dynamic forward to @code{stealth-sshd-host}, when the
+@code{stealth?} field of this record is toggled. In this case, The
+baseline connection service's command is extended in such a way that it
+auto-magically uses this port of localhost to proxy its own connection.
+
+@item @code{%auto-start?} (default @code{#t)})
+A boolean value. Whether the service and, when the @code{stealth?}
+field of this record is toggled, its proxying service should be
+automatically started by their superior shepherd when it starts.
+
+@end table
+
+@end deftp
+
+@node Configuration example (whispers ssh), , Configuring the ssh hierarchy and services, The ssh hierarchy
+@subsection Configuration examples (whispers ssh)
+
+The hierarchy configured below extends and uses an ssh agent which loads
+a rsa key in a default location, extends and uses a persistent ssh
+connection exposing the host at ip "5.6.7.8" as a socks5 proxy available
+on localhost port 3333, and extends a persistent ssh connection to host
+at ip "1.2.3.4" through the aforementioned proxy which creates one port
+forward and three reverse port forwards.
+
+If their superior is running, the ssh connection and its proxy ssh
+connection get resurrected (if necessary) and force-resurrected (always)
+at periodic times defined by the @code{resurrect-time-spec} and
+@code{force-resurrect-time-spec} quoted cron time job specifications,
+@pxref{Guile Syntax,,,mcron,mcron}.
+
+As for the extended port and reverse port forwardings, in this specific
+example, most presumably, the sshd of the host at ip "1.2.3.4" and of
+the client extending the hierarchy are made mutually available to each
+other on their port 2222, and the 2 other extended reverse forwardings
+can be useful to the BTC and XMR node services of the @code{finance}
+hierarchy, @pxref{Configuration examples (whispers finance)}.
+
+The tree of tmpfs extended by this hierarchy has 2 extremities, located
+at @code{/run/whispers/ssh/root-user/tunneler} and
+@code{/run/whispers/ssh/root-user/ssh-agent}, @pxref{Purpose}. As an
+example, the command @command{whispers -l /ssh/root-user restart
+tunneler} will - by default, and in this example - trigger restarting
+the 2 extended persistent ssh connections, without touching the ssh
+agent service, @pxref{The whispers command}.
+
+@cindex ssh forwarding, example
+@lisp
+(service
+ whispers-ssh-service-type
+ (whispers-ssh-configuration
+ (users-groups-keys-forwards
+ (list
+ (ssh-user-group-keys-forwards
+ (user-and-group (whispers-user-group (user "root")
+ (group "root")))
+ (keys '("/root/.ssh/id_rsa"))
+ (tunneler? #t)
+ (forwardings
+ (list
+ (whispers-forwarding
+ (forwards
+ (list
+ (port-forward-configuration
+ (entry-port 2222)) ;; from port 2222 to default exit port 22
+ (reverse-port-forward-configuration
+ (entry-port 2222)) ;; from port 2222 to default exit port 22
+ (reverse-port-forward-configuration
+ (entry-port 8333) ;; for bitcoin node, firewall bypassing
+ (exit-port 8333)) ;;
+ (reverse-port-forward-configuration
+ (entry-port 18080) ;; for monero node, firewall bypassing
+ (exit-port 18080)))) ;;
+ (sshd-host "1.2.3.4")
+ (resurrect? #t)
+ (resurrect-time-spec ''(next-minute '(32)))
+ (force-resurrect? #t)
+ (force-resurrect-time-spec
+ ''(next-minute-from (next-hour '(2)) '(41)))
+ (stealth? #t)
+ (stealth-sshd-host "5.6.7.8")
+ (stealth-proxy-port 3333)))))))))
+@end lisp
+
+@node The vpn hierarchy, The xdg hierarchy, The ssh hierarchy, Whispers services
+@section The vpn hierachy
+
+This section aims to provide VPN function as a set of shepherd services
+in the whispers tree. At the time of writing, it is entirely
+experimental at this stage and nothing more than proof of concept.
+
+Do not try to use the Whispers VPN, since it is probably insecure and it
+will leave your computer's network in inconsistent states whenever a
+network drop occurs.
+
+For demonstration and debugging purposes only, the
+@command{whispers-vpn-tests} command from the @code{whispers-tests}
+package deploys a network of virtual machines and deploys a VPN between
+them.
+
+@node The xdg hierarchy, Unprivileged services, The vpn hierarchy, Whispers services
+@section The xdg hierarchy
+
+This hierarchy actually only extends shepherd processes and their
+associated directories. It simply aims to provide a tmpfs file system
+for storing temporary files in the @code{XDG_RUNTIME_DIR} directory.
+
+There seem to be some problems with the current approach. Sometimes the
+tmpfs file systems of whispers do not unmount to empty directories when
+whispers is stopped, even when X is not running. Some X applications
+complain about the runtime directory permissions.
+
+@node Unprivileged services, , The xdg hierarchy, Whispers services
+@section Unprivileged services
+
+@code{whispers-user-group} guix records are used to configure whispers
+services running as normal users:
+
+@deftp {Data Type} whispers-user-group
+
+@table @asis
+
+@item @code{user} (default @code{"johndoe"})
+A string. A user name.
+
+@item @code{group} (default @code{"loner"})
+A string. A group name.
+
+@end table
+
+@end deftp
+
+@node The whispers command, Caveats, Whispers services, Top
+@chapter The whispers command
+
+The whispers command is a simple convenience wrapper around the herd
+program, @xref{Invoking herd,,,shepherd,The GNU Shepherd
+Manual}. Instead of specifying a file path to the listening socket of a
+running shepherd in the whispers tree, the user simply provides its
+absolute whispers tree path as an argument to the @command{--lieutenant}
+option of this command.
+
+@lisp
+
+Usage: whispers [--help-herd]
+ [--usage-herd]
+ [--vers-herd]
+ [-l LIEUTENANT-PATH ACTION [SERVICE [ARG...]]]
+
+@end lisp
+
+The @command{-l} option of the @command{whispers} command takes an
+arbitrary number of positional parameters:
+
+@table @command
+
+@item LIEUTENANT-PATH
+Absolute path to a shepherd lieutenant in the whispers tree. Must start
+with a slash character.
+
+@item ACTION
+The shepherd service action to perform.
+
+@item SERVICE
+The shepherd service of which the ACTION is to be performed.
+
+@item ARG...
+Arguments passed to the procedure of the shepherd action.
+
+@end table
+
+If the @command{--lieutenant} switch and its @command{LIEUTENANT-PATH}
+argument are omitted, and if no other valid command-line options is
+given, an action is performed on a service of the shepherd at the root
+of the whispers tree, which is itself a child process of the root
+shepherd PID 1 handled as one of its services. As such, using
+@command{whispers -l / ACTION [SERVICE [ARG...]]} or @command{whispers
+ACTION [SERVICE [ARG...]]} have exactly the same effect.
+
+Command-line options of the @command{whispers} trigger the following
+effects:
+
+@table @command
+
+@item --help
+Display the help message of the @command{whispers} command.
+
+@item --help-herd
+Display the help message of the @command{herd} command.
+
+@item --lieutenant=@var{LIEUTENANT-PATH}
+@itemx -l @var{LIEUTENANT-PATH}
+Absolute path to a shepherd lieutenant in the whispers tree. Must start
+with a slash character.
+
+@item --usage-herd
+Display the short usage message of the @command{herd} command.
+
+@item --vers-herd
+Display the @command{herd} version.
+
+@end table
+
+A few examples of the @command{whispers} command usage are given below:
+
+@table @command
+
+@item whispers status
+Prints the short status of all services handled by the shepherd at the
+top of the hierarchy.
+
+@item whispers -l /ssh/root-user/tunneler status
+Prints the short status of persistent ssh connections running as root
+within the ssh hierarchy, @xref{The ssh hierarchy}.
+
+@item whispers -l /ssh/root-user/restart tunneler
+Restarts the shepherd service for the shepherd process which daemonizes
+the persistent connections of root. The persistent ssh connections
+themselves will be restarted if the @code{%auto-start?} switch is
+toggled in @code{whispers-forwarding} record populating the
+@code{whispers-ssh-configuration} record value of the Guix service of
+type @code{whispers-ssh-service-type}, in the system configuration.
+
+@end table
+
+@node Caveats, Bugs, The whispers command, Top
+@chapter Caveats
+
+When re-configuring the whole Guix system, whispers services or whispers
+itself are not automatically restarted if their configuration has been
+updated.
+
+In order to run whispers service with an updated configuration after
+reconfiguring the Guix system, it is necessary to restart all of the
+whispers process tree from PID 1, using for example @command{herd
+restart whispers}. Re-starting services lower in the tree, such as with
+the @command{whispers} command will not run them according to their
+updated configuration.
+
+@node Bugs, GNU Free Documentation License, Caveats, Top
+@chapter Bugs
+
+Log rotation is not working in @code{/var/log/whispers}. As of writing,
+the cause of this bug is unknown.
+
+@node GNU Free Documentation License, Concept Index, Bugs, Top
+@appendix GNU Free Documentation License
+@cindex license, GNU Free Documentation License
+@include fdl-1.3.texi
+
+@node Concept Index, Programming Index, GNU Free Documentation License, Top
+@unnumbered Concept Index
+@printindex cp
+
+@node Programming Index, , Concept Index, Top
+@unnumbered Programming Index
+@syncodeindex tp fn
+@syncodeindex vr fn
+@printindex fn
+
+@bye