Package: rnsh
r n s hShell over Reticulumrnshis a utility written in Python that facilitates shell
sessions overReticulumnetworks.
It is based on thernxutility that ships with Reticulum and
aims to provide a similar experience to SSH.ContentsAlpha DisclaimerRecent ChangesQuickstartOptionsHow it worksRoadmapActive TODOReminder: Beta SoftwareThe interface is starting to firm up, but some bug fixes at this
point still may introduce breaking changes, especially in the
protocol layers of the software.Recent Changesv0.1.3Fix an issue where disconnecting a session using ~. would result in further connections to
the same initiator would appear to hang.Setting-qwill suppress the pre-connect spinnersv0.1.2Adaptive compression (RNS update) provides significant performance improvements (PR)Allowed identities file - put allowed identities in a file instead of on the command
line for easier service invocations. (see PR for details)Escape Sequences, Session Termination & Line-Interactive Mode (see PR for details)v0.1.1Fix issue with intermittent data corruptionv0.1.0First beta! Includes peformance improvements.v0.0.13, v0.0.14Bug fixesv0.0.12Remove service name from RNS destination aspects. Service name
now selects a suffix for the identity file and should only be
supplied on the listener. The initiator only needs the destination
hash of the listener to connect.Show a spinner during link establishment on tty sessionsAttempt to catch and beautify exceptions on initiatorv0.0.11Event loop bursting improves throughput and CPU utilization on
both listener and initiator.Packet retries use RNS resend feature to prevent duplicate
packets.v0.0.10Rate limit window change events to prevent saturation of transportTweaked some loop timers to improve CPU utilizationv0.0.9Switch to a new packet-based protocolBug fixes and dependency updatesQuickstartTested (thus far) on Python 3.11 macOS 13.1 ARM64. Should
run on Python 3.6+ on Linux or Unix. WSL probably works.
Cygwin might work, too.Activate a virtualenvpip3 install rnshOr from awhlrelease,pip3 install /path/to/rnsh-0.0.1-py3-none-any.whlConfigure Reticulum interfaces, check withrnstatusReady to runrnsh. The options are shown below.Example: Shell serverSetupBefore running the listener or initiator, you'll need to get the
listener destination hash and the initiator identity hash.# On listenerrnsh-l-p# On initiatorrnsh-pNote: service name no longer is supplied on initiator. The destination
hash encapsulates this information.ListenerListening for default service name ("default").Using user's default Reticulum config dir (~/.reticulum).Using default identity ($RNSCONFIGDIR/storage/identities/rnsh).Allowing remote identity6d47805065fa470852cf1b1ef417a1acto connect.Launching/bin/zshon authorized connect.rnsh-l-a6d47805065fa470852cf1b1ef417a1ac--/bin/zshInitiatorConnecting to default service name ("default").Using user's default Reticulum config dir (~/.reticulum).Using default identity ($RNSCONFIGDIR/storage/identities/rnsh).Connecting to destinationa5f72aefc2cb3cdba648f73f77c4e887rnsha5f72aefc2cb3cdba648f73f77c4e887OptionsUsage:
    rnsh -l [-c <configdir>] [-i <identityfile> | -s <service_name>] [-v... | -q...] -p
    rnsh -l [-c <configdir>] [-i <identityfile> | -s <service_name>] [-v... | -q...] 
            [-b <period>] (-n | -a <identity_hash> [-a <identity_hash>] ...) [-A | -C] 
            [[--] <program> [<arg> ...]]
    rnsh [-c <configdir>] [-i <identityfile>] [-v... | -q...] -p
    rnsh [-c <configdir>] [-i <identityfile>] [-v... | -q...] [-N] [-m] [-w <timeout>] 
         <destination_hash> [[--] <program> [<arg> ...]]
    rnsh -h
    rnsh --version

Options:
    -c DIR --config DIR          Alternate Reticulum config directory to use
    -i FILE --identity FILE      Specific identity file to use
    -s NAME --service NAME       Service name for identity file if not default
    -p --print-identity          Print identity information and exit
    -l --listen                  Listen (server) mode. If supplied, <program> <arg>...will 
                                   be used as the command line when the initiator does not
                                   provide one or when remote command is disabled. If
                                   <program> is not supplied, the default shell of the 
                                   user rnsh is running under will be used.
    -b --announce PERIOD         Announce on startup and every PERIOD seconds
                                 Specify 0 for PERIOD to announce on startup only.
    -a HASH --allowed HASH       Specify identities allowed to connect
    -n --no-auth                 Disable authentication
    -N --no-id                   Disable identify on connect
    -A --remote-command-as-args  Concatenate remote command to argument list of <program>/shell
    -C --no-remote-command       Disable executing command line from remote
    -m --mirror                  Client returns with code of remote process
    -w TIME --timeout TIME       Specify client connect and request timeout in seconds
    -q --quiet                   Increase quietness (move level up), multiple increases effect
                                          DEFAULT LOGGING LEVEL
                                                  CRITICAL (silent)
                                    Initiator ->  ERROR
                                                  WARNING
                                     Listener ->  INFO
                                                  DEBUG    (insane)
    -v --verbose                 Increase verbosity (move level down), multiple increases effect
    --version                    Show version
    -h --help                    Show this helpHow it worksListenersListener instances are the servers. Each listener is configured
with an RNS identity, and a service name. Together, RNS makes
these into a destination hash that can be used to connect to
your listener.Each listener must use a unique identity. The-sparameter
can be used to specify a service name, which creates a unique
identity file.Listeners can be configured with a command line to run on
connect. Initiators can supply a command line as well. There
are several different options for the way the command line
is handled:-Cno initiator command line is allowed; the connection will
be terminated if one is supplied.-Ainitiator-supplied command line is appended to listener-
configured command lineWith neither of these options, the listener will use the first
valid command line from this list:Initiator-supplied command lineListener command line argumentDefault shell of user listener is running underIf the-noption is not set on the listener, the initiator
is required to identify before starting a command. The program
will be started with the initiator's identity hash string is set
in the environment variableRNS_REMOTE_IDENTITY.Listeners are set up using the-lflag.InitiatorsInitiators are the clients. Each initiator has an identity
hash which is used as an authentication mechanism on Reticulum.
You'll need this value to configure the listener to allow
your connection. It is possible to run the server without
authentication, but hopefully it's obvious that this is an
advanced use case.To get the identity hash, use the-pflag.With the initiator identity set up in the listener command
line, and with the listener identity copied (you'll need to
do-pon the listener side, too), you can run the
initiator.I recommend staying pretty vanilla to start with and
trying/bin/zshor whatever your favorite shell is these
days. The shell should start in login mode. Ideally it
works just like ansshshell session.ProtocolThe protocol is build on top of the ReticulumPacketAPI.
Application software sends and receivesMessageobjects,
which are encapsulated byPacketobjects. Messages are
(currently) sent one per packet, and only one packet is
sent at a time (per link). The next packet is not sent until
the receiver proves the outstanding packet.A future update will work to allow a sliding window of
outstanding packets to improve channel utilization.Session EstablishmentInitiator establishes link. Listener session enters stateLSSTATE_WAIT_IDENT, orLSSTATE_WAIT_VERSif running
with--no-authoption.Initiator identifies on link if not using--no-id.If using--allowed-hash, listener validates identity
against configuration and if no match, sends a
protocol error message and tears down link after prune
timer.Initiator transmits aVersionInformationMessage, which
is evaluated by the server for compatibility. If
incompatible, a protocol error is sent.Listener responds with aVersionInfoMessageand enters
stateLSSTATE_WAIT_CMDInitiator evaluates the listener's version information
for compatibility and if incompatible, tears down link.Initiator sends anExecuteCommandMessage(which could
be an empty command) and enters the session event loop.Listener evaluates the command message against the
configured options such as-Aor-Cand responds
with a protocol error if not allowed.Listener starts the program. If success, the listener
enters the session event loop. If failure, responds
with aCommandExitedMessage.Session Event LoopListener stateLSSTATE_RUNNINGProcess messages received from initiator.WindowSizeMessage: set window size on child tty if appropriateStreamDataMessage: binary data stream for child process;
streams ids 0, 1, 2 = stdin, stdout, stderrNoopMessage: no operation - listener replies withNoopMessageWhen link is torn down, child process is terminated if running and
session destroyedIf command terminates, aCommandExitedMessageis sent and session
is pruned after an idle timeout.Initiator stateISSTATE_RUNNINGProcess messages received from listener.ErrorMessage: print error, terminate link, and exitStreamDataMessage: binary stream information;
streams ids 0, 1, 2 = stdin, stdout, stderrCommandExitedMessage: remote command exitedIf link is torn down unexpectedly, print message and exitRoadmapPlan a better roadmap?Keep my day jobTODOInitial versionPip package with command-line utility supportPublish to PyPIImprove signal handlingMake it scriptable (currently requires a tty)Protocol improvements (throughput!)Documentation improvementsFix issues with runningrnshin a binary pipeline, i.e.
piping the output oftaroverrsh.Test on several platformsFix issues that come up with testingv0.1.0 betaTest and fix more issuesMore betasEnhancement Ideasauthorized_keysmode similar to SSH to allow one listener
process to serve multiple usersGit overrnsh(git remote helper)Sliding window acknowledgements for improved throughputv1.0 someday probably maybeMiscellaneousBy piping into/out ofrnsh, it is possible to transfer
files using the same method discussed inthis article.
It's not terribly fast currently, due to the round-trip rule
enforced by the protocol. Sliding window acknowledgements will
speed this up significantly.