\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename ssh-tunneler.info @documentencoding UTF-8 @settitle SSH Tunneler 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{} 2023 Runciter @* 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 * SSH tunneler: (ssh-tunneler). Daemonized SSH forwardings for GNU Guix @end direntry @titlepage @title SSH Tunneler Reference Manual @subtitle Daemonized SSH Forwardings for GNU Guix @author Runciter @page @vskip 0pt plus 1filll Edition @value{EDITION} @* @value{UPDATED} @* @insertcopying @end titlepage @contents @c ********************************************************************* @node Top @top SSH Tunneler This document describes SSH Tunneler version @value{VERSION}, a ssh forwarding service written for GNU Guix. @insertcopying The @code{(whispers packages ssh-tunneler)} module provides Guix services extending a root or home shepherd with daemonized client ssh connections establishing all types of ssh forwardings: @table @code @cindex port forwarding @item Port forwarding Port forwardings, which can be established using the @command{-L} switch of the ssh command, forward connections to a port or socket of the ssh client to a port or socket of the sshd, or to a port of another remote host whose port becomes reachable through client host's port, transported through the sshd host. @cindex reverse port forwarding @item Reverse port forwarding Reverse port forwardings, which can be established using the @command{-R} switch of the ssh command, forward connections to a port or socket of the sshd to a port or socket of the ssh client, or to a port of another remote host whose port becomes reachable through the sshd host's port, transported through the client host. @cindex dynamic forwarding @item Dynamic forwarding Dynamic forwardings, which can be established using the @command{-D} switch of the ssh command, expose the sshd as a SOCKS proxy that a network program which supports this type of proxying can reach through a port of the ssh client. @cindex TUN device forwarding @item TUN device forwarding Tun device forwardings, a.k.a. ``ssh tunnels'' in the vernacular, which can be established using the @command{-w} switch of the ssh command, create a TUN software network device on the ssh client and another such device on the sshd, such that all network packets routed through either of these TUN device are encrypted and can be de-encrypted by the TUN device on the other end of the tunnel, should they be transported there through other (ultimately physical) network devices. @end table @menu * Purpose:: * Configuration:: * Shepherd actions:: * GNU Free Documentation License:: * Concept Index:: * Programming Index:: @detailmenu --- The Detailed Node Listing --- Configuration * Client system configuration:: * Host key troubleshooting:: * sshd configuration:: * Configuration examples:: Configuration examples * Port forwarding example:: * Remote shell access:: * Resurrected remote shell access:: * Dynamic forwarding to a SOCKS v5 proxy:: * Clear password authentication:: * ssh tunnel for a VPN:: * Proxyed ssh tunnel for a stealth VPN:: @end detailmenu @end menu @c ********************************************************************* @node Purpose @chapter Purpose Apart from the proverbial ease with which its adepts are empowered to work-around the firewalls of their place of employment, ssh forwarding has several other useful applications, non-exhaustively listed here. The services that the @code{(whispers packages ssh-tunneler)} module extends are an attempt to make these available to Guix users, easily configurable, robustly daemonized, and when needed in their most unstoppable form. @table @code @cindex remote shell access @item Remote shell access Through reverse port forwarding, the sshd of a home computer stuck behind a dynamic IP router can be made permanently available through a chosen port of a VPS. On the shepherd side, ssh-tunneler provides features to @command{resurrect} the reverse forwarding in case the connection to the VPS is unreliable. @xref{Remote shell access} and @ref{Resurrected remote shell access} for example configurations. @cindex censorship-resistant web browsing @item Censorship-resistant web browsing Many web browsers support SOCKS v4 or v5 proxies. Any sshd can act as such a proxy, nearly out-of-the-box (@pxref{sshd configuration}). The ssh-tunneler module can be used to turn a remote sshd into a SOCKS proxy reachable through a chosen port of localhost. The proxy host can be a VPS with a sshd under the user's full control, or a server from a company offering a simple commercial SOCKS proxying service. When the proxy host is located outside the area where a local censorship IP blacklist is enforced, such censorship is effectively nullified for purpose of web browsing. At the time of writing, proxy hosts reached exclusively in this way seem to be immune to detection by advanced packet-scanning techniques... or at the very least, spared from automatic blacklisting. @xref{Dynamic forwarding to a SOCKS v5 proxy} for an example configuration. @cindex VPN @item VPN When augmented with appropriate network addressing, routing and @code{iptables} stances on the client and server side, ssh tunnels can support the operation of a VPN. At the time of writing, such augmentations probably have to be setup by the user manually or using shell scripts, since the ssh-tunneler module only supports the creation of the ssh tunnel proper. @xref{ssh tunnel for a VPN} for an example configuration of a service extending a ssh tunnel. There are plans in the works to create other services that will enable a set of computers all running Guix to unite into a small dynamically addressed VPN. @cindex stealth VPN @item Stealth VPN It is possible, albeit in a pretty hackish way, to establish a ssh tunnel through an intermediate SOCKS proxy. At the time of writing, similar to what is mentioned above, when the proxy host is located outside an area where packets are being scanned for VPN connection signatures, this method protects the VPN server host and the proxy host from being blacklisted. The ssh-tunneler module supports the establishment of such ``stealth'' tunnels through a SOCKS proxy. @xref{Proxyed ssh tunnel for a stealth VPN} for an example configuration. @end table @c ********************************************************************* @node Configuration @chapter Configuration @c ********************************************************************* @menu * Client system configuration:: * Host key troubleshooting:: * sshd configuration:: * Configuration examples:: @end menu @node Client system configuration @section Client system configuration In order to establish the persistent forwardings, the client has to extend a service (@pxref{Services,,, guix, GNU Guix}) from its system configuration file (@pxref{Using the Configuration System,,, guix, GNU Guix}). @defvar persistent-ssh-service-type This is the type for the service extending the shepherd with a daemonized ssh connection. Its value must be an @code{ssh-connection-configuration} record. @end defvar @deftp {Data Type} ssh-connection-configuration This is the configuration record for a ssh connection daemonized by the shepherd. @table @asis @item @code{shepherd-package} (default @code{shepherd}) A file-like object. The shepherd package to use. @item @code{ssh-package} (default @code{openssh}) A file-like object. The openssh package to use. @item @code{netcat-package} (default @code{netcat-openbsd})) A file-like object. The netcat-openbsd package to use. @item @code{sshpass-package} (default @code{sshpass}) A file-like object. The sshpass package to use. @item @code{ineutils-package} (default @code{inetutils}) A file-like object. The inetutils package to use. @item @code{procps-package} (default @code{procps}) A file-like object. The procps package to use. @item @code{socks-proxy-config} (default @code{(socks-proxy-configuration)}) A guix record of type @code{socks-proxy-configuration}, configuring proxying of the connection opened by the service. See below for the record's documentation. @item @code{id-rsa-file?} (default @code{#t}) A boolean value. Whether to authenticate to the sshd from a private key loaded from a file. @item @code{id-rsa-file} (default @code{"/root/.ssh/id_rsa"}) A string. When configured to do so, the path to the private key file to load in order to authenticate to the sshd. @item @code{clear-password?} (default @code{#f}) A boolean value. Whether to authenticate to the sshd with a clear password. Setting this field to @code{#t} is not recommended for security, especially on a multi-user machine, among other concerns because a password will be written into the Guix store in clear text. @item @code{sshd-user-password} (default @code{"none"}) A string. When configured to do so, the clear text password to use to authenticate the connection. About security, see the reservations above. @item @code{sshd-user} (default @code{"root"}) A string, the UNIX handle of the user to authenticate as on the sshd. @item @code{sshd-host} (default @code{"127.0.0.1"}) A string defining an IP address. The IP of the sshd to connect to. @item @code{sshd-port} (default @code{22}) An integer. The port used to connect to the sshd. @item @code{gateway-ports?} (default @code{#t}) A boolean value. Whether to activate the GatewayPorts switch @emph{on the client side}. This is the @emph{ssh_config} GatewayPorts, @emph{not} the @emph{sshd_config} GatewayPorts. @item @code{known-hosts-files} (default @code{("~/.ssh/known_hosts" ~/.ssh/known_hosts2)}) A list of strings, configuring the list of files checked for known host keys of the configured @code{sshd-host} by setting the UserKnownHostsFiles option of @command{ssh}. The default, which reproduces @command{ssh}'s default configuration at the time of writing, might cause an otherwise correctly configured service to fail its start action. @xref{Host key troubleshooting}. @item @code{strict-check} (default @code{"yes"}) A string, configuring the value of the StrictHostKeyChecking configuration option of ssh. The default is changed from @command{ssh}'s default value of @code{"ask"} because it is not possible to answer interactive prompts while starting a Shepherd service. A conservative default value is used for security reasons, which might cause an otherwise correctly configured service to fail its start action. @xref{Host key troubleshooting}. @item @code{server-alive-interval} (default @code{30})) An integer. The value assigned to the ServerAliveInterval @command{ssh} configuration option of the connection. @item @code{server-alive-count-max} (default @code{6})) An integer. The value assigned to the ServerAliveCountMax @command{ssh} configuration option of the connection. @item @code{name-prefix} (default @code{"ssh-forwards"}) A string. The prefix of the service provision of the shepherd service supporting the connection. To this prefix will be by default appended a suffix computed from the characteristics of the forwarding(s) configured for the connection, and its proxy, if any. The resulting string will be converted to a symbol. @item @code{suffix-name?} (default @code{#t}) A boolean value. Whether to append an automatically computed suffix to the shepherd provision of the service supporting the connection. @item @code{special-options} (default @code{'()}) A list of strings. A list of options to add to the ssh command of the connection. @item @code{forwards} (default @code{'()}) A list of @code{ssh-forward-configuration} records. @item @code{exit-forward-failure?} (default @code{#t})) A boolean value. Whether to active the ExitOnForwardFailure ssh configuration switch for the connection. @item @code{connection-attempts} (default @code{1})) An integer. the value assigned to to the ConnectionAttempts ssh configuration switch of the connection. @item @code{local-command?} A boolean value. Its default is computed at system reconfiguration time. Whether to execute a command locally on the client after successfully creating the forwardings of the connection. If the shepherd service uses a PID file, which is the default, setting this options to @code{#f} will prevent the service from starting successfully. @item @code{extra-local-commands} (default @code{'()}) A list of strings. A list of commands to execute locally on the client after successfully creating the forwardings of the connection and starting the shepherd service. @item @code{require-networking?} (default @code{#t}) A boolean value. Whether the @code{networking} service should be included in the requirements of the shepherd service of the connection. @item @code{extra-requires} (default @code{'()}) A list of symbols. A list of extra requirements for the shepherd service of the connection. @item @code{elogind?} (default @code{#f}) A boolean value. @item @code{pid-file?} (default @code{#t}) A boolean value. Whether the shepherd should use a PID file for the service of the connection. @item @code{pid-folder-override?} (default @code{#f}) A boolean value. Whether to override the shepherd's global default for the folder of the PID file of the service. @item @code{pid-folder-override} (default @code{"/var/run"}) A string. When configured to override the shepherd's global default, the path to the folder where to store the PID file of the service. @item @code{timeout-override?} (default @code{#f}) A boolean value. Whether to override the shepherd's global default for the timeout of the service startup. @item @code{timeout-override} (default @code{5}) An integer. When configured to override the shepherd's global default, the timeout of the service startup. @item @code{dedicated-log-file?} (default @code{#f}) A boolean value. Whether the service should log to a dedicated file. @item @code{log-rotate?} (default @code{#f}) A boolean value. Whether the dedicated log file of the service should be rotated by @command{rottlog}. This is an experimental feature. @item @code{log-folder-override?} (default @code{#f}) A boolean value. Whether to override the shepherd's global default for the log folder of the service. @item @code{log-folder-override} (default @code{"/var/run"}) A string. When configured to override the shepherd's global default, the folder where to store the log file of the service. @item @code{verbosity} (default @code{0}) An integer between 0 and 3, both included. The verbosity level of the ssh command of the connection, equal to the number of times the @command{-v} switch of ssh is used. @item @code{command?} (default @code{#f}) A boolean value. Whether to execute a command on the sshd host after successfully creating the forwardings of the connection. @item @code{command} (default @code{'()}) A string. When configured to do so, the command to be executed on the sshd after successfully establishing the forwardings of the connection. @item @code{resurrect-time-spec} (default @code{''(next-minute '(47))}) A quoted cron job time specification, for which the author would like to extend his most sincere apologies to the user. See the default value for an example of this field's format. The quoted time specification of the cron job extended to @command{resurrect} the service, when configured to do so. @pxref{Shepherd actions}. @item @code{flat-resurrect?} (default @code{#f}) A boolean value. Whether to @emph{not} recursively @command{resurrect} the service. @item @code{force-resurrect-time-spec} (default @code{''(next-hour '(3))}) A quoted cron job time specification. Apologies repeated. The quoted time specification of the cron job extended to @command{force-resurrect} the service, when configured to do so. @pxref{Shepherd actions}. @item @code{flat-force-resurrect?} (default @code{#f}) A boolean value. Whether to @emph{not} recursively @command{force-resurrect} the service. @item @code{%cron-resurrect?} (default @code{#f}) A boolean value. Whether to automatically @command{resurrect} the service by means of a cron job. @item @code{%cron-force-resurrect?} (default @code{#f}) A boolean value. Whether to automatically @command{force-resurrect} the service by means of a cron job. @item @code{%auto-start?} (default @code{#f}) A boolean value. Whether to automatically start the service on boot. This feature is experimental, and unreliable. @end table @end deftp @deftp {Data Type} ssh-forward-configuration This is the configuration record for one of the forwardings provided by a daemonized ssh connection. @table @asis @item @code{forward-type} (default @code{'dynamic}) A symbol which can be @code{'dynamic}, @code{'port}, @code{'reverse-port} or @code{'tunnel}. @item @code{entry-type} (default @code{'port}) A symbol which can be @code{'preset} or @code{'any} when the @code{'forward-type} field is @code{'tunnel}, and which can be @code{'port} or @code{'socket} otherwise. It is ignored when the @code{'forward-type} field is @code{'dynamic.} @item @code{exit-type} (default @code{'port}) A symbol which can be @code{'preset} or @code{'any} when the @code{forward-type} field is @code{'tunnel}, and which can be @code{'port} or @code{'socket} otherwise. It is ignored when the @code{forward-type} field is @code{'dynamic}. @item @code{entry-port} (default @code{8971}) An integer. When the @code{forward-type} is @code{'dynamic}, @code{'port} or @code{'reverse-port} and the @code{entry-type} is @code{'port}, the port to forward from at the entry of the forwarding. @item @code{exit-port} (default @code{22}) An integer. When the @code{forward-type} is @code{'port} or @code{'reverse-port} and the @code{exit-type} is @code{'port}, the port to forward to at the final destination of the forwarding. @item @code{entry-socket} (default @code{""})) A string. When the @code{forward-type} is @code{'port} or @code{'reverse-port} and the @code{entry-type} is @code{'socket}, the path to the socket file to forward from at the entry of the forwarding. This is an experimental feature. @item @code{exit-socket} (default @code{""}) A string. When the @code{forward-type} is @code{'port} or @code{'reverse-port} and the @code{exit-type} is @code{'socket}, the path to the socket file to forward to at the final destination of the forwarding. This is an experimental feature. @item @code{forward-host} (default @code{"127.0.0.1"}) A string representing an IP address. The final destination host of the forwarding, applicable when the @code{forward-type} is @code{'port} or @code{'reverse-port}. @item @code{entry-tun} (default @code{0}) An integer. When the @code{forward-type} is @code{'tunnel} and the @code{entry-type} is @code{'preset}, the TUN interface number (tunX) on the side of the client extending the service. @item @code{exit-tun} (default @code{0}))) An integer. When the @code{forward-type} is @code{'tunnel} and the @code{exit-type} is @code{'preset}, the TUN interface number (tunX) on the sshd side. @end table @end deftp @deftp {Data Type} socks-proxy-configuration This is the configuration record for the SOCKS proxy used by a daemonized ssh connection to connect to the sshd. @table @asis @item @code{use-proxy?} (default @code{#f}) A boolean value. Whether to establish the ssh connection configured by the parent record through a SOCKS proxy. For as much as the rest of this record's documentation may be confusing to the first-time reader (sorry), he might feel relieved to note that it is sufficient to set the value of this field to @code{#t} to proxy a single daemonized ssh connection through a default port of localhost. @item @code{extend?} A boolean value. Whether the ssh connection connection supporting the SOCKS proxy should be auto-magically extended as a shepherd service on whose provision the ssh connection configured by the parent record will depend. While, strictly speaking, the default of the @code{extend?} field is computed at Guix system-reconfiguration time, the default behavior is to auto-magically extend a shepherd service adequately configured to expose the proxy on localhost whenever the user configuring the Guix system has elected to use such a proxy through the @code{use-proxy?} field of this record. Overriding this default behavior is experimental, and can be achieved by explicitly setting the @code{extend?} field to @code{#f} in your system configuration. @item @code{port} An integer. Its default is computed at Guix system-reconfiguration time. Overriding this default is experimental. The port of localhost to use to connect to the SOCKS proxy. @item @code{dynamic-forward} A value which can be @code{#f}, or a Guix record returned by a call to @code{ssh-connection-configuration}. In the latter case, this field defines the configuration record for the service of type @code{persistent-ssh-service-type} that will extend the connection supporting the proxy for the connection configured by the parent record, if any. The value @code{#f} is probably always the most adequate when the connection extended by the parent record will not use a SOCKS proxy, and it does not need to be changed by the user. When the user configuring a the system extends a SOCKS proxy, he may optionally wish to change the value of the @code{dynamic-forward} field from its computed default, for example if he wants to use a non-default port, one requirement being that it must then be a configuration record for a connection creating a dynamic port forward as the first member of its list of @code{forwards}. @end table @end deftp For the user's convenience, macros are provided as helpers to instantiate @code{ssh-forward-configuration} records with sane defaults preset for the supported types of forwardings. Field values of the record @code{ssh-forward-configuration} returned by these macros can be changed from their defaults exactly as if instantiating a @code{ssh-forward-configuration} record directly. @defmac dynamic-forward-configuration @dots{} This macro (included for the sake of completeness) returns an @code{ssh-forward-configuration} record with sane defaults set to configure a dynamic port forwarding in the service. The defaults of fields are actually not changed from a direct call to @code{dynamic-forward-configuration}. @pxref{Dynamic forwarding to a SOCKS v5 proxy} for an example usage. @end defmac @defmac port-forward-configuration @dots{} This macro returns an @code{ssh-forward-configuration} record with sane defaults set to configure a port forwarding in the service. The default of the @code{forward-type} field of the returned record is changed to @code{'port}, and the default of the @code{entry-port} field of the record is chanted to @code{6947}. @xref{Port forwarding example} for an example usage. @end defmac @defmac reverse-port-forward-configuration @dots{} This macro returns an @code{ssh-forward-configuration} record with sane defaults set to configure a reverse port forwarding in the service. The default of the @code{forward-type} field of the returned record is changed to @code{'reverse-port}, and the default of the @code{entry-port} field of the record is chanted to @code{6283}. @xref{Remote shell access} for an example usage. @end defmac @defmac tunnel-forward-configuration @dots{} This macro returns an @code{ssh-forward-configuration} record with sane defaults set to configure a tunnel forwarding in the service. The default of the @code{forward-type} field of the returned record is changed to @code{'tunnel}, the default of the @code{entry-type} field of the record is chanted to @code{'any}, and the default of the @code{exit-type} field of the record is also changed to @code{'any} . @xref{ssh tunnel for a VPN} for an example usage. @end defmac @c ********************************************************************* @node Host key troubleshooting @section Host key troubleshooting For security reasons, mostly related to the prevention of man-in-the-middle attacks, @command{ssh} authenticates the sshd host through its host keys, and by default aborts or pauses establishing a connection when it is unable to verify host keys or when it verifies that a host key previously known to the client for this host has changed. Stemming from the same concerns, the services extended from this module have to implement slightly more conservative defaults than @command{ssh}. However, as a result, users might experience less-than-trivial failures to start the services extended from this module. If a user is certain that he is connecting to the intended host, but this host's key has changed or is currently unknown to the client @command{ssh} started by the Shepherd, the following configuration settings for the service should bypass any and all effects of host key verification by @command{ssh}: @cindex bypass host key checking @lisp (ssh-connection-configuration ... (strict-check "no") (known-hosts-files '("/dev/null")) ...) @end lisp The above can be tried for troubleshooting purposes. @c ********************************************************************* @node sshd configuration @section sshd configuration Any machine running a sshd can be the server for the connection, it doesn't need to be running Guix System. By default, the client extending the service will connect to the sshd as root. Depending on the specifics of your sshd host, you might wish to change that in order to improve security. You can do it by setting a non-default value for the @code{sshd-user} field of the @code{ssh-connection-configuration} record of the client service, and probably still enjoy functionality provided you do not want to extend a ssh tunnel or to reverse forward a priviledged port of the sshd. Configuring the sshd should be easy, there are 2 items to consider: @table @code @item Authentication The service extended by the client must authenticate its connection to the sshd. The recommended way is through public key authentication. To achieve it, the public key corresponding to the private key configured by the @code{ssh-connection-configuration} record of the service must be registered as authorized for the user of the sshd host that the connection authenticates as. In common situations (but see above), and with default values of the @code{id-rsa-file?}, @code{id-rsa-file} and @code{sshd-user} fields of the client's configuration record, you should be able to authenticate by adding the contents of the @code{/root/.ssh/id_rsa.pub} file of the client to the @code{/root/.ssh/authorized_keys} file of the sshd. Alternatively, when the sshd itself is also extended as a Guix service on the server host, Guix provides a nice facility to extend public key authorizations (@pxref{Networking Services,,, guix, GNU Guix}). @item GatewayPorts sshd option For most uses of the ssh-tunneler service, it should be either practical or necessary to set @code{GatewayPorts=yes} in the configuration of sshd, for example by adding this option switch to the @code{sshd_config} file. @end table @c ********************************************************************* @node Configuration examples @section Configuration examples This section provides a collection of client configuration examples for typical uses of the @code{(whispers packages ssh-tunneler)} module, including the applications described in @ref{Purpose}. Throughout this section, @code{1.2.3.4} is used as a placeholder for the IP address of the sshd host to which the client extending a forwarding service connects. @menu * Port forwarding example:: * Remote shell access:: * Resurrected remote shell access:: * Dynamic forwarding to a SOCKS v5 proxy:: * Clear password authentication:: * ssh tunnel for a VPN:: * Proxyed ssh tunnel for a stealth VPN:: @end menu @c ********************************************************************* @node Port forwarding example @subsection Port forwarding This example extends a port forwarding service which forwards the Guix client's port 1357 to the port 2468 of a third host, which the sshd at IP 1.2.3.4 reaches at IP 5.6.7.8. The daemonized ssh forwarding stance is @command{-L 1357:5.6.7.8:2468}. @cindex port forwarding, example @lisp (ssh-connection-configuration (sshd-user "joe-chip") ; "root" is the default (sshd-host "1.2.3.4") ; change to IP of sshd as string (forwards (list (port-forward-configuration (entry-port 1357) ; 6947 is the default (exit-host "5.6.7.8") ; default is the sshd's localhost (exit-port 2468)))))) ; 22 is the default @end lisp You can start the extended service with the following shell command as root: @example herd start ssh-forwards@@port,1357:5.6.7.8:2468 @end example @c ********************************************************************* @node Remote shell access @subsection Remote shell access This example extends a simple reverse port forwarding service, of the kind that can be used for remote shell access to the local machine, should this machine be firewalled or stuck behind a dynamic IP. The daemonized ssh forwarding stance is @command{-R 1357:localhost:22}. @cindex reverse port forwarding, example @cindex remote shell access, example @lisp (service persistent-ssh-service-type (ssh-connection-configuration (sshd-user "joe-chip") ; "root" is the default (sshd-host "1.2.3.4") ; change to IP of sshd as string (forwards (list (reverse-port-forward-configuration (entry-port 1357) ; 6283 is the default (exit-port 22)))))) ; 22 is the default @end lisp Note that if the port 1357 of the sshd is not priviledged, it is possible to extend a connection to the sshd as a non-root user, such as in this example. You can start the extended service with the following shell command as root: @example herd start ssh-forwards@@reverse-port,1357:localhost:22 @end example After setting @code{GatewayPorts=yes} on the sshd and starting the extended shepherd service on the client, you can start a remote shell session on the client through the sshd's IP on port 1357, for example by running this command to start a remote shell as the client's UNIX handle @code{pat-conley}: @example ssh -p 1357 pat-conley@@1.2.3.4 @end example @c ********************************************************************* @node Resurrected remote shell access @subsection Remote shell access This example defines exactly the same reverse port forwarding service as the previous one, @xref{Remote shell access}. As an added feature of the service, mcron jobs are extended to improve its robustness. Those are especially useful and perhaps @emph{necessary} if you cannot physically attend the machine which daemonizes the connection for prolonged periods of time. The daemonized ssh forwarding stance is @command{-R 1357:localhost:22}. @cindex resurrected reverse port forward, ex. @cindex resurrected remote shell access, ex. @lisp (service persistent-ssh-service-type (ssh-connection-configuration (sshd-user "joe-chip") ; "root" is the default (sshd-host "1.2.3.4") ; change to IP of sshd as string (%cron-resurrect? #t) ; #f is the default (resurrect-time-spec ''(next-minute '(38))) (%cron-force-resurrect? #t) ; #f is the default (force-resurrect-time-spec ''(next-hour '(3))) (forwards (list (reverse-port-forward-configuration (entry-port 1357) ; 6283 is the default (exit-port 22)))))) ; 22 is the default @end lisp You can start the extended service with the following shell command as root: @example herd start ssh-forwards@@reverse-port,1357:localhost:22 @end example In this example, the daemonized ssh connection is resurrected at the 38th minute of every hour and forcefully resurrected at 03:00AM every day. For the sake of the illustration's completeness, 2 mcron jobs are extended by the configured example service. If your situation makes resurrection desirable, you should probably @code{resurrect} your tunneler service(s) with a mcron job. If you have decided to @code{resurrect} a service, you should only then consider if you also want to @code{force-resurrect} this service by means of a second cron job. Forced resurrection can be useful in the event a long-running daemonized ssh connection has stopped providing its forwardings. Resurrecting a started service should be completely innocuous to the running service being resurrected and consume only a small amount of shepherd run-time. The author considers a frequency of once per hour for the mcron job of the @code{resurrect} action to be adequate. By contrast, in most situations, it is expected to be counter-productive to @code{force-resurrect} too frequently. The author recommends a maximum frequency of once a day for forced resurrection. In the event that you resurrect and/or forcefully resurrect multiple services, it might be (tbc) good practice to spread the times at which the mcron jobs are performed by a couple of minutes or more. @c ********************************************************************* @node Dynamic forwarding to a SOCKS v5 proxy @subsection Dynamic forwarding to a SOCKS v5 proxy This example extends a dynamic forwarding service, making the sshd host available as a SOCKS proxy. The daemonized ssh forwarding stance is @command{-D 1357}. @cindex dynamic forwarding, example @cindex SOCKS proxy, example @cindex censorship-resistant browsing, ex. @lisp (service persistent-ssh-service-type (ssh-connection-configuration (sshd-user "joe-chip") ; "root" is the default (sshd-host "1.2.3.4") ; change to IP of sshd as string (forwards (list (dynamic-forward-configuration (entry-port 1357)))))) ; 8971 is the default @end lisp You can start the extended service with the following shell command as root: @example herd start ssh-forwards@@dynamic,1357 @end example In graphical web browsers, proxy settings are generally accessible through a settings dialog. You would setup a proxy of type @code{SOCKS5} or @code{SOCKS v5} with proxy host @code{localhost} on port @code{1357}. For such a general web browsing use case, you definitely need @code{GatewayPorts=yes} to be set for the proxy sshd at 1.2.3.4, for example in its @code{sshd_config} file. @c ********************************************************************* @node Clear password authentication @subsection Clear password authentication This example defines exactly the same dynamic forwarding as the previous one, @xref{Dynamic forwarding to a SOCKS v5 proxy}. The difference is that authentication is achieved with a password extended in clear text from the Guix service's configuration record, and by wrapping the ssh command in a call to the @command{sshpass} program. This type of configuration might expose a clear password to other users of the machine, and is not recommended. In any case, it should be reserved for situations where key pair authentication is not available, and only when the extended clear password does not protect any confidential data. When the client extending the service is a multi-user machine, this is even worse security than merely using the sshpass program from command-line, because the clear-text password will end up in the Guix store. The daemonized ssh forwarding stance is @command{-D 1357}. @cindex clear password, example @lisp (service persistent-ssh-service-type (ssh-connection-configuration (sshd-user "joe-chip") ; "root" is the default (sshd-host "1.2.3.4") ; change to IP of sshd as string (clear-password? #t) ; what do you think you're doing? (sshd-user-password "12345") ; here's hoping yours is better (forwards (list (dynamic-forward-configuration (entry-port 1357)))))) ; 8971 is the default @end lisp You can start the extended service with the following shell command as root: @example herd start ssh-forwards@@dynamic,1357 @end example @c ********************************************************************* @node ssh tunnel for a VPN @subsection ssh tunnel for a VPN This example extends a ssh tunnel for purpose of supporting a connection to the sshd as a VPN server. The daemonized ssh forwarding stance is @command{-w any:any}. @cindex TUN device forwarding, example @cindex ssh tunnel, example @cindex VPN, example @lisp (service persistent-ssh-service-type (ssh-connection-configuration (sshd-user "root") ; "root" is the default (sshd-host "1.2.3.4") ; change to IP of sshd as string (forwards (list (tunnel-forward-configuration))))) @end lisp You can start the extended service with the following shell command as root: @example herd start ssh-forwards@@tunnel,any:any @end example @c ********************************************************************* @node Proxyed ssh tunnel for a stealth VPN @subsection Proxyed ssh tunnel for a stealth VPN This example extends a ssh tunnel through an inferior socks proxy of which it also extends the dynamic forward, for purpose of supporting a connection to the sshd as a ``stealth'' VPN server. Under the hood, the daemonized ssh connection uses the command @command{nc} from the program @code{netcat-openbsd} to direct packets of the connection to the dynamic forward providing access to the SOCKS proxy. This dirty hack is known to work at the time of writing. The ssh stance directing the connection to transmit through the proxy should be something like the following, with shell quoting added somewhat artificially for clarity to the human reader: @example -o ProxyCommand='/gnu/store/...-netcat-openbsd-x.x-x/bin/nc -X 5 -x localhost:1357 %h %p' @end example The daemonized ssh forwarding stance is @command{-w any:any}. @cindex stealth TUN device forwarding, ex. @cindex stealth ssh tunnel, example @cindex stealth VPN, example @lisp (service persistent-ssh-service-type (ssh-connection-configuration (sshd-user "root") ; "root" is the default (sshd-host "1.2.3.4") ; change to IP of VPN server sshd as string (forwards (list (tunnel-forward-configuration))) (socks-proxy-config (socks-proxy-configuration (use-proxy? #t) (dynamic-forward (ssh-connection-configuration (sshd-host "1.2.3.4") ; change to IP of proxy sshd as string (forwards (list (dynamic-forward-configuration (entry-port 1357)))))))))) ; default is 8971 @end lisp You can start the extended service with the following shell command as root: @example herd start ssh-forwards@@tunnel,any:any@@1357 @end example In this example, the SOCKS proxy sshd providing stealth and the VPN server sshd are actually one and the same host. In general, you can use the same host or have 2 different hosts according to your preference. While using 2 hosts might provide more privacy, in the author's experience, using the same host as SOCKS proxy and VPN server still grants protection from IP blacklisting to the sshd. Final note of caution: once a host is blacklisted, connecting to that same host's VPN server stealthily will obviously not unblacklist it. Your luck holds only as long as the server host is @emph{only} connected to through a SOCKS proxy and @emph{never} directly by VPN clients. Do not underestimate the evils of this world, we are not @emph{defeating} censorship, merely @emph{flying under the radar} for a little while. @c ********************************************************************* @node Shepherd actions @chapter Shepherd actions Shepherd services extended by Guix services of type @code{persistent-ssh-service-type} provide 2 special shepherd actions, @ref{Jump Start,,, shepherd, The GNU Shepherd Manual} on how to use them from command-line. @table @code @cindex resurrect, shepherd action @item resurrect The @code{resurrect} action has no side effects when the service to which is belongs is running. Otherwise, and in this order, it will @code{enable} the service, by default recursively perform itself on a service which provides a dynamic forward that the service uses for proxying (if any), then @code{start} the service. @cindex force-resurrect, shepherd action @item force-resurrect The @code{force-resurrect} always has side effects which include stopping before starting the service to which it belongs when this service is started. It therefore @emph{always} causes an interruption of connectivity, namely it will @code{enable} the service, @code{stop} the service, by default recursively perform itself on a service which provides a dynamic forward that the service uses for proxying (if any), then @code{start} the service. @end table @c ********************************************************************* @node GNU Free Documentation License @appendix GNU Free Documentation License @cindex license, GNU Free Documentation License @include fdl-1.3.texi @c ********************************************************************* @node Concept Index @unnumbered Concept Index @printindex cp @node Programming Index @unnumbered Programming Index @syncodeindex tp fn @syncodeindex vr fn @printindex fn @bye @c Local Variables: @c ispell-local-dictionary: "american"; @c End: