mirror of
https://github.com/markqvist/Reticulum.git
synced 2026-07-26 09:38:14 -07:00
Cleanup
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
.. _examples-main:
|
||||
|
||||
*************
|
||||
Code Examples
|
||||
*************
|
||||
|
||||
A number of examples are included in the source distribution of Reticulum.
|
||||
You can use these examples to learn how to write your own programs.
|
||||
|
||||
.. _example-minimal:
|
||||
|
||||
Minimal
|
||||
=======
|
||||
|
||||
The *Minimal* example demonstrates the bare-minimum setup required to connect to
|
||||
a Reticulum network from your program. In about five lines of code, you will
|
||||
have the Reticulum Network Stack initialised, and ready to pass traffic in your
|
||||
program.
|
||||
|
||||
.. literalinclude:: ../../Examples/Minimal.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Minimal.py>`_.
|
||||
|
||||
.. _example-announce:
|
||||
|
||||
Announce
|
||||
========
|
||||
|
||||
The *Announce* example builds upon the previous example by exploring how to
|
||||
announce a destination on the network, and how to let your program receive
|
||||
notifications about announces from relevant destinations.
|
||||
|
||||
.. literalinclude:: ../../Examples/Announce.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Announce.py>`_.
|
||||
|
||||
.. _example-broadcast:
|
||||
|
||||
Broadcast
|
||||
=========
|
||||
The *Broadcast* example explores how to transmit plaintext broadcast messages
|
||||
over the network.
|
||||
|
||||
.. literalinclude:: ../../Examples/Broadcast.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Broadcast.py>`_.
|
||||
|
||||
.. _example-echo:
|
||||
|
||||
Echo
|
||||
====
|
||||
|
||||
The *Echo* example demonstrates communication between two destinations using
|
||||
the Packet interface.
|
||||
|
||||
.. literalinclude:: ../../Examples/Echo.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Echo.py>`_.
|
||||
|
||||
.. _example-link:
|
||||
|
||||
Link
|
||||
====
|
||||
|
||||
The *Link* example explores establishing an encrypted link to a remote
|
||||
destination, and passing traffic back and forth over the link.
|
||||
|
||||
.. literalinclude:: ../../Examples/Link.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Link.py>`_.
|
||||
|
||||
.. _example-identify:
|
||||
|
||||
Identification
|
||||
==============
|
||||
|
||||
The *Identify* example explores identifying an intiator of a link, once
|
||||
the link has been established.
|
||||
|
||||
.. literalinclude:: ../../Examples/Identify.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Identify.py>`_.
|
||||
|
||||
.. _example-request:
|
||||
|
||||
Requests & Responses
|
||||
====================
|
||||
|
||||
The *Request* example explores sending requests and receiving responses.
|
||||
|
||||
.. literalinclude:: ../../Examples/Request.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Request.py>`_.
|
||||
|
||||
.. _example-channel:
|
||||
|
||||
Channel
|
||||
=======
|
||||
|
||||
The *Channel* example explores using a ``Channel`` to send structured
|
||||
data between peers of a ``Link``.
|
||||
|
||||
.. literalinclude:: ../../Examples/Channel.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Channel.py>`_.
|
||||
|
||||
Buffer
|
||||
======
|
||||
|
||||
The *Buffer* example explores using buffered readers and writers to send
|
||||
binary data between peers of a ``Link``.
|
||||
|
||||
.. literalinclude:: ../../Examples/Buffer.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Buffer.py>`_.
|
||||
|
||||
.. _example-filetransfer:
|
||||
|
||||
Filetransfer
|
||||
============
|
||||
|
||||
The *Filetransfer* example implements a basic file-server program that
|
||||
allow clients to connect and download files. The program uses the Resource
|
||||
interface to efficiently pass files of any size over a Reticulum :ref:`Link<api-link>`.
|
||||
|
||||
.. literalinclude:: ../../Examples/Filetransfer.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py>`_.
|
||||
|
||||
.. _example-custominterface:
|
||||
|
||||
Custom Interfaces
|
||||
=================
|
||||
|
||||
The *ExampleInterface* demonstrates creating custom interfaces for Reticulum.
|
||||
Any number of custom interfaces can be loaded and utilised by Reticulum, and
|
||||
will be fully on-par with natively included interfaces, including all supported
|
||||
:ref:`interface modes<interfaces-modes>` and :ref:`common configuration options<interfaces-options>`.
|
||||
|
||||
.. literalinclude:: ../../Examples/ExampleInterface.py
|
||||
|
||||
This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/ExampleInterface.py>`_.
|
||||
@@ -0,0 +1,4 @@
|
||||
********************************************
|
||||
An Explanation of Reticulum for Human Beings
|
||||
********************************************
|
||||
|
||||
@@ -0,0 +1,749 @@
|
||||
********************
|
||||
Getting Started Fast
|
||||
********************
|
||||
|
||||
The best way to get started with the Reticulum Network Stack depends on what
|
||||
you want to do. This guide will outline sensible starting paths for different
|
||||
scenarios.
|
||||
|
||||
|
||||
Standalone Reticulum Installation
|
||||
=============================================
|
||||
If you simply want to install Reticulum and related utilities on a system,
|
||||
the easiest way is via the ``pip`` package manager:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install rns
|
||||
|
||||
If you do not already have pip installed, you can install it using the package manager
|
||||
of your system with a command like ``sudo apt install python3-pip``,
|
||||
``sudo pamac install python-pip`` or similar.
|
||||
|
||||
You can also dowload the Reticulum release wheels from GitHub, or other release channels,
|
||||
and install them offline using ``pip``:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install ./rns-0.5.1-py3-none-any.whl
|
||||
|
||||
For more detailed installation instructions, please see the
|
||||
:ref:`Platform-Specific Install Notes<install-guides>` section.
|
||||
|
||||
After installation is complete, it might be helpful to refer to the
|
||||
:ref:`Using Reticulum on Your System<using-main>` chapter.
|
||||
|
||||
Resolving Dependency & Installation Issues
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
On some platforms, there may not be binary packages available for all dependencies, and
|
||||
``pip`` installation may fail with an error message. In these cases, the issue can usually
|
||||
be resolved by installing the development essentials packages for your platform:
|
||||
|
||||
.. code::
|
||||
|
||||
# Debian / Ubuntu / Derivatives
|
||||
sudo apt install build-essential
|
||||
|
||||
# Arch / Manjaro / Derivatives
|
||||
sudo pamac install base-devel
|
||||
|
||||
# Fedora
|
||||
sudo dnf groupinstall "Development Tools" "Development Libraries"
|
||||
|
||||
With the base development packages installed, ``pip`` should be able to compile any missing
|
||||
dependencies from source, and complete installation even on platforms that don't have pre-
|
||||
compiled packages available.
|
||||
|
||||
Try Using a Reticulum-based Program
|
||||
=============================================
|
||||
|
||||
If you simply want to try using a program built with Reticulum, a few different
|
||||
programs exist that allow basic communication and a range of other useful functions,
|
||||
even over extremely low-bandwidth Reticulum networks.
|
||||
|
||||
These programs will let you get a feel for how Reticulum works. They have been designed
|
||||
to run well over networks based on LoRa or packet radio, but can also be used over fast
|
||||
links, such as local WiFi, wired Ethernet, the Internet, or any combination.
|
||||
|
||||
As such, it is easy to get started experimenting, without having to set up any radio
|
||||
transceivers or infrastructure just to try it out. Launching the programs on separate
|
||||
devices connected to the same WiFi network is enough to get started, and physical
|
||||
radio interfaces can then be added later.
|
||||
|
||||
Remote Shell
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The `rnsh <https://github.com/acehoss/rnsh>`_ program lets you establish fully interactive
|
||||
remote shell sessions over Reticulum. It also allows you to pipe any program to or from a
|
||||
remote system, and is similar to how ``ssh`` works. The ``rnsh`` is very efficient, and
|
||||
can facilitate fully interactive shell sessions, even over extremely low-bandwidth links,
|
||||
such as LoRa or packet radio.
|
||||
|
||||
Nomad Network
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The terminal-based program `Nomad Network <https://github.com/markqvist/nomadnet>`_
|
||||
provides a complete encrypted communications suite built with Reticulum. It features
|
||||
encrypted messaging (both direct and delayed-delivery for offline users), file sharing,
|
||||
and has a built-in text-browser and page server with support for dynamically rendered pages,
|
||||
user authentication and more.
|
||||
|
||||
.. image:: screenshots/nomadnet_3.png
|
||||
:target: _images/nomadnet_3.png
|
||||
|
||||
`Nomad Network <https://github.com/markqvist/nomadnet>`_ is a user-facing client
|
||||
for the messaging and information-sharing protocol
|
||||
`LXMF <https://github.com/markqvist/lxmf>`_, another project built with Reticulum.
|
||||
|
||||
You can install Nomad Network via pip:
|
||||
|
||||
.. code::
|
||||
|
||||
# Install ...
|
||||
pip install nomadnet
|
||||
|
||||
# ... and run
|
||||
nomadnet
|
||||
|
||||
.. note::
|
||||
If this is the very first time you use ``pip`` to install a program
|
||||
on your system, you might need to reboot your system for your program to become
|
||||
available. If you get a "command not found" error or similar when running the
|
||||
program, reboot your system and try again. In some cases, you may even need to
|
||||
manually add the ``pip`` install path to your ``PATH`` environment variable.
|
||||
|
||||
Sideband
|
||||
^^^^^^^^
|
||||
|
||||
If you would rather use a program with a graphical user interface, you can take
|
||||
a look at `Sideband <https://unsigned.io/sideband>`_, which is available for Android,
|
||||
Linux, macOS and Windows.
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. image:: screenshots/sideband_devices.webp
|
||||
:align: center
|
||||
:target: _images/sideband_devices.webp
|
||||
|
||||
.. only:: latexpdf
|
||||
|
||||
.. image:: screenshots/sideband_devices.png
|
||||
:align: center
|
||||
:target: _images/sideband_devices.png
|
||||
|
||||
Sideband allows you to communicate with other people or LXMF-compatible
|
||||
systems over Reticulum networks using LoRa, Packet Radio, WiFi, I2P, Encrypted QR
|
||||
Paper Messages, or anything else Reticulum supports. It also interoperates with
|
||||
the Nomad Network program.
|
||||
|
||||
MeshChat
|
||||
^^^^^^^^
|
||||
|
||||
The `Reticulum MeshChat <https://github.com/liamcottle/reticulum-meshchat>`_ application
|
||||
is a user-friendly LXMF client for macOS and Windows, that also includes voice call
|
||||
functionality, and a range of other interesting functions.
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. image:: screenshots/meshchat_1.webp
|
||||
:align: center
|
||||
:target: _images/meshchat_1.webp
|
||||
|
||||
.. only:: latexpdf
|
||||
|
||||
.. image:: screenshots/meshchat_1.png
|
||||
:align: center
|
||||
:target: _images/meshchat_1.png
|
||||
|
||||
Reticulum MeshChat is of course also compatible with Sideband and Nomad Network, or
|
||||
any other LXMF client.
|
||||
|
||||
Using the Included Utilities
|
||||
=============================================
|
||||
Reticulum comes with a range of included utilities that make it easier to
|
||||
manage your network, check connectivity and make Reticulum available to other
|
||||
programs on your system.
|
||||
|
||||
You can use ``rnsd`` to run Reticulum as a background or foreground service,
|
||||
and the ``rnstatus``, ``rnpath`` and ``rnprobe`` utilities to view and query
|
||||
network status and connectivity.
|
||||
|
||||
To learn more about these utility programs, have a look at the
|
||||
:ref:`Using Reticulum on Your System<using-main>` chapter of this manual.
|
||||
|
||||
|
||||
Creating a Network With Reticulum
|
||||
=============================================
|
||||
To create a network, you will need to specify one or more *interfaces* for
|
||||
Reticulum to use. This is done in the Reticulum configuration file, which by
|
||||
default is located at ``~/.reticulum/config``. You can get an example
|
||||
configuration file with all options via ``rnsd --exampleconfig``.
|
||||
|
||||
When Reticulum is started for the first time, it will create a default
|
||||
configuration file, with one active interface. This default interface uses
|
||||
your existing Ethernet and WiFi networks (if any), and only allows you to
|
||||
communicate with other Reticulum peers within your local broadcast domains.
|
||||
|
||||
To communicate further, you will have to add one or more interfaces. The default
|
||||
configuration includes a number of examples, ranging from using TCP over the
|
||||
internet, to LoRa and Packet Radio interfaces.
|
||||
|
||||
With Reticulum, you only need to configure what interfaces you want to communicate
|
||||
over. There is no need to configure address spaces, subnets, routing tables,
|
||||
or other things you might be used to from other network types.
|
||||
|
||||
Once Reticulum knows which interfaces it should use, it will automatically
|
||||
discover topography and configure transport of data to any destinations it
|
||||
knows about.
|
||||
|
||||
In situations where you already have an established WiFi or Ethernet network, and
|
||||
many devices that want to utilise the same external Reticulum network paths (for example over
|
||||
LoRa), it will often be sufficient to let one system act as a Reticulum gateway, by
|
||||
adding any external interfaces to the configuration of this system, and then enabling transport on it. Any
|
||||
other device on your local WiFi will then be able to connect to this wider Reticulum
|
||||
network just using the default (:ref:`AutoInterface<interfaces-auto>`) configuration.
|
||||
|
||||
Possibly, the examples in the config file are enough to get you started. If
|
||||
you want more information, you can read the :ref:`Building Networks<networks-main>`
|
||||
and :ref:`Interfaces<interfaces-main>` chapters of this manual.
|
||||
|
||||
Connecting Reticulum Instances Over the Internet
|
||||
================================================
|
||||
Reticulum currently offers two interfaces suitable for connecting instances over the Internet: :ref:`TCP<interfaces-tcps>`
|
||||
and :ref:`I2P<interfaces-i2p>`. Each interface offers a different set of features, and Reticulum
|
||||
users should carefully choose the interface which best suites their needs.
|
||||
|
||||
The ``TCPServerInterface`` allows users to host an instance accessible over TCP/IP. This
|
||||
method is generally faster, lower latency, and more energy efficient than using ``I2PInterface``,
|
||||
however it also leaks more data about the server host.
|
||||
|
||||
TCP connections reveal the IP address of both your instance and the server to anyone who can
|
||||
inspect the connection. Someone could use this information to determine your location or identity. Adversaries
|
||||
inspecting your packets may be able to record packet metadata like time of transmission and packet size.
|
||||
Even though Reticulum encrypts traffic, TCP does not, so an adversary may be able to use
|
||||
packet inspection to learn that a system is running Reticulum, and what other IP addresses connect to it.
|
||||
Hosting a publicly reachable instance over TCP also requires a publicly reachable IP address,
|
||||
which most Internet connections don't offer anymore.
|
||||
|
||||
The ``I2PInterface`` routes messages through the `Invisible Internet Protocol
|
||||
(I2P) <https://geti2p.net/en/>`_. To use this interface, users must also run an I2P daemon in
|
||||
parallel to ``rnsd``. For always-on I2P nodes it is recommended to use `i2pd <https://i2pd.website/>`_.
|
||||
|
||||
By default, I2P will encrypt and mix all traffic sent over the Internet, and
|
||||
hide both the sender and receiver Reticulum instance IP addresses. Running an I2P node
|
||||
will also relay other I2P user's encrypted packets, which will use extra
|
||||
bandwidth and compute power, but also makes timing attacks and other forms of
|
||||
deep-packet-inspection much more difficult.
|
||||
|
||||
I2P also allows users to host globally available Reticulum instances from non-public IP's and behind firewalls and NAT.
|
||||
|
||||
In general it is recommended to use an I2P node if you want to host a publicly accessible
|
||||
instance, while preserving anonymity. If you care more about performance, and a slightly
|
||||
easier setup, use TCP.
|
||||
|
||||
|
||||
Connect to the Public Testnet
|
||||
===========================================
|
||||
|
||||
An experimental public testnet has been made accessible over both I2P and TCP. You can join it
|
||||
by adding one of the following interfaces to your ``.reticulum/config`` file:
|
||||
|
||||
.. code::
|
||||
|
||||
# TCP/IP interface to the RNS Amsterdam Hub
|
||||
[[RNS Testnet Amsterdam]]
|
||||
type = TCPClientInterface
|
||||
enabled = yes
|
||||
target_host = amsterdam.connect.reticulum.network
|
||||
target_port = 4965
|
||||
|
||||
# TCP/IP interface to the BetweenTheBorders Hub (community-provided)
|
||||
[[RNS Testnet BetweenTheBorders]]
|
||||
type = TCPClientInterface
|
||||
enabled = yes
|
||||
target_host = reticulum.betweentheborders.com
|
||||
target_port = 4242
|
||||
|
||||
# Interface to Testnet I2P Hub
|
||||
[[RNS Testnet I2P Hub]]
|
||||
type = I2PInterface
|
||||
enabled = yes
|
||||
peers = g3br23bvx3lq5uddcsjii74xgmn6y5q325ovrkq2zw2wbzbqgbuq.b32.i2p
|
||||
|
||||
Many other Reticulum instances are connecting to this testnet, and you can also join it
|
||||
via other entry points if you know them. There is absolutely no control over the network
|
||||
topography, usage or what types of instances connect. It will also occasionally be used
|
||||
to test various failure scenarios, and there are no availability or service guarantees.
|
||||
Expect weird things to happen on this network, as people experiment and try out things.
|
||||
|
||||
It probably goes without saying, but *don't use the testnet entry-points as
|
||||
hardcoded or default interfaces in any applications you ship to users*. When
|
||||
shipping applications, the best practice is to provide your own default
|
||||
connectivity solutions, if needed and applicable, or in most cases, simply
|
||||
leave it up to the user which networks to connect to, and how.
|
||||
|
||||
|
||||
Adding Radio Interfaces
|
||||
==============================================
|
||||
Once you have Reticulum installed and working, you can add radio interfaces with
|
||||
any compatible hardware you have available. Reticulum supports a wide range of radio
|
||||
hardware, and if you already have any available, it is very likely that it will
|
||||
work with Reticulum. For information on how to configure this, see the
|
||||
:ref:`Interfaces<interfaces-main>` section of this manual.
|
||||
|
||||
If you do not already have transceiver hardware available, you can easily and
|
||||
cheaply build an :ref:`RNode<rnode-main>`, which is a general-purpose long-range
|
||||
digital radio transceiver, that integrates easily with Reticulum.
|
||||
|
||||
To build one yourself requires installing a custom firmware on a supported LoRa
|
||||
development board with an auto-install script. Please see the :ref:`Communications Hardware<hardware-main>`
|
||||
chapter for a guide. If you prefer purchasing a ready-made unit, you can refer to the
|
||||
:ref:`list of suppliers<rnode-suppliers>`. For more information on RNode, you can also
|
||||
refer to these additional external resources:
|
||||
|
||||
* `How To Make Your Own RNodes <https://unsigned.io/how-to-make-your-own-rnodes/>`_
|
||||
* `Installing RNode Firmware on Compatible LoRa Devices <https://unsigned.io/installing-rnode-firmware-on-supported-devices/>`_
|
||||
* `Private, Secure and Uncensorable Messaging Over a LoRa Mesh <https://unsigned.io/private-messaging-over-lora/>`_
|
||||
* `RNode Firmware <https://github.com/markqvist/RNode_Firmware/>`_
|
||||
|
||||
If you have communications hardware that is not already supported by any of the
|
||||
:ref:`existing interface types<interfaces-main>`, but you think would be suitable for use with Reticulum,
|
||||
you are welcome to head over to the `GitHub discussion pages <https://github.com/markqvist/Reticulum/discussions>`_
|
||||
and propose adding an interface for the hardware.
|
||||
|
||||
|
||||
Creating and Using Custom Interfaces
|
||||
===========================================
|
||||
|
||||
While Reticulum includes a flexible and broad range of built-in interfaces, these
|
||||
will not cover every conceivable type of communications hardware that Reticulum
|
||||
can potentially use to communicate.
|
||||
|
||||
It is therefore possible to easily write your own interface modules, that can be
|
||||
loaded at run-time and used on-par with any of the built-in interface types.
|
||||
|
||||
For more information on this subject, and code examples to build on, please see
|
||||
the :ref:`Configuring Interfaces<interfaces-main>` chapter.
|
||||
|
||||
|
||||
Develop a Program with Reticulum
|
||||
===========================================
|
||||
If you want to develop programs that use Reticulum, the easiest way to get
|
||||
started is to install the latest release of Reticulum via pip:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install rns
|
||||
|
||||
The above command will install Reticulum and dependencies, and you will be
|
||||
ready to import and use RNS in your own programs. The next step will most
|
||||
likely be to look at some :ref:`Example Programs<examples-main>`.
|
||||
|
||||
The entire Reticulum API is documented in the :ref:`API Reference<api-main>`
|
||||
chapter of this manual.
|
||||
|
||||
|
||||
Participate in Reticulum Development
|
||||
==============================================
|
||||
If you want to participate in the development of Reticulum and associated
|
||||
utilities, you'll want to get the latest source from GitHub. In that case,
|
||||
don't use pip, but try this recipe:
|
||||
|
||||
.. code::
|
||||
|
||||
# Install dependencies
|
||||
pip install cryptography pyserial
|
||||
|
||||
# Clone repository
|
||||
git clone https://github.com/markqvist/Reticulum.git
|
||||
|
||||
# Move into Reticulum folder and symlink library to examples folder
|
||||
cd Reticulum
|
||||
ln -s ../RNS ./Examples/
|
||||
|
||||
# Run an example
|
||||
python Examples/Echo.py -s
|
||||
|
||||
# Unless you've manually created a config file, Reticulum will do so now,
|
||||
# and immediately exit. Make any necessary changes to the file:
|
||||
nano ~/.reticulum/config
|
||||
|
||||
# ... and launch the example again.
|
||||
python Examples/Echo.py -s
|
||||
|
||||
# You can now repeat the process on another computer,
|
||||
# and run the same example with -h to get command line options.
|
||||
python Examples/Echo.py -h
|
||||
|
||||
# Run the example in client mode to "ping" the server.
|
||||
# Replace the hash below with the actual destination hash of your server.
|
||||
python Examples/Echo.py 174a64852a75682259ad8b921b8bf416
|
||||
|
||||
# Have a look at another example
|
||||
python Examples/Filetransfer.py -h
|
||||
|
||||
When you have experimented with the basic examples, it's time to go read the
|
||||
:ref:`Understanding Reticulum<understanding-main>` chapter. Before submitting
|
||||
your first pull request, it is probably a good idea to introduce yourself on
|
||||
the `disucssion forum on GitHub <https://github.com/markqvist/Reticulum/discussions>`_,
|
||||
or ask one of the developers or maintainers for a good place to start.
|
||||
|
||||
.. _install-guides:
|
||||
|
||||
Platform-Specific Install Notes
|
||||
==============================================
|
||||
|
||||
Some platforms require a slightly different installation procedure, or have
|
||||
various quirks that are worth being aware of. These are listed here.
|
||||
|
||||
Android
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Reticulum can be used on Android in different ways. The easiest way to get
|
||||
started is using an app like `Sideband <https://unsigned.io/sideband>`_.
|
||||
|
||||
For more control and features, you can use Reticulum and related programs via
|
||||
the `Termux app <https://termux.com/>`_, at the time of writing available on
|
||||
`F-droid <https://f-droid.org>`_.
|
||||
|
||||
Termux is a terminal emulator and Linux environment for Android based devices,
|
||||
which includes the ability to use many different programs and libraries,
|
||||
including Reticulum.
|
||||
|
||||
To use Reticulum within the Termux environment, you will need to install
|
||||
``python`` and the ``python-cryptography`` library using ``pkg``, the package-manager
|
||||
build into Termux. After that, you can use ``pip`` to install Reticulum.
|
||||
|
||||
From within Termux, execute the following:
|
||||
|
||||
.. code::
|
||||
|
||||
# First, make sure indexes and packages are up to date.
|
||||
pkg update
|
||||
pkg upgrade
|
||||
|
||||
# Then install python and the cryptography library.
|
||||
pkg install python python-cryptography
|
||||
|
||||
# Make sure pip is up to date, and install the wheel module.
|
||||
pip install wheel pip --upgrade
|
||||
|
||||
# Install Reticulum
|
||||
pip install rns
|
||||
|
||||
If for some reason the ``python-cryptography`` package is not available for
|
||||
your platform via the Termux package manager, you can attempt to build it
|
||||
locally on your device using the following command:
|
||||
|
||||
.. code::
|
||||
|
||||
# First, make sure indexes and packages are up to date.
|
||||
pkg update
|
||||
pkg upgrade
|
||||
|
||||
# Then install dependencies for the cryptography library.
|
||||
pkg install python build-essential openssl libffi rust
|
||||
|
||||
# Make sure pip is up to date, and install the wheel module.
|
||||
pip install wheel pip --upgrade
|
||||
|
||||
# To allow the installer to build the cryptography module,
|
||||
# we need to let it know what platform we are compiling for:
|
||||
export CARGO_BUILD_TARGET="aarch64-linux-android"
|
||||
|
||||
# Start the install process for the cryptography module.
|
||||
# Depending on your device, this can take several minutes,
|
||||
# since the module must be compiled locally on your device.
|
||||
pip install cryptography
|
||||
|
||||
# If the above installation succeeds, you can now install
|
||||
# Reticulum and any related software
|
||||
pip install rns
|
||||
|
||||
It is also possible to include Reticulum in apps compiled and distributed as
|
||||
Android APKs. A detailed tutorial and example source code will be included
|
||||
here at a later point. Until then you can use the `Sideband source code <https://github.com/markqvist/sideband>`_ as an example and starting point.
|
||||
|
||||
|
||||
ARM64
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
On some architectures, including ARM64, not all dependencies have precompiled
|
||||
binaries. On such systems, you may need to install ``python3-dev`` (or similar) before
|
||||
installing Reticulum or programs that depend on Reticulum.
|
||||
|
||||
.. code::
|
||||
|
||||
# Install Python and development packages
|
||||
sudo apt update
|
||||
sudo apt install python3 python3-pip python3-dev
|
||||
|
||||
# Install Reticulum
|
||||
python3 -m pip install rns
|
||||
|
||||
With these packages installed, ``pip`` will be able to build any missing dependencies
|
||||
on your system locally.
|
||||
|
||||
|
||||
Debian Bookworm
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
On versions of Debian released after April 2023, it is no longer possible by default
|
||||
to use ``pip`` to install packages onto your system. Unfortunately, you will need to
|
||||
use the replacement ``pipx`` command instead, which places installed packages in an
|
||||
isolated environment. This should not negatively affect Reticulum, but will not work
|
||||
for including and using Reticulum in your own scripts and programs.
|
||||
|
||||
.. code::
|
||||
|
||||
# Install pipx
|
||||
sudo apt install pipx
|
||||
|
||||
# Make installed programs available on the command line
|
||||
pipx ensurepath
|
||||
|
||||
# Install Reticulum
|
||||
pipx install rns
|
||||
|
||||
Alternatively, you can restore normal behaviour to ``pip`` by creating or editing
|
||||
the configuration file located at ``~/.config/pip/pip.conf``, and adding the
|
||||
following section:
|
||||
|
||||
.. code:: text
|
||||
|
||||
[global]
|
||||
break-system-packages = true
|
||||
|
||||
For a one-shot installation of Reticulum, without globally enabling the ``break-system-packages``
|
||||
option, you can use the following command:
|
||||
|
||||
.. code:: text
|
||||
|
||||
pip install rns --break-system-packages
|
||||
|
||||
.. note::
|
||||
The ``--break-system-packages`` directive is a somewhat misleading choice
|
||||
of words. Setting it will of course not break any system packages, but will simply
|
||||
allow installing ``pip`` packages user- and system-wide. While this *could* in rare
|
||||
cases lead to version conflicts, it does not generally pose any problems, especially
|
||||
not in the case of installing Reticulum.
|
||||
|
||||
|
||||
MacOS
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
To install Reticulum on macOS, you will need to have Python and the ``pip`` package
|
||||
manager installed.
|
||||
|
||||
Systems running macOS can vary quite widely in whether or not Python is pre-installed,
|
||||
and if it is, which version is installed, and whether the ``pip`` package manager is
|
||||
also installed and set up. If in doubt, you can `download and install <https://www.python.org/downloads/>`_
|
||||
Python manually.
|
||||
|
||||
When Python and ``pip`` is available on your system, simply open a terminal window
|
||||
and use one of the following commands:
|
||||
|
||||
.. code::
|
||||
|
||||
# Install Reticulum and utilities with pip:
|
||||
pip3 install rns
|
||||
|
||||
# On some versions, you may need to use the
|
||||
# flag --break-system-packages to install:
|
||||
pip3 install rns --break-system-packages
|
||||
|
||||
.. note::
|
||||
The ``--break-system-packages`` directive is a somewhat misleading choice
|
||||
of words. Setting it will of course not break any system packages, but will simply
|
||||
allow installing ``pip`` packages user- and system-wide. While this *could* in rare
|
||||
cases lead to version conflicts, it does not generally pose any problems, especially
|
||||
not in the case of installing Reticulum.
|
||||
|
||||
Additionally, some version combinations of macOS and Python require you to
|
||||
manually add your installed ``pip`` packages directory to your `PATH` environment
|
||||
variable, before you can use installed commands in your terminal. Usually, adding
|
||||
the following line to your shell init script (for example ``~/.zshrc``) will be enough:
|
||||
|
||||
.. code::
|
||||
|
||||
export PATH=$PATH:~/Library/Python/3.9/bin
|
||||
|
||||
Adjust Python version and shell init script location according to your system.
|
||||
|
||||
|
||||
OpenWRT
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
On OpenWRT systems with sufficient storage and memory, you can install
|
||||
Reticulum and related utilities using the `opkg` package manager and `pip`.
|
||||
|
||||
.. note::
|
||||
|
||||
At the time of releasing this manual, work is underway to create pre-built
|
||||
Reticulum packages for OpenWRT, with full configuration, service
|
||||
and ``uci`` integration. Please see the `feed-reticulum <https://github.com/gretel/feed-reticulum>`_
|
||||
and `reticulum-openwrt <https://github.com/gretel/reticulum-openwrt>`_
|
||||
repositories for more information.
|
||||
|
||||
To install Reticulum on OpenWRT, first log into a command line session, and
|
||||
then use the following instructions:
|
||||
|
||||
.. code::
|
||||
|
||||
# Install dependencies
|
||||
opkg install python3 python3-pip python3-cryptography python3-pyserial
|
||||
|
||||
# Install Reticulum
|
||||
pip install rns
|
||||
|
||||
# Start rnsd with debug logging enabled
|
||||
rnsd -vvv
|
||||
|
||||
.. note::
|
||||
|
||||
The above instructions have been verified and tested on OpenWRT 21.02 only.
|
||||
It is likely that other versions may require slightly altered installation
|
||||
commands or package names. You will also need enough free space in your
|
||||
overlay FS, and enough free RAM to actually run Reticulum and any related
|
||||
programs and utilities.
|
||||
|
||||
Depending on your device configuration, you may need to adjust firewall rules
|
||||
for Reticulum connectivity to and from your device to work. Until proper
|
||||
packaging is ready, you will also need to manually create a service or startup
|
||||
script to automatically laucnh Reticulum at boot time.
|
||||
|
||||
Please also note that the `AutoInterface` requires link-local IPv6 addresses
|
||||
to be enabled for any Ethernet and WiFi devices you intend to use. If ``ip a``
|
||||
shows an address starting with ``fe80::`` for the device in question,
|
||||
``AutoInterface`` should work for that device.
|
||||
|
||||
Raspberry Pi
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
It is currently recommended to use a 64-bit version of the Raspberry Pi OS
|
||||
if you want to run Reticulum on Raspberry Pi computers, since 32-bit versions
|
||||
don't always have packages available for some dependencies. If Python and the
|
||||
`pip` package manager is not already installed, do that first, and then
|
||||
install Reticulum using `pip`.
|
||||
|
||||
.. code::
|
||||
|
||||
# Install dependencies
|
||||
sudo apt install python3 python3-pip python3-cryptography python3-pyserial
|
||||
|
||||
# Install Reticulum
|
||||
pip install rns --break-system-packages
|
||||
|
||||
.. note::
|
||||
The ``--break-system-packages`` directive is a somewhat misleading choice
|
||||
of words. Setting it will of course not break any system packages, but will simply
|
||||
allow installing ``pip`` packages user- and system-wide. While this *could* in rare
|
||||
cases lead to version conflicts, it does not generally pose any problems, especially
|
||||
not in the case of installing Reticulum.
|
||||
|
||||
While it is possible to install and run Reticulum on 32-bit Rasperry Pi OSes,
|
||||
it will require manually configuring and installing required build dependencies,
|
||||
and is not detailed in this manual.
|
||||
|
||||
|
||||
RISC-V
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
On some architectures, including RISC-V, not all dependencies have precompiled
|
||||
binaries. On such systems, you may need to install ``python3-dev`` (or similar) before
|
||||
installing Reticulum or programs that depend on Reticulum.
|
||||
|
||||
.. code::
|
||||
|
||||
# Install Python and development packages
|
||||
sudo apt update
|
||||
sudo apt install python3 python3-pip python3-dev
|
||||
|
||||
# Install Reticulum
|
||||
python3 -m pip install rns
|
||||
|
||||
With these packages installed, ``pip`` will be able to build any missing dependencies
|
||||
on your system locally.
|
||||
|
||||
|
||||
Ubuntu Lunar
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
On versions of Ubuntu released after April 2023, it is no longer possible by default
|
||||
to use ``pip`` to install packages onto your system. Unfortunately, you will need to
|
||||
use the replacement ``pipx`` command instead, which places installed packages in an
|
||||
isolated environment. This should not negatively affect Reticulum, but will not work
|
||||
for including and using Reticulum in your own scripts and programs.
|
||||
|
||||
.. code::
|
||||
|
||||
# Install pipx
|
||||
sudo apt install pipx
|
||||
|
||||
# Make installed programs available on the command line
|
||||
pipx ensurepath
|
||||
|
||||
# Install Reticulum
|
||||
pipx install rns
|
||||
|
||||
Alternatively, you can restore normal behaviour to ``pip`` by creating or editing
|
||||
the configuration file located at ``~/.config/pip/pip.conf``, and adding the
|
||||
following section:
|
||||
|
||||
.. code:: text
|
||||
|
||||
[global]
|
||||
break-system-packages = true
|
||||
|
||||
For a one-shot installation of Reticulum, without globally enabling the ``break-system-packages``
|
||||
option, you can use the following command:
|
||||
|
||||
.. code:: text
|
||||
|
||||
pip install rns --break-system-packages
|
||||
|
||||
.. note::
|
||||
The ``--break-system-packages`` directive is a somewhat misleading choice
|
||||
of words. Setting it will of course not break any system packages, but will simply
|
||||
allow installing ``pip`` packages user- and system-wide. While this *could* in rare
|
||||
cases lead to version conflicts, it does not generally pose any problems, especially
|
||||
not in the case of installing Reticulum.
|
||||
|
||||
Windows
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
On Windows operating systems, the easiest way to install Reticulum is by using the
|
||||
``pip`` package manager from the command line (either the command prompt or Windows
|
||||
Powershell).
|
||||
|
||||
If you don't already have Python installed, `download and install Python <https://www.python.org/downloads/>`_.
|
||||
At the time of publication of this manual, the recommended version is `Python 3.12.7 <https://www.python.org/downloads/release/python-3127>`_.
|
||||
|
||||
**Important!** When asked by the installer, make sure to add the Python program to
|
||||
your PATH environment variables. If you don't do this, you will not be able to
|
||||
use the ``pip`` installer, or run the included Reticulum utility programs (such as
|
||||
``rnsd`` and ``rnstatus``) from the command line.
|
||||
|
||||
After installing Python, open the command prompt or Windows Powershell, and type:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install rns
|
||||
|
||||
You can now use Reticulum and all included utility programs directly from your
|
||||
preferred command line interface.
|
||||
|
||||
Pure-Python Reticulum
|
||||
==============================================
|
||||
|
||||
.. warning::
|
||||
If you use the ``rnspure`` package to run Reticulum on systems that
|
||||
do not support `PyCA/cryptography <https://github.com/pyca/cryptography>`_, it is
|
||||
important that you read and understand the :ref:`Cryptographic Primitives <understanding-primitives>`
|
||||
section of this manual.
|
||||
|
||||
In some rare cases, and on more obscure system types, it is not possible to
|
||||
install one or more dependencies. In such situations,
|
||||
you can use the ``rnspure`` package instead of the ``rns`` package, or use ``pip``
|
||||
with the ``--no-dependencies`` command-line option. The ``rnspure``
|
||||
package requires no external dependencies for installation. Please note that the
|
||||
actual contents of the ``rns`` and ``rnspure`` packages are *completely identical*.
|
||||
The only difference is that the ``rnspure`` package lists no dependencies required
|
||||
for installation.
|
||||
|
||||
No matter how Reticulum is installed and started, it will load external dependencies
|
||||
only if they are *needed* and *available*. If for example you want to use Reticulum
|
||||
on a system that cannot support ``pyserial``, it is perfectly possible to do so using
|
||||
the `rnspure` package, but Reticulum will not be able to use serial-based interfaces.
|
||||
All other available modules will still be loaded when needed.
|
||||
@@ -0,0 +1,335 @@
|
||||
.. _hardware-main:
|
||||
|
||||
***********************
|
||||
Communications Hardware
|
||||
***********************
|
||||
|
||||
One of the truly valuable aspects of Reticulum is the ability to use it over
|
||||
almost any conceivable kind of communications medium. The :ref:`interface types<interfaces-main>`
|
||||
available for configuration in Reticulum are flexible enough to cover the use
|
||||
of most wired and wireless communications hardware available, from decades-old
|
||||
packet radio modems to modern millimeter-wave backhaul systems.
|
||||
|
||||
If you already have or operate some kind of communications hardware, there is a
|
||||
very good chance that it will work with Reticulum out of the box. In case it does
|
||||
not, it is possible to provide the necessary glue with very little effort using
|
||||
for example the :ref:`PipeInterface<interfaces-pipe>` or the :ref:`TCPClientInterface<interfaces-tcpc>`
|
||||
in combination with code like `TCP KISS Server <https://github.com/simplyequipped/tcpkissserver>`_
|
||||
by `simplyequipped <https://github.com/simplyequipped>`_.
|
||||
|
||||
While this broad support and flexibility is very useful, an abundance of options
|
||||
can sometimes make it difficult to know where to begin, especially when you are
|
||||
starting from scratch.
|
||||
|
||||
This chapter will outline a few different sensible starting paths to get
|
||||
real-world functional wireless communications up and running with minimal cost
|
||||
and effort. Two fundamental devices categories will be covered, *RNodes* and
|
||||
*WiFi-based radios*. Additionally, other common options will be briefly described.
|
||||
|
||||
Knowing how to employ just a few different types of hardware will make it possible
|
||||
to build a wide range of useful networks with little effort.
|
||||
|
||||
Combining Hardware Types
|
||||
========================
|
||||
|
||||
It is useful to combine different link and hardware types when designing and
|
||||
building a network. One useful design pattern is to employ high-capacity point-to-point
|
||||
links based on WiFi or millimeter-wave radios (with high-gain directional antennas)
|
||||
for the network backbone, and using LoRa-based RNodes for covering large areas with
|
||||
connectivity for client devices.
|
||||
|
||||
|
||||
.. _rnode-main:
|
||||
|
||||
RNode
|
||||
=====
|
||||
|
||||
Reliable and general-purpose long-range digital radio transceiver systems are
|
||||
commonly either very expensive, difficult to set up and operate, hard to source,
|
||||
power-hungry, or all of the above at the same time. In an attempt to alleviate
|
||||
this situation, the transceiver system *RNode* was designed. It is important to
|
||||
note that RNode is not one specific device, from one particular vendor, but
|
||||
*an open plaform* that anyone can use to build interoperable digital transceivers
|
||||
suited to their needs and particular situations.
|
||||
|
||||
An RNode is a general purpose, interoperable, low-power and long-range, reliable,
|
||||
open and flexible radio communications device. Depending on its components, it can
|
||||
operate on many different frequency bands, and use many different modulation
|
||||
schemes, but most commonly, and for the purposes of this chapter, we will limit
|
||||
the discussion to RNodes using *LoRa* modulation in common ISM bands.
|
||||
|
||||
**Avoid Confusion!** RNodes can use LoRa as a *physical-layer modulation*, but it
|
||||
does not use, and has nothing to do with the *LoRaWAN* protocol and standard, commonly
|
||||
used for centrally controlled IoT devices. RNodes use *raw LoRa modulation*, without
|
||||
any additional protocol overhead. All high-level protocol functionality is handled
|
||||
directly by Reticulum.
|
||||
|
||||
.. _rnode-creating:
|
||||
|
||||
Creating RNodes
|
||||
^^^^^^^^^^^^^^^
|
||||
RNode has been designed as a system that is easy to replicate across time and
|
||||
space. You can put together a functioning transceiver using commonly available
|
||||
components, and a few open source software tools. While you can design and build RNodes
|
||||
completely from scratch, to your exact desired specifications, this chapter
|
||||
will explain the easiest possible approach to creating RNodes: Using common
|
||||
LoRa development boards. This approach can be boiled down to two simple steps:
|
||||
|
||||
1. Obtain one or more :ref:`supported development boards<rnode-supported>`
|
||||
2. Install the RNode firmware with the :ref:`automated installer<rnode-installation>`
|
||||
|
||||
Once the firmware has been installed and provisioned by the install script, it
|
||||
is ready to use with any software that supports RNodes, including Reticulum.
|
||||
The device can be used with Reticulum by adding an :ref:`RNodeInterface<interfaces-rnode>`
|
||||
to the configuration.
|
||||
|
||||
.. _rnode-supported:
|
||||
|
||||
Supported Boards and Devices
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
To create one or more RNodes, you will need to obtain supported development
|
||||
boards. The following boards are supported by the auto-installer.
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_tbeam_supreme.png
|
||||
:width: 75%
|
||||
:align: center
|
||||
|
||||
LilyGO T-Beam Supreme
|
||||
"""""""""""""
|
||||
- **Transceiver IC** Semtech SX1262, SX1268
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_tbeam.png
|
||||
:width: 75%
|
||||
:align: center
|
||||
|
||||
LilyGO T-Beam
|
||||
"""""""""""""
|
||||
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 and SX1278
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_t3s3.png
|
||||
:width: 50%
|
||||
:align: center
|
||||
|
||||
LilyGO T3S3
|
||||
"""""""""""
|
||||
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 and SX1278
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_rak4631.png
|
||||
:width: 45%
|
||||
:align: center
|
||||
|
||||
RAK4631-based Boards
|
||||
""""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1262, SX1268
|
||||
- **Device Platform** nRF52
|
||||
- **Manufacturer** `RAK Wireless <https://www.rakwireless.com>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_rnodev2.png
|
||||
:width: 68%
|
||||
:align: center
|
||||
|
||||
Unsigned RNode v2.x
|
||||
"""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1276 and SX1278
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `unsigned.io <https://unsigned.io>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_t3v21.png
|
||||
:width: 46%
|
||||
:align: center
|
||||
|
||||
LilyGO LoRa32 v2.1
|
||||
""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1276 and SX1278
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_t3v20.png
|
||||
:width: 46%
|
||||
:align: center
|
||||
|
||||
LilyGO LoRa32 v2.0
|
||||
""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1276 and SX1278
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_t3v10.png
|
||||
:width: 46%
|
||||
:align: center
|
||||
|
||||
LilyGO LoRa32 v1.0
|
||||
""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1276 and SX1278
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_tdeck.png
|
||||
:width: 45%
|
||||
:align: center
|
||||
|
||||
LilyGO T-Deck
|
||||
"""""""""""""
|
||||
- **Transceiver IC** Semtech SX1262, SX1268
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `LilyGO <https://lilygo.cn>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_heltec32v30.png
|
||||
:width: 58%
|
||||
:align: center
|
||||
|
||||
Heltec LoRa32 v3.0
|
||||
""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1262 and SX1268
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_heltec32v20.png
|
||||
:width: 58%
|
||||
:align: center
|
||||
|
||||
Heltec LoRa32 v2.0
|
||||
""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1276 and SX1278
|
||||
- **Device Platform** ESP32
|
||||
- **Manufacturer** `Heltec Automation <https://heltec.org>`_
|
||||
|
||||
------------
|
||||
|
||||
.. image:: graphics/board_rnode.png
|
||||
:width: 50%
|
||||
:align: center
|
||||
|
||||
Unsigned RNode v1.x
|
||||
"""""""""""""""""""
|
||||
- **Transceiver IC** Semtech SX1276 and SX1278
|
||||
- **Device Platform** AVR ATmega1284p
|
||||
- **Manufacturer** `unsigned.io <https://unsigned.io>`_
|
||||
|
||||
------------
|
||||
|
||||
.. _rnode-installation:
|
||||
|
||||
Installation
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Once you have obtained compatible boards, you can install the `RNode Firmware <https://github.com/markqvist/RNode_Firmware>`_
|
||||
using the `RNode Configuration Utility <https://github.com/markqvist/rnodeconfigutil>`_.
|
||||
If you have installed Reticulum on your system, the ``rnodeconf`` program will already be
|
||||
available. If not, make sure that ``Python3`` and ``pip`` is installed on your system, and
|
||||
then install Reticulum with with ``pip``:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install rns
|
||||
|
||||
Once installation has completed, it is time to start installing the firmware on your
|
||||
devices. Run ``rnodeconf`` in auto-install mode like so:
|
||||
|
||||
.. code::
|
||||
|
||||
rnodeconf --autoinstall
|
||||
|
||||
The utility will guide you through the installation process by asking a series of
|
||||
questions about your hardware. Simply follow the guide, and the utility will
|
||||
auto-install and configure your devices.
|
||||
|
||||
.. _rnode-usage:
|
||||
|
||||
Usage with Reticulum
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
When the devices have been installed and provisioned, you can use them with Reticulum
|
||||
by adding the :ref:`relevant interface section<interfaces-rnode>` to the configuration
|
||||
file of Reticulum. In the configuraion you can specify all interface parameters,
|
||||
such as serial port and on-air parameters.
|
||||
|
||||
|
||||
WiFi-based Hardware
|
||||
===================
|
||||
|
||||
It is possible to use all kinds of both short- and long-range WiFi-based hardware
|
||||
with Reticulum. Any kind of hardware that fully supports bridged Ethernet over the
|
||||
WiFi interface will work with the :ref:`AutoInterface<interfaces-auto>` in Reticulum.
|
||||
Most devices will behave like this by default, or allow it via configuration options.
|
||||
|
||||
This means that you can simply configure the physical links of the WiFi based devices,
|
||||
and start communicating over them using Reticulum. It is not necessary to enable any IP
|
||||
infrastructure such as DHCP servers, DNS or similar, as long as at least Ethernet is
|
||||
available, and packets are passed transparently over the physical WiFi-based devices.
|
||||
|
||||
.. only:: html
|
||||
|
||||
.. image:: graphics/radio_rblhg5.png
|
||||
:width: 49%
|
||||
|
||||
.. image:: graphics/radio_is5ac.png
|
||||
:width: 49%
|
||||
|
||||
Below is a list of example WiFi (and similar) radios that work well for high capacity
|
||||
Reticulum links over long distances:
|
||||
|
||||
- `Ubiquiti airMAX radios <https://store.ui.com/collections/operator-airmax-devices>`_
|
||||
- `Ubiquiti LTU radios <https://store.ui.com/collections/operator-ltu>`_
|
||||
- `MikroTik radios <https://mikrotik.com/products/group/wireless-systems>`_
|
||||
|
||||
This list is by no means exhaustive, and only serves as a few examples of radio hardware
|
||||
that is relatively cheap while providing long range and high capacity for Reticulum
|
||||
networks. As in all other cases, it is also possible for Reticulum to co-exist with IP
|
||||
networks running concurrently on such devices.
|
||||
|
||||
Ethernet-based Hardware
|
||||
=======================
|
||||
|
||||
Reticulum can run over any kind of hardware that can provide a switched Ethernet-based
|
||||
medium. This means that anything from a plain Ethernet switch, to fiber-optic systems,
|
||||
to data radios with Ethernet interfaces can be used by Reticulum.
|
||||
|
||||
The Ethernet medium does not need to have any IP infrastructure such as DHCP servers
|
||||
or routing set up, but in case such infrastructure does exist, Reticulum will simply
|
||||
co-exist with.
|
||||
|
||||
To use Reticulum over Ethernet-based mediums, it is generally enough to use the included
|
||||
:ref:`AutoInterface<interfaces-auto>`. This interface also works over any kind of
|
||||
virtual networking adapter, such as ``tun`` and ``tap`` devices in Linux.
|
||||
|
||||
Serial Lines & Devices
|
||||
======================
|
||||
|
||||
Using Reticulum over any kind of raw serial line is also possible with the
|
||||
:ref:`SerialInterface<interfaces-serial>`. This interface type is also useful for
|
||||
using Reticulum over communications hardware that provides a serial port interface.
|
||||
|
||||
Packet Radio Modems
|
||||
===================
|
||||
|
||||
Any packet radio modem that provides a standard KISS interface over USB, serial or TCP
|
||||
can be used with Reticulum. This includes virtual software modems such as
|
||||
`FreeDV TNC <https://github.com/xssfox/freedv-tnc>`_ and `Dire Wolf <https://github.com/wb2osz/direwolf>`_.
|
||||
@@ -0,0 +1,43 @@
|
||||
******************************
|
||||
Reticulum Network Stack Manual
|
||||
******************************
|
||||
|
||||
This manual aims to provide you with all the information you need to
|
||||
understand Reticulum, build networks or develop programs using it, or
|
||||
to participate in the development of Reticulum itself.
|
||||
|
||||
.. only:: builder_html
|
||||
|
||||
This manual is also available in `PDF <https://github.com/markqvist/Reticulum/releases/latest/download/Reticulum.Manual.pdf>`_ and `EPUB <https://github.com/markqvist/Reticulum/releases/latest/download/Reticulum.Manual.epub>`_ formats.
|
||||
|
||||
.. only:: builder_html
|
||||
|
||||
Table Of Contents
|
||||
=================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
whatis
|
||||
gettingstartedfast
|
||||
using
|
||||
understanding
|
||||
hardware
|
||||
interfaces
|
||||
networks
|
||||
examples
|
||||
support
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
reference
|
||||
|
||||
|
||||
.. only:: html
|
||||
|
||||
Indices and Tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,169 @@
|
||||
.. _networks-main:
|
||||
|
||||
*****************
|
||||
Building Networks
|
||||
*****************
|
||||
|
||||
This chapter will provide you with the knowledge needed to build networks with
|
||||
Reticulum, which can often be easier than using traditional stacks, since you
|
||||
don't have to worry about coordinating addresses, subnets and routing for an
|
||||
entire network that you might not know how will evolve in the future. With
|
||||
Reticulum, you can simply add more segments to your network when it becomes
|
||||
necessary, and Reticulum will handle the convergence of the entire network
|
||||
automatically.
|
||||
|
||||
Concepts & Overview
|
||||
--------------------
|
||||
|
||||
There are important points that need to be kept in mind when building networks
|
||||
with Reticulum:
|
||||
|
||||
* | In a Reticulum network, any node can autonomously generate as many addresses
|
||||
(called *destinations* in Reticulum terminology) as it needs, which become
|
||||
globally reachable to the rest of the network. There is no central point of
|
||||
control over the address space.
|
||||
|
||||
* | Reticulum was designed to handle both very small, and very large networks.
|
||||
While the address space can support billions of endpoints, Reticulum is
|
||||
also very useful when just a few devices needs to communicate.
|
||||
|
||||
* | Low-bandwidth networks, like LoRa and packet radio, can interoperate and
|
||||
interconnect with much larger and higher bandwidth networks without issue.
|
||||
Reticulum automatically manages the flow of information to and from various
|
||||
network segments, and when bandwidth is limited, local traffic is prioritised.
|
||||
|
||||
* | Reticulum provides sender/initiator anonymity by default. There is no way
|
||||
to filter traffic or discriminate it based on the source of the traffic.
|
||||
|
||||
* | All traffic is encrypted using ephemeral keys generated by an Elliptic Curve
|
||||
Diffie-Hellman key exchange on Curve25519. There is no way to inspect traffic
|
||||
contents, and no way to prioritise or throttle certain kinds of traffic.
|
||||
All transport and routing layers are thus completely agnostic to traffic type,
|
||||
and will pass all traffic equally.
|
||||
|
||||
* | Reticulum can function both with and without infrastructure. When *transport
|
||||
nodes* are available, they can route traffic over multiple hops for other
|
||||
nodes, and will function as a distributed cryptographic keystore. When there
|
||||
is no transport nodes available, all nodes that are within communication range
|
||||
can still communicate.
|
||||
|
||||
* | Every node can become a transport node, simply by enabling it in it's
|
||||
configuration, but there is no need for every node on the network to be a
|
||||
transport node. Letting every node be a transport node will in most cases
|
||||
degrade the performance and reliability of the network.
|
||||
|
||||
*In general terms, if a node is stationary, well-connected and kept running
|
||||
most of the time, it is a good candidate to be a transport node. For optimal
|
||||
performance, a network should contain the amount of transport nodes that
|
||||
provides connectivity to the intended area / topography, and not many more
|
||||
than that.*
|
||||
|
||||
* | Reticulum is designed to work reliably in open, trustless environments. This
|
||||
means you can use it to create open-access networks, where participants can
|
||||
join and leave in a free and unorganised manner. This property allows an
|
||||
entirely new, and so far, mostly unexplored class of networked applications,
|
||||
where networks, and the information flow within them can form and dissolve
|
||||
organically.
|
||||
|
||||
* | You can just as easily create closed networks, since Reticulum allows you to
|
||||
add authentication to any interface. This means you can restrict access on
|
||||
any interface type, even when using legacy devices, such as modems. You can
|
||||
also mix authenticated and open interfaces on the same system. See the
|
||||
:ref:`Common Interface Options<interfaces-options>` section of the :ref:`Interfaces<interfaces-main>`
|
||||
chapter of this manual for information on how to set up interface authentication.
|
||||
|
||||
|
||||
Reticulum allows you to mix very different kinds of networking mediums into a
|
||||
unified mesh, or to keep everything within one medium. You could build a "virtual
|
||||
network" running entirely over the Internet, where all nodes communicate over TCP
|
||||
and UDP "channels". You could also build such a network using other already-established
|
||||
communications channels as the underlying carrier for Reticulum.
|
||||
|
||||
However, most real-world networks will probably involve either some form of
|
||||
wireless or direct hardline communications. To allow Reticulum to communicate
|
||||
over any type of medium, you must specify it in the configuration file, by default
|
||||
located at ``~/.reticulum/config``. See the :ref:`Supported Interfaces<interfaces-main>`
|
||||
chapter of this manual for interface configuration examples.
|
||||
|
||||
Any number of interfaces can be configured, and Reticulum will automatically
|
||||
decide which are suitable to use in any given situation, depending on where
|
||||
traffic needs to flow.
|
||||
|
||||
Example Scenarios
|
||||
-----------------
|
||||
|
||||
This section illustrates a few example scenarios, and how they would, in general
|
||||
terms, be planned, implemented and configured.
|
||||
|
||||
Interconnected LoRa Sites
|
||||
=========================
|
||||
|
||||
An organisation wants to provide communication and information services to it's
|
||||
members, which are located mainly in three separate areas. Three suitable hill-top
|
||||
locations are found, where the organisation can install equipment: Site A, B and C.
|
||||
|
||||
Since the amount of data that needs to be exchanged between users is mainly text-
|
||||
based, the bandwidth requirements are low, and LoRa radios are chosen to connect
|
||||
users to the network.
|
||||
|
||||
Due to the hill-top locations found, there is radio line-of-sight between site A
|
||||
and B, and also between site B and C. Because of this, the organisation does not
|
||||
need to use the Internet to interconnect the sites, but purchases four Point-to-Point
|
||||
WiFi based radios for interconnecting the sites.
|
||||
|
||||
At each site, a Raspberry Pi is installed to function as a gateway. A LoRa radio
|
||||
is connected to the Pi with a USB cable, and the WiFi radio is connected to the
|
||||
Ethernet port of the Pi. At site B, two WiFi radios are needed to be able to reach
|
||||
both site A and site C, so an extra Ethernet adapter is connected to the Pi in
|
||||
this location.
|
||||
|
||||
Once the hardware has been installed, Reticulum is installed on all the Pis, and at
|
||||
site A and C, one interface is added for the LoRa radio, as well as one for the WiFi
|
||||
radio. At site B, an interface for the LoRa radio, and one interface for each WiFi
|
||||
radio is added to the Reticulum configuration file. The transport node option is
|
||||
enabled in the configuration of all three gateways.
|
||||
|
||||
The network is now operational, and ready to serve users across all three areas.
|
||||
The organisation prepares a LoRa radio that is supplied to the end users, along
|
||||
with a Reticulum configuration file, that contains the right parameters for
|
||||
communicating with the LoRa radios installed at the gateway sites.
|
||||
|
||||
Once users connect to the network, anyone will be able to communicate with anyone
|
||||
else across all three sites.
|
||||
|
||||
Bridging Over the Internet
|
||||
==========================
|
||||
|
||||
As the organisation grows, several new communities form in places too far away
|
||||
from the core network to be reachable over WiFi links. New gateways similar to those
|
||||
previously installed are set up for the new communities at the new sites D and E, but
|
||||
they are islanded from the core network, and only serve the local users.
|
||||
|
||||
After investigating the options, it is found that it is possible to install an
|
||||
Internet connection at site A, and an interface on the Internet connection is
|
||||
configured for Reticulum on the Raspberry Pi at site A.
|
||||
|
||||
A member of the organisation at site D, named Dori, is willing to help by sharing
|
||||
the Internet connection she already has in her home, and is able to leave a Raspberry
|
||||
Pi running. A new Reticulum interface is configured on her Pi, connecting to the newly
|
||||
enabled Internet interface on the gateway at site A. Dori is now connected to both
|
||||
the nodes at her own local site (through the hill-top LoRa gateway), and all the
|
||||
combined users of sites A, B and C. She then enables transport on her node, and
|
||||
traffic from site D can now reach everyone at site A, B and C, and vice versa.
|
||||
|
||||
Growth and Convergence
|
||||
======================
|
||||
|
||||
As the organisation grows, more gateways are added to keep up with the growing user
|
||||
base. Some local gateways even add VHF radios and packet modems to reach outlying users
|
||||
and communities that are out of reach for the LoRa radios and WiFi backhauls.
|
||||
|
||||
As more sites, gateways and users are connected, the amount of coordination required
|
||||
is kept to a minimum. If one community wants to add connectivity to the next one
|
||||
over, it can simply be done without having to involve everyone or coordinate address
|
||||
space or routing tables.
|
||||
|
||||
With the added geographical coverage, the operators at site A one day find that
|
||||
the original internet bridged interfaces are no longer utilised. The network has
|
||||
converged to be completely self-connected, and the sites that were once poorly
|
||||
connected outliers are now an integral part of the network.
|
||||
@@ -0,0 +1,214 @@
|
||||
:tocdepth: 4
|
||||
|
||||
.. _api-main:
|
||||
|
||||
*************
|
||||
API Reference
|
||||
*************
|
||||
Communication over Reticulum networks is achieved by using a simple set of classes exposed by the RNS API.
|
||||
This chapter lists and explains all classes exposed by the Reticulum Network Stack API, along with their method signatures and usage. It can be used as a reference while writing applications that utilise Reticulum, or it can be read in entirity to gain an understanding of the complete functionality of RNS from a developers perspective.
|
||||
|
||||
.. _api-reticulum:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Reticulum |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Reticulum
|
||||
---------
|
||||
|
||||
.. autoclass:: RNS.Reticulum
|
||||
:members:
|
||||
|
||||
|
||||
.. _api-identity:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Identity |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Identity
|
||||
--------
|
||||
|
||||
.. autoclass:: RNS.Identity
|
||||
:members:
|
||||
|
||||
.. _api-destination:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Destination |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Destination
|
||||
-----------
|
||||
|
||||
.. autoclass:: RNS.Destination
|
||||
:members:
|
||||
|
||||
.. _api-packet:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Packet |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Packet
|
||||
------
|
||||
|
||||
.. autoclass:: RNS.Packet(destination, data, create_receipt = True)
|
||||
:members:
|
||||
|
||||
.. _api-packetreceipt:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Packet Receipt |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Packet Receipt
|
||||
--------------
|
||||
|
||||
.. autoclass:: RNS.PacketReceipt()
|
||||
:members:
|
||||
|
||||
.. _api-link:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Link |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Link
|
||||
----
|
||||
|
||||
.. autoclass:: RNS.Link(destination, established_callback=None, closed_callback = None)
|
||||
:members:
|
||||
|
||||
.. _api-requestreceipt:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Request Receipt |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Request Receipt
|
||||
---------------
|
||||
|
||||
.. autoclass:: RNS.RequestReceipt()
|
||||
:members:
|
||||
|
||||
.. _api-resource:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Resource |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Resource
|
||||
--------
|
||||
|
||||
.. autoclass:: RNS.Resource(data, link, advertise=True, auto_compress=True, callback=None, progress_callback=None, timeout=None)
|
||||
:members:
|
||||
|
||||
.. _api-channel:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Channel |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Channel
|
||||
-------
|
||||
|
||||
.. autoclass:: RNS.Channel.Channel()
|
||||
:members:
|
||||
|
||||
.. _api-messsagebase:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| MessageBase |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
MessageBase
|
||||
-----------
|
||||
|
||||
.. autoclass:: RNS.MessageBase()
|
||||
:members:
|
||||
|
||||
.. _api-buffer:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Buffer |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Buffer
|
||||
------
|
||||
|
||||
.. autoclass:: RNS.Buffer
|
||||
:members:
|
||||
|
||||
.. _api-rawchannelreader:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| RawChannelReader |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
RawChannelReader
|
||||
----------------
|
||||
|
||||
.. autoclass:: RNS.RawChannelReader
|
||||
:members: __init__, add_ready_callback, remove_ready_callback
|
||||
|
||||
.. _api-rawchannelwriter:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| RawChannelWriter |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
RawChannelWriter
|
||||
----------------
|
||||
|
||||
.. autoclass:: RNS.RawChannelWriter
|
||||
:members: __init__
|
||||
|
||||
.. _api-transport:
|
||||
|
||||
.. only:: html
|
||||
|
||||
|start-h3| Transport |end-h3|
|
||||
|
||||
.. only:: latex
|
||||
|
||||
Transport
|
||||
---------
|
||||
|
||||
.. autoclass:: RNS.Transport
|
||||
:members:
|
||||
|
||||
.. |start-h3| raw:: html
|
||||
|
||||
<h3>
|
||||
|
||||
.. |end-h3| raw:: html
|
||||
|
||||
</h3>
|
||||
@@ -0,0 +1,44 @@
|
||||
.. _support-main:
|
||||
|
||||
*****************
|
||||
Support Reticulum
|
||||
*****************
|
||||
You can help support the continued development of open, free and private communications
|
||||
systems by donating, providing feedback and contributing code and learning resources.
|
||||
|
||||
Donations
|
||||
=========
|
||||
Donations are gratefully accepted via the following channels:
|
||||
|
||||
|
||||
.. code:: text
|
||||
|
||||
Monero:
|
||||
84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
|
||||
|
||||
Ethereum:
|
||||
0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
|
||||
|
||||
Bitcoin:
|
||||
3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq
|
||||
|
||||
Ko-Fi:
|
||||
https://ko-fi.com/markqvist
|
||||
|
||||
Are certain features in the development roadmap are important to you or your
|
||||
organisation? Make them a reality quickly by sponsoring their implementation.
|
||||
|
||||
Provide Feedback
|
||||
================
|
||||
All feedback on the usage, functioning and potential dysfunctioning of any and
|
||||
all components of the system is very valuable to the continued development and
|
||||
improvement of Reticulum.
|
||||
|
||||
Absolutely no automated analytics, telemetry, error
|
||||
reporting or statistics is collected and reported by Reticulum under any
|
||||
circumstances, so we rely on old-fashioned human feedback.
|
||||
|
||||
Contribute Code
|
||||
===============
|
||||
Join us on `the GitHub repository <https://github.com/markqvist/reticulum>`_ to
|
||||
report issues, suggest functionality and contribute code to Reticulum.
|
||||
@@ -0,0 +1,910 @@
|
||||
.. _understanding-main:
|
||||
|
||||
***********************
|
||||
Understanding Reticulum
|
||||
***********************
|
||||
This chapter will briefly describe the overall purpose and operating principles of Reticulum.
|
||||
It should give you an overview of how the stack works, and an understanding of how to
|
||||
develop networked applications using Reticulum.
|
||||
|
||||
This chapter is not an exhaustive source of information on Reticulum, at least not yet. Currently,
|
||||
the only complete repository, and final authority on how Reticulum actually functions, is the Python
|
||||
reference implementation and API reference. That being said, this chapter is an essential resource in
|
||||
understanding how Reticulum works from a high-level perspective, along with the general principles of
|
||||
Reticulum, and how to apply them when creating your own networks or software.
|
||||
|
||||
After reading this document, you should be well-equipped to understand how a Reticulum network
|
||||
operates, what it can achieve, and how you can use it yourself. If you want to help out with the
|
||||
development, this is also the place to start, since it will provide a pretty clear overview of the
|
||||
sentiments and the philosophy behind Reticulum, what problems it seeks to solve, and how it
|
||||
approaches those solutions.
|
||||
|
||||
.. _understanding-motivation:
|
||||
|
||||
Motivation
|
||||
==========
|
||||
|
||||
The primary motivation for designing and implementing Reticulum has been the current lack of
|
||||
reliable, functional and secure minimal-infrastructure modes of digital communication. It is my
|
||||
belief that it is highly desirable to create a reliable and efficient way to set up long-range digital
|
||||
communication networks that can securely allow exchange of information between people and
|
||||
machines, with no central point of authority, control, censorship or barrier to entry.
|
||||
|
||||
Almost all of the various networking systems in use today share a common limitation: They
|
||||
require large amounts of coordination and centralised trust and power to function. To join such networks, you need approval
|
||||
of gatekeepers in control. This need for coordination and trust inevitably leads to an environment of
|
||||
central control, where it's very easy for infrastructure operators or governments to control or alter
|
||||
traffic, and censor or persecute unwanted actors. It also makes it completely impossible to freely deploy
|
||||
and use networks at will, like one would use other common tools that enhance individual agency and freedom.
|
||||
|
||||
Reticulum aims to require as little coordination and trust as possible. It aims to make secure,
|
||||
anonymous and permissionless networking and information exchange a tool that anyone can just pick up and use.
|
||||
|
||||
Since Reticulum is completely medium agnostic, it can be used to build networks on whatever is best
|
||||
suited to the situation, or whatever you have available. In some cases, this might be packet radio
|
||||
links over VHF frequencies, in other cases it might be a 2.4 GHz
|
||||
network using off-the-shelf radios, or it might be using common LoRa development boards.
|
||||
|
||||
At the time of release of this document, the fastest and easiest setup for development and testing is using
|
||||
LoRa radio modules with an open source firmware (see the section :ref:`Reference Setup<understanding-referencesystem>`),
|
||||
connected to any kind of computer or mobile device that Reticulum can run on.
|
||||
|
||||
The ultimate aim of Reticulum is to allow anyone to be their own network operator, and to make it
|
||||
cheap and easy to cover vast areas with a myriad of independent, interconnectable and autonomous networks.
|
||||
Reticulum **is not** *one network*, it **is a tool** to build *thousands of networks*. Networks without
|
||||
kill-switches, surveillance, censorship and control. Networks that can freely interoperate, associate and disassociate
|
||||
with each other, and require no central oversight. Networks for human beings. *Networks for the people*.
|
||||
|
||||
.. _understanding-goals:
|
||||
|
||||
Goals
|
||||
=====
|
||||
|
||||
To be as widely usable and efficient to deploy as possible, the following goals have been used to
|
||||
guide the design of Reticulum:
|
||||
|
||||
|
||||
* **Fully useable as open source software stack**
|
||||
Reticulum must be implemented with, and be able to run using only open source software. This is
|
||||
critical to ensuring the availability, security and transparency of the system.
|
||||
* **Hardware layer agnosticism**
|
||||
Reticulum must be fully hardware agnostic, and shall be useable over a wide range of
|
||||
physical networking layers, such as data radios, serial lines, modems, handheld transceivers,
|
||||
wired Ethernet, WiFi, or anything else that can carry a digital data stream. Hardware made for
|
||||
dedicated Reticulum use shall be as cheap as possible and use off-the-shelf components, so
|
||||
it can be easily modified and replicated by anyone interested in doing so.
|
||||
* **Very low bandwidth requirements**
|
||||
Reticulum should be able to function reliably over links with a transmission capacity as low
|
||||
as *5 bits per second*.
|
||||
* **Encryption by default**
|
||||
Reticulum must use strong encryption by default for all communication.
|
||||
* **Initiator Anonymity**
|
||||
It must be possible to communicate over a Reticulum network without revealing any identifying
|
||||
information about oneself.
|
||||
* **Unlicensed use**
|
||||
Reticulum shall be functional over physical communication mediums that do not require any
|
||||
form of license to use. Reticulum must be designed in a way, so it is usable over ISM radio
|
||||
frequency bands, and can provide functional long distance links in such conditions, for example
|
||||
by connecting a modem to a PMR or CB radio, or by using LoRa or WiFi modules.
|
||||
* **Supplied software**
|
||||
In addition to the core networking stack and API, that allows a developer to build
|
||||
applications with Reticulum, a basic set of Reticulum-based communication tools must be
|
||||
implemented and released along with Reticulum itself. These shall serve both as a
|
||||
functional, basic communication suite, and as an example and learning resource to others wishing
|
||||
to build applications with Reticulum.
|
||||
* **Ease of use**
|
||||
The reference implementation of Reticulum is written in Python, to make it easy to use
|
||||
and understand. A programmer with only basic experience should be able to use
|
||||
Reticulum to write networked applications.
|
||||
* **Low cost**
|
||||
It shall be as cheap as possible to deploy a communication system based on Reticulum. This
|
||||
should be achieved by using cheap off-the-shelf hardware that potential users might already
|
||||
own. The cost of setting up a functioning node should be less than $100 even if all parts
|
||||
needs to be purchased.
|
||||
|
||||
.. _understanding-basicfunctionality:
|
||||
|
||||
Introduction & Basic Functionality
|
||||
==================================
|
||||
|
||||
Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
|
||||
core a *message oriented* system. It is suited for both local point-to-point or point-to-multipoint
|
||||
scenarios where all nodes are within range of each other, as well as scenarios where packets need
|
||||
to be transported over multiple hops in a complex network to reach the recipient.
|
||||
|
||||
Reticulum does away with the idea of addresses and ports known from IP, TCP and UDP. Instead
|
||||
Reticulum uses the singular concept of *destinations*. Any application using Reticulum as its
|
||||
networking stack will need to create one or more destinations to receive data, and know the
|
||||
destinations it needs to send data to.
|
||||
|
||||
All destinations in Reticulum are _represented_ as a 16 byte hash. This hash is derived from truncating a full
|
||||
SHA-256 hash of identifying characteristics of the destination. To users, the destination addresses
|
||||
will be displayed as 16 hexadecimal bytes, like this example: ``<13425ec15b621c1d928589718000d814>``.
|
||||
|
||||
The truncation size of 16 bytes (128 bits) for destinations has been chosen as a reasonable trade-off
|
||||
between address space
|
||||
and packet overhead. The address space accommodated by this size can support many billions of
|
||||
simultaneously active devices on the same network, while keeping packet overhead low, which is
|
||||
essential on low-bandwidth networks. In the very unlikely case that this address space nears
|
||||
congestion, a one-line code change can upgrade the Reticulum address space all the way up to 256
|
||||
bits, ensuring the Reticulum address space could potentially support galactic-scale networks.
|
||||
This is obviously complete and ridiculous over-allocation, and as such, the current 128 bits should
|
||||
be sufficient, even far into the future.
|
||||
|
||||
By default Reticulum encrypts all data using elliptic curve cryptography and AES. Any packet sent to a
|
||||
destination is encrypted with a per-packet derived key. Reticulum can also set up an encrypted
|
||||
channel to a destination, called a *Link*. Both data sent over Links and single packets offer
|
||||
*Initiator Anonymity*. Links additionally offer *Forward Secrecy* by default, employing an Elliptic Curve
|
||||
Diffie Hellman key exchange on Curve25519 to derive per-link ephemeral keys. Asymmetric, link-less
|
||||
packet communication can also provide forward secrecy, with automatic key ratcheting, by enabling
|
||||
ratchets on a per-destination basis. The multi-hop transport, coordination, verification and reliability
|
||||
layers are fully autonomous and also based on elliptic curve cryptography.
|
||||
|
||||
Reticulum also offers symmetric key encryption for group-oriented communications, as well as
|
||||
unencrypted packets for local broadcast purposes.
|
||||
|
||||
Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports,
|
||||
and offers the possibility to easily tunnel Reticulum traffic over IP links such as the Internet or
|
||||
private IP networks.
|
||||
|
||||
.. _understanding-destinations:
|
||||
|
||||
Destinations
|
||||
------------
|
||||
|
||||
To receive and send data with the Reticulum stack, an application needs to create one or more
|
||||
destinations. Reticulum uses three different basic destination types, and one special:
|
||||
|
||||
|
||||
* **Single**
|
||||
The *single* destination type is the most common type in Reticulum, and should be used for
|
||||
most purposes. It is always identified by a unique public key. Any data sent to this
|
||||
destination will be encrypted using ephemeral keys derived from an ECDH key exchange, and will
|
||||
only be readable by the creator of the destination, who holds the corresponding private key.
|
||||
* **Plain**
|
||||
A *plain* destination type is unencrypted, and suited for traffic that should be broadcast to a
|
||||
number of users, or should be readable by anyone. Traffic to a *plain* destination is not encrypted.
|
||||
Generally, *plain* destinations can be used for broadcast information intended to be public.
|
||||
Plain destinations are only reachable directly, and packets addressed to plain destinations are
|
||||
never transported over multiple hops in the network. To be transportable over multiple hops in Reticulum, information
|
||||
*must* be encrypted, since Reticulum uses the per-packet encryption to verify routing paths and
|
||||
keep them alive.
|
||||
* **Group**
|
||||
The *group* special destination type, that defines a symmetrically encrypted virtual destination.
|
||||
Data sent to this destination will be encrypted with a symmetric key, and will be readable by
|
||||
anyone in possession of the key, but as with the *plain* destination type, packets to this type
|
||||
of destination are not currently transported over multiple hops, although a planned upgrade
|
||||
to Reticulum will allow globally reachable *group* destinations.
|
||||
* **Link**
|
||||
A *link* is a special destination type, that serves as an abstract channel to a *single*
|
||||
destination, directly connected or over multiple hops. The *link* also offers reliability and
|
||||
more efficient encryption, forward secrecy, initiator anonymity, and as such can be useful even
|
||||
when a node is directly reachable. It also offers a more capable API and allows easily carrying
|
||||
out requests and responses, large data transfers and more.
|
||||
|
||||
.. _understanding-destinationnaming:
|
||||
|
||||
Destination Naming
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Destinations are created and named in an easy to understand dotted notation of *aspects*, and
|
||||
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 128 bits. The
|
||||
top level aspect should always be a unique identifier for the application using the destination.
|
||||
The next levels of aspects can be defined in any way by the creator of the application.
|
||||
|
||||
Aspects can be as long and as plentiful as required, and a resulting long destination name will not
|
||||
impact efficiency, as names are always represented as truncated SHA-256 hashes on the network.
|
||||
|
||||
As an example, a destination for a environmental monitoring application could be made up of the
|
||||
application name, a device type and measurement type, like this:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
app name : environmentlogger
|
||||
aspects : remotesensor, temperature
|
||||
|
||||
full name : environmentlogger.remotesensor.temperature
|
||||
hash : 4faf1b2e0a077e6a9d92fa051f256038
|
||||
|
||||
For the *single* destination, Reticulum will automatically append the associated public key as a
|
||||
destination aspect before hashing. This is done to ensure only the correct destination is reached,
|
||||
since anyone can listen to any destination name. Appending the public key ensures that a given
|
||||
packet is only directed at the destination that holds the corresponding private key to decrypt the
|
||||
packet.
|
||||
|
||||
**Take note!** There is a very important concept to understand here:
|
||||
|
||||
* Anyone can use the destination name ``environmentlogger.remotesensor.temperature``
|
||||
|
||||
* Each destination that does so will still have a unique destination hash, and thus be uniquely
|
||||
addressable, because their public keys will differ.
|
||||
|
||||
In actual use of *single* destination naming, it is advisable not to use any uniquely identifying
|
||||
features in aspect naming. Aspect names should be general terms describing what kind of destination
|
||||
is represented. The uniquely identifying aspect is always achieved by appending the public key,
|
||||
which expands the destination into a uniquely identifiable one. Reticulum does this automatically.
|
||||
|
||||
Any destination on a Reticulum network can be addressed and reached simply by knowing its
|
||||
destination hash (and public key, but if the public key is not known, it can be requested from the
|
||||
network simply by knowing the destination hash). The use of app names and aspects makes it easy to
|
||||
structure Reticulum programs and makes it possible to filter what information and data your program
|
||||
receives.
|
||||
|
||||
To recap, the different destination types should be used in the following situations:
|
||||
|
||||
* **Single**
|
||||
When private communication between two endpoints is needed. Supports multiple hops.
|
||||
* **Group**
|
||||
When private communication between two or more endpoints is needed. Supports multiple hops
|
||||
indirectly, but must first be established through a *single* destination.
|
||||
* **Plain**
|
||||
When plain-text communication is desirable, for example when broadcasting information, or for local discovery purposes.
|
||||
|
||||
To communicate with a *single* destination, you need to know its public key. Any method for
|
||||
obtaining the public key is valid, but Reticulum includes a simple mechanism for making other
|
||||
nodes aware of your destinations public key, called the *announce*. It is also possible to request
|
||||
an unknown public key from the network, as all transport instances serve as a distributed ledger
|
||||
of public keys.
|
||||
|
||||
Note that public key information can be shared and verified in other ways than using the
|
||||
built-in *announce* functionality, and that it is therefore not required to use the *announce* and *path request*
|
||||
functionality to obtain public keys. It is by far the easiest though, and should definitely be used
|
||||
if there is not a very good reason for doing it differently.
|
||||
|
||||
.. _understanding-keyannouncements:
|
||||
|
||||
Public Key Announcements
|
||||
------------------------
|
||||
|
||||
An *announce* will send a special packet over any relevant interfaces, containing all needed
|
||||
information about the destination hash and public key, and can also contain some additional,
|
||||
application specific data. The entire packet is signed by the sender to ensure authenticity. It is not
|
||||
required to use the announce functionality, but in many cases it will be the simplest way to share
|
||||
public keys on the network. The announce mechanism also serves to establish end-to-end connectivity
|
||||
to the announced destination, as the announce propagates through the network.
|
||||
|
||||
As an example, an announce in a simple messenger application might contain the following information:
|
||||
|
||||
|
||||
* The announcers destination hash
|
||||
* The announcers public key
|
||||
* Application specific data, in this case the users nickname and availability status
|
||||
* A random blob, making each new announce unique
|
||||
* An Ed25519 signature of the above information, verifying authenticity
|
||||
|
||||
With this information, any Reticulum node that receives it will be able to reconstruct an outgoing
|
||||
destination to securely communicate with that destination. You might have noticed that there is one
|
||||
piece of information lacking to reconstruct full knowledge of the announced destination, and that is
|
||||
the aspect names of the destination. These are intentionally left out to save bandwidth, since they
|
||||
will be implicit in almost all cases. The receiving application will already know them. If a destination
|
||||
name is not entirely implicit, information can be included in the application specific data part that
|
||||
will allow the receiver to infer the naming.
|
||||
|
||||
It is important to note that announces will be forwarded throughout the network according to a
|
||||
certain pattern. This will be detailed in the section
|
||||
:ref:`The Announce Mechanism in Detail<understanding-announce>`.
|
||||
|
||||
In Reticulum, destinations are allowed to move around the network at will. This is very different from
|
||||
protocols such as IP, where an address is always expected to stay within the network segment it was assigned in.
|
||||
This limitation does not exist in Reticulum, and any destination is *completely portable* over the entire topography
|
||||
of the network, and *can even be moved to other Reticulum networks* than the one it was created in, and
|
||||
still become reachable. To update its reachability, a destination simply needs to send an announce on any
|
||||
networks it is part of. After a short while, it will be globally reachable in the network.
|
||||
|
||||
Seeing how *single* destinations are always tied to a private/public key pair leads us to the next topic.
|
||||
|
||||
.. _understanding-identities:
|
||||
|
||||
Identities
|
||||
----------
|
||||
|
||||
In Reticulum, an *identity* does not necessarily represent a personal identity, but is an abstraction that
|
||||
can represent any kind of *verifiable entity*. This could very well be a person, but it could also be the
|
||||
control interface of a machine, a program, robot, computer, sensor or something else entirely. In
|
||||
general, any kind of agent that can act, or be acted upon, or store or manipulate information, can be
|
||||
represented as an identity. An *identity* can be used to create any number of destinations.
|
||||
|
||||
A *single* destination will always have an *identity* tied to it, but not *plain* or *group*
|
||||
destinations. Destinations and identities share a multilateral connection. You can create a
|
||||
destination, and if it is not connected to an identity upon creation, it will just create a new one to use
|
||||
automatically. This may be desirable in some situations, but often you will probably want to create
|
||||
the identity first, and then use it to create new destinations.
|
||||
|
||||
As an example, we could use an identity to represent the user of a messaging application.
|
||||
Destinations can then be created by this identity to allow communication to reach the user.
|
||||
In all cases it is of great importance to store the private keys associated with any
|
||||
Reticulum Identity securely and privately, since obtaining access to the identity keys equals
|
||||
obtaining access and controlling reachability to any destinations created by that identity.
|
||||
|
||||
.. _understanding-gettingfurther:
|
||||
|
||||
Getting Further
|
||||
---------------
|
||||
|
||||
The above functions and principles form the core of Reticulum, and would suffice to create
|
||||
functional networked applications in local clusters, for example over radio links where all interested
|
||||
nodes can directly hear each other. But to be truly useful, we need a way to direct traffic over multiple
|
||||
hops in the network.
|
||||
|
||||
In the following sections, two concepts that allow this will be introduced, *paths* and *links*.
|
||||
|
||||
.. _understanding-transport:
|
||||
|
||||
Reticulum Transport
|
||||
===================
|
||||
|
||||
The methods of routing used in traditional networks are fundamentally incompatible with the physical medium
|
||||
types and circumstances that Reticulum was designed to handle. These mechanisms mostly assume trust at the physical layer,
|
||||
and often needs a lot more bandwidth than Reticulum can assume is available. Since Reticulum is designed to
|
||||
survive running over open radio spectrum, no such trust can be assumed, and bandwidth is often very limited.
|
||||
|
||||
To overcome such challenges, Reticulum’s *Transport* system uses asymmetric elliptic curve cryptography to
|
||||
implement the concept of *paths* that allow discovery of how to get information closer to a certain
|
||||
destination. It is important to note that no single node in a Reticulum network knows the complete
|
||||
path to a destination. Every Transport node participating in a Reticulum network will only
|
||||
know the most direct way to get a packet one hop closer to it's destination.
|
||||
|
||||
|
||||
.. _understanding-nodetypes:
|
||||
|
||||
Node Types
|
||||
----------
|
||||
|
||||
Currently, Reticulum distinguishes between two types of network nodes. All nodes on a Reticulum network
|
||||
are *Reticulum Instances*, and some are also *Transport Nodes*. If a system running Reticulum is fixed in
|
||||
one place, and is intended to be kept available most of the time, it is a good contender to be a *Transport Node*.
|
||||
|
||||
Any Reticulum Instance can become a Transport Node by enabling it in the configuration.
|
||||
This distinction is made by the user configuring the node, and is used to determine what nodes on the
|
||||
network will help forward traffic, and what nodes rely on other nodes for wider connectivity.
|
||||
|
||||
If a node is an *Instance* it should be given the configuration directive ``enable_transport = No``, which
|
||||
is the default setting.
|
||||
|
||||
If it is a *Transport Node*, it should be given the configuration directive ``enable_transport = Yes``.
|
||||
|
||||
|
||||
.. _understanding-announce:
|
||||
|
||||
The Announce Mechanism in Detail
|
||||
--------------------------------
|
||||
|
||||
When an *announce* for a destination is transmitted by a Reticulum instance, it will be forwarded by
|
||||
any transport node receiving it, but according to some specific rules:
|
||||
|
||||
|
||||
* | If this exact announce has already been received before, ignore it.
|
||||
|
||||
* | If not, record into a table which Transport Node the announce was received from, and how many times in
|
||||
total it has been retransmitted to get here.
|
||||
|
||||
* | If the announce has been retransmitted *m+1* times, it will not be forwarded any more. By default, *m* is
|
||||
set to 128.
|
||||
|
||||
* | After a randomised delay, the announce will be retransmitted on all interfaces that have bandwidth
|
||||
available for processing announces. By default, the maximum bandwidth allocation for processing
|
||||
announces is set at 2%, but can be configured on a per-interface basis.
|
||||
|
||||
* | If any given interface does not have enough bandwidth available for retransmitting the announce,
|
||||
the announce will be assigned a priority inversely proportional to its hop count, and be inserted
|
||||
into a queue managed by the interface.
|
||||
|
||||
* | When the interface has bandwidth available for processing an announce, it will prioritise announces
|
||||
for destinations that are closest in terms of hops, thus prioritising reachability and connectivity
|
||||
of local nodes, even on slow networks that connect to wider and faster networks.
|
||||
|
||||
* | After the announce has been re-transmitted, and if no other nodes are heard retransmitting the announce
|
||||
with a greater hop count than when it left this node, transmitting it will be retried *r* times. By default,
|
||||
*r* is set to 1.
|
||||
|
||||
* | If a newer announce from the same destination arrives, while an identical one is already waiting
|
||||
to be transmitted, the newest announce is discarded. If the newest announce contains different
|
||||
application specific data, it will replace the old announce.
|
||||
|
||||
Once an announce has reached a node in the network, any other node in direct contact with that
|
||||
node will be able to reach the destination the announce originated from, simply by sending a packet
|
||||
addressed to that destination. Any node with knowledge of the announce will be able to direct the
|
||||
packet towards the destination by looking up the next node with the shortest amount of hops to the
|
||||
destination.
|
||||
|
||||
According to these rules, an announce will propagate throughout the network in a predictable way,
|
||||
and make the announced destination reachable in a short amount of time. Fast networks that have the
|
||||
capacity to process many announces can reach full convergence very quickly, even when constantly adding
|
||||
new destinations. Slower segments of such networks might take a bit longer to gain full knowledge about
|
||||
the wide and fast networks they are connected to, but can still do so over time, while prioritising full
|
||||
and quickly converging end-to-end connectivity for their local, slower segments.
|
||||
|
||||
In general, even extremely complex networks, that utilize the maximum 128 hops will converge to full
|
||||
end-to-end connectivity in about one minute, given there is enough bandwidth available to process
|
||||
the required amount of announces.
|
||||
|
||||
.. _understanding-paths:
|
||||
|
||||
Reaching the Destination
|
||||
------------------------
|
||||
|
||||
In networks with changing topology and trustless connectivity, nodes need a way to establish
|
||||
*verified connectivity* with each other. Since the network is assumed to be trustless, Reticulum
|
||||
must provide a way to guarantee that the peer you are communicating with is actually who you
|
||||
expect. Reticulum offers two ways to do this.
|
||||
|
||||
For exchanges of small amounts of information, Reticulum offers the *Packet* API, which works exactly like you would expect - on a per packet level. The following process is employed when sending a packet:
|
||||
|
||||
* | A packet is always created with an associated destination and some payload data. When the packet is sent
|
||||
to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform
|
||||
an ECDH key exchange with the destination's public key (or ratchet key, if available), and encrypt the information.
|
||||
|
||||
* | It is important to note that this key exchange does not require any network traffic. The sender already
|
||||
knows the public key of the destination from an earlier received *announce*, and can thus perform the ECDH
|
||||
key exchange locally, before sending the packet.
|
||||
|
||||
* | The public part of the newly generated ephemeral key-pair is included with the encrypted token, and sent
|
||||
along with the encrypted payload data in the packet.
|
||||
|
||||
* | When the destination receives the packet, it can itself perform an ECDH key exchange and decrypt the
|
||||
packet.
|
||||
|
||||
* | A new ephemeral key is used for every packet sent in this way.
|
||||
|
||||
* | Once the packet has been received and decrypted by the addressed destination, that destination can opt
|
||||
to *prove* its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
|
||||
and signing this hash with its Ed25519 signing key. Transport nodes in the network can then direct this
|
||||
*proof* back to the packets origin, where the signature can be verified against the destination's known
|
||||
public signing key.
|
||||
|
||||
* | In case the packet is addressed to a *group* destination type, the packet will be encrypted with the
|
||||
pre-shared AES-128 key associated with the destination. In case the packet is addressed to a *plain*
|
||||
destination type, the payload data will not be encrypted. Neither of these two destination types can offer
|
||||
forward secrecy. In general, it is recommended to always use the *single* destination type, unless it is
|
||||
strictly necessary to use one of the others.
|
||||
|
||||
|
||||
For exchanges of larger amounts of data, or when longer sessions of bidirectional communication is desired, Reticulum offers the *Link* API. To establish a *link*, the following process is employed:
|
||||
|
||||
* | First, the node that wishes to establish a link will send out a special packet, that
|
||||
traverses the network and locates the desired destination. Along the way, the Transport Nodes that
|
||||
forward the packet will take note of this *link request*.
|
||||
|
||||
* | Second, if the destination accepts the *link request* , it will send back a packet that proves the
|
||||
authenticity of its identity (and the receipt of the link request) to the initiating node. All
|
||||
nodes that initially forwarded the packet will also be able to verify this proof, and thus
|
||||
accept the validity of the *link* throughout the network.
|
||||
|
||||
* | When the validity of the *link* has been accepted by forwarding nodes, these nodes will
|
||||
remember the *link* , and it can subsequently be used by referring to a hash representing it.
|
||||
|
||||
* | As a part of the *link request*, an Elliptic Curve Diffie-Hellman key exchange takes place, that sets up an
|
||||
efficiently encrypted tunnel between the two nodes. As such, this mode of communication is preferred,
|
||||
even for situations when nodes can directly communicate, when the amount of data to be exchanged numbers
|
||||
in the tens of packets, or whenever the use of the more advanced API functions is desired.
|
||||
|
||||
* | When a *link* has been set up, it automatically provides message receipt functionality, through
|
||||
the same *proof* mechanism discussed before, so the sending node can obtain verified confirmation
|
||||
that the information reached the intended recipient.
|
||||
|
||||
* | Once the *link* has been set up, the initiator can remain anonymous, or choose to authenticate towards
|
||||
the destination using a Reticulum Identity. This authentication is happening inside the encrypted
|
||||
link, and is only revealed to the verified destination, and no intermediaries.
|
||||
|
||||
In a moment, we will discuss the details of how this methodology is
|
||||
implemented, but let’s first recap what purposes this methodology serves. We
|
||||
first ensure that the node answering our request is actually the one we want to
|
||||
communicate with, and not a malicious actor pretending to be so. At the same
|
||||
time we establish an efficient encrypted channel. The setup of this is
|
||||
relatively cheap in terms of bandwidth, so it can be used just for a short
|
||||
exchange, and then recreated as needed, which will also rotate encryption keys.
|
||||
The link can also be kept alive for longer periods of time, if this is more
|
||||
suitable to the application. The procedure also inserts the *link id* , a hash
|
||||
calculated from the link request packet, into the memory of forwarding nodes,
|
||||
which means that the communicating nodes can thereafter reach each other simply
|
||||
by referring to this *link id*.
|
||||
|
||||
The combined bandwidth cost of setting up a link is 3 packets totalling 297 bytes (more info in the
|
||||
:ref:`Binary Packet Format<understanding-packetformat>` section). The amount of bandwidth used on keeping
|
||||
a link open is practically negligible, at 0.45 bits per second. Even on a slow 1200 bits per second packet
|
||||
radio channel, 100 concurrent links will still leave 96% channel capacity for actual data.
|
||||
|
||||
|
||||
Link Establishment in Detail
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
After exploring the basics of the announce mechanism, finding a path through the network, and an overview
|
||||
of the link establishment procedure, this section will go into greater detail about the Reticulum link
|
||||
establishment process.
|
||||
|
||||
The *link* in Reticulum terminology should not be viewed as a direct node-to-node link on the
|
||||
physical layer, but as an abstract channel, that can be open for any amount of time, and can span
|
||||
an arbitrary number of hops, where information will be exchanged between two nodes.
|
||||
|
||||
|
||||
* | When a node in the network wants to establish verified connectivity with another node, it
|
||||
will randomly generate a new X25519 private/public key pair. It then creates a *link request*
|
||||
packet, and broadcast it.
|
||||
|
|
||||
| *It should be noted that the X25519 public/private keypair mentioned above is two separate keypairs:
|
||||
An encryption key pair, used for derivation of a shared symmetric key, and a signing key pair, used
|
||||
for signing and verifying messages on the link. They are sent together over the wire, and can be
|
||||
considered as single public key for simplicity in this explanation.*
|
||||
|
||||
* | The *link request* is addressed to the destination hash of the desired destination, and
|
||||
contains the following data: The newly generated X25519 public key *LKi*.
|
||||
|
||||
* | The broadcasted packet will be directed through the network according to the rules laid out
|
||||
previously.
|
||||
|
||||
* | Any node that forwards the link request will store a *link id* in it’s *link table* , along with the
|
||||
amount of hops the packet had taken when received. The link id is a hash of the entire link
|
||||
request packet. If the link request packet is not *proven* by the addressed destination within some
|
||||
set amount of time, the entry will be dropped from the *link table* again.
|
||||
|
||||
* | When the destination receives the link request packet, it will decide whether to accept the request.
|
||||
If it is accepted, the destination will also generate a new X25519 private/public key pair, and
|
||||
perform a Diffie Hellman Key Exchange, deriving a new symmetric key that will be used to encrypt the
|
||||
channel, once it has been established.
|
||||
|
||||
* | A *link proof* packet is now constructed and transmitted over the network. This packet is
|
||||
addressed to the *link id* of the *link*. It contains the following data: The newly generated X25519
|
||||
public key *LKr* and an Ed25519 signature of the *link id* and *LKr* made by the *original signing key* of
|
||||
the addressed destination.
|
||||
|
||||
* | By verifying this *link proof* packet, all nodes that originally transported the *link request*
|
||||
packet to the destination from the originator can now verify that the intended destination received
|
||||
the request and accepted it, and that the path they chose for forwarding the request was valid.
|
||||
In successfully carrying out this verification, the transporting nodes marks the link as active.
|
||||
An abstract bi-directional communication channel has now been established along a path in the network.
|
||||
Packets can now be exchanged bi-directionally from either end of the link simply by adressing the
|
||||
packets to the *link id* of the link.
|
||||
|
||||
* | When the source receives the *proof* , it will know unequivocally that a verified path has been
|
||||
established to the destination. It can now also use the X25519 public key contained in the
|
||||
*link proof* to perform it's own Diffie Hellman Key Exchange and derive the symmetric key
|
||||
that is used to encrypt the channel. Information can now be exchanged reliably and securely.
|
||||
|
||||
|
||||
It’s important to note that this methodology ensures that the source of the request does not need to
|
||||
reveal any identifying information about itself. The link initiator remains completely anonymous.
|
||||
|
||||
When using *links*, Reticulum will automatically verify all data sent over the link, and can also
|
||||
automate retransmissions if *Resources* are used.
|
||||
|
||||
.. _understanding-resources:
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
For exchanging small amounts of data over a Reticulum network, the :ref:`Packet<api-packet>` interface
|
||||
is sufficient, but for exchanging data that would require many packets, an efficient way to coordinate
|
||||
the transfer is needed.
|
||||
|
||||
This is the purpose of the Reticulum :ref:`Resource<api-resource>`. A *Resource* can automatically
|
||||
handle the reliable transfer of an arbitrary amount of data over an established :ref:`Link<api-link>`.
|
||||
Resources can auto-compress data, will handle breaking the data into individual packets, sequencing
|
||||
the transfer, integrity verification and reassembling the data on the other end.
|
||||
|
||||
:ref:`Resources<api-resource>` are programmatically very simple to use, and only requires a few lines
|
||||
of codes to reliably transfer any amount of data. They can be used to transfer data stored in memory,
|
||||
or stream data directly from files.
|
||||
|
||||
.. _understanding-referencesystem:
|
||||
|
||||
Reference Setup
|
||||
======================
|
||||
|
||||
This section will detail a recommended *Reference Setup* for Reticulum. It is important to
|
||||
note that Reticulum is designed to be usable on more or less any computing device, and over more
|
||||
or less any medium that allows you to send and receive data, which satisfies some very low
|
||||
minimum requirements.
|
||||
|
||||
The communication channel must support at least half-duplex operation, and provide an average
|
||||
throughput of 5 bits per second or greater, and supports a physical layer MTU of 500 bytes. The
|
||||
Reticulum stack should be able to run on more or less any hardware that can provide a Python 3.x
|
||||
runtime environment.
|
||||
|
||||
That being said, this reference setup has been outlined to provide a common platform for anyone
|
||||
who wants to help in the development of Reticulum, and for everyone who wants to know a
|
||||
recommended setup to get started experimenting. A reference system consists of three parts:
|
||||
|
||||
* **An Interface Device**
|
||||
Which provides access to the physical medium whereupon the communication
|
||||
takes place, for example a radio with an integrated modem. A setup with a separate modem
|
||||
connected to a radio would also be an interface device.
|
||||
* **A Host Device**
|
||||
Some sort of computing device that can run the necessary software, communicate with the
|
||||
interface device, and provide user interaction.
|
||||
* **A Software Stack**
|
||||
The software implementing the Reticulum protocol and applications using it.
|
||||
|
||||
The reference setup can be considered a relatively stable platform to develop on, and also to start
|
||||
building networks or applications on. While details of the implementation might change at the current stage of
|
||||
development, it is the goal to maintain hardware compatibility for as long as entirely possible, and
|
||||
the current reference setup has been determined to provide a functional platform for many years
|
||||
into the future. The current Reference System Setup is as follows:
|
||||
|
||||
|
||||
* **Interface Device**
|
||||
A data radio consisting of a LoRa radio module, and a microcontroller with open source
|
||||
firmware, that can connect to host devices via USB. It operates in either the 430, 868 or 900
|
||||
MHz frequency bands. More details can be found on the `RNode Page <https://unsigned.io/rnode>`_.
|
||||
* **Host Device**
|
||||
Any computer device running Linux and Python. A Raspberry Pi with a Debian based OS is
|
||||
recommended.
|
||||
* **Software Stack**
|
||||
The most recently released Python Implementation of Reticulum, running on a Debian based
|
||||
operating system.
|
||||
|
||||
To avoid confusion, it is very important to note, that the reference interface device **does not**
|
||||
use the LoRaWAN standard, but uses a custom MAC layer on top of the plain LoRa modulation! As such, you will
|
||||
need a plain LoRa radio module connected to an controller with the correct firmware. Full details on how to
|
||||
get or make such a device is available on the `RNode Page <https://unsigned.io/rnode>`_.
|
||||
|
||||
With the current reference setup, it should be possible to get on a Reticulum network for around 100$
|
||||
even if you have none of the hardware already, and need to purchase everything.
|
||||
|
||||
This reference setup is of course just a recommendation for getting started easily, and you should
|
||||
tailor it to your own specific needs, or whatever hardware you have available.
|
||||
|
||||
.. _understanding-protocolspecifics:
|
||||
|
||||
Protocol Specifics
|
||||
==================
|
||||
|
||||
This chapter will detail protocol specific information that is essential to the implementation of
|
||||
Reticulum, but non critical in understanding how the protocol works on a general level. It should be
|
||||
treated more as a reference than as essential reading.
|
||||
|
||||
|
||||
Packet Prioritisation
|
||||
---------------------
|
||||
|
||||
Currently, Reticulum is completely priority-agnostic regarding general traffic. All traffic is handled
|
||||
on a first-come, first-serve basis. Announce re-transmission are handled according to the re-transmission
|
||||
times and priorities described earlier in this chapter.
|
||||
|
||||
|
||||
Interface Access Codes
|
||||
----------------------
|
||||
|
||||
Reticulum can create named virtual networks, and networks that are only accessible by knowing a preshared
|
||||
passphrase. The configuration of this is detailed in the :ref:`Common Interface Options<interfaces-options>`
|
||||
section. To implement these feature, Reticulum uses the concept of Interface Access Codes, that are calculated
|
||||
and verified per packet.
|
||||
|
||||
An interface with a named virtual network or passphrase authentication enabled will derive a shared Ed25519
|
||||
signing identity, and for every outbound packet generate a signature of the entire packet. This signature is
|
||||
then inserted into the packet as an Interface Access Code before transmission. Depending on the speed and
|
||||
capabilities of the interface, the IFAC can be the full 512-bit Ed25519 signature, or a truncated version.
|
||||
Configured IFAC length can be inspected for all interfaces with the ``rnstatus`` utility.
|
||||
|
||||
Upon receipt, the interface will check that the signature matches the expected value, and drop the packet if it
|
||||
does not. This ensures that only packets sent with the correct naming and/or passphrase parameters are allowed to
|
||||
pass onto the network.
|
||||
|
||||
|
||||
.. _understanding-packetformat:
|
||||
|
||||
Wire Format
|
||||
-----------
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
== Reticulum Wire Format ======
|
||||
|
||||
A Reticulum packet is composed of the following fields:
|
||||
|
||||
[HEADER 2 bytes] [ADDRESSES 16/32 bytes] [CONTEXT 1 byte] [DATA 0-465 bytes]
|
||||
|
||||
* The HEADER field is 2 bytes long.
|
||||
* Byte 1: [IFAC Flag], [Header Type], [Context Flag], [Propagation Type],
|
||||
[Destination Type] and [Packet Type]
|
||||
* Byte 2: Number of hops
|
||||
|
||||
* Interface Access Code field if the IFAC flag was set.
|
||||
* The length of the Interface Access Code can vary from
|
||||
1 to 64 bytes according to physical interface
|
||||
capabilities and configuration.
|
||||
|
||||
* The ADDRESSES field contains either 1 or 2 addresses.
|
||||
* Each address is 16 bytes long.
|
||||
* The Header Type flag in the HEADER field determines
|
||||
whether the ADDRESSES field contains 1 or 2 addresses.
|
||||
* Addresses are SHA-256 hashes truncated to 16 bytes.
|
||||
|
||||
* The CONTEXT field is 1 byte.
|
||||
* It is used by Reticulum to determine packet context.
|
||||
|
||||
* The DATA field is between 0 and 465 bytes.
|
||||
* It contains the packets data payload.
|
||||
|
||||
IFAC Flag
|
||||
-----------------
|
||||
open 0 Packet for publically accessible interface
|
||||
authenticated 1 Interface authentication is included in packet
|
||||
|
||||
|
||||
Header Types
|
||||
-----------------
|
||||
type 1 0 Two byte header, one 16 byte address field
|
||||
type 2 1 Two byte header, two 16 byte address fields
|
||||
|
||||
|
||||
Context Flag
|
||||
-----------------
|
||||
unset 0 The context flag is used for various types
|
||||
set 1 of signalling, depending on packet context
|
||||
|
||||
|
||||
Propagation Types
|
||||
-----------------
|
||||
broadcast 0
|
||||
transport 1
|
||||
|
||||
|
||||
Destination Types
|
||||
-----------------
|
||||
single 00
|
||||
group 01
|
||||
plain 10
|
||||
link 11
|
||||
|
||||
|
||||
Packet Types
|
||||
-----------------
|
||||
data 00
|
||||
announce 01
|
||||
link request 10
|
||||
proof 11
|
||||
|
||||
|
||||
+- Packet Example -+
|
||||
|
||||
HEADER FIELD DESTINATION FIELDS CONTEXT FIELD DATA FIELD
|
||||
_______|_______ ________________|________________ ________|______ __|_
|
||||
| | | | | | | |
|
||||
01010000 00000100 [HASH1, 16 bytes] [HASH2, 16 bytes] [CONTEXT, 1 byte] [DATA]
|
||||
|| | | | |
|
||||
|| | | | +-- Hops = 4
|
||||
|| | | +------- Packet Type = DATA
|
||||
|| | +--------- Destination Type = SINGLE
|
||||
|| +----------- Propagation Type = TRANSPORT
|
||||
|+------------- Header Type = HEADER_2 (two byte header, two address fields)
|
||||
+-------------- Access Codes = DISABLED
|
||||
|
||||
|
||||
+- Packet Example -+
|
||||
|
||||
HEADER FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
|
||||
_______|_______ _______|_______ ________|______ __|_
|
||||
| | | | | | | |
|
||||
00000000 00000111 [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|
||||
|| | | | |
|
||||
|| | | | +-- Hops = 7
|
||||
|| | | +------- Packet Type = DATA
|
||||
|| | +--------- Destination Type = SINGLE
|
||||
|| +----------- Propagation Type = BROADCAST
|
||||
|+------------- Header Type = HEADER_1 (two byte header, one address field)
|
||||
+-------------- Access Codes = DISABLED
|
||||
|
||||
|
||||
+- Packet Example -+
|
||||
|
||||
HEADER FIELD IFAC FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
|
||||
_______|_______ ______|______ _______|_______ ________|______ __|_
|
||||
| | | | | | | | | |
|
||||
10000000 00000111 [IFAC, N bytes] [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|
||||
|| | | | |
|
||||
|| | | | +-- Hops = 7
|
||||
|| | | +------- Packet Type = DATA
|
||||
|| | +--------- Destination Type = SINGLE
|
||||
|| +----------- Propagation Type = BROADCAST
|
||||
|+------------- Header Type = HEADER_1 (two byte header, one address field)
|
||||
+-------------- Access Codes = ENABLED
|
||||
|
||||
|
||||
Size examples of different packet types
|
||||
---------------------------------------
|
||||
|
||||
The following table lists example sizes of various
|
||||
packet types. The size listed are the complete on-
|
||||
wire size counting all fields including headers,
|
||||
but excluding any interface access codes.
|
||||
|
||||
- Path Request : 51 bytes
|
||||
- Announce : 167 bytes
|
||||
- Link Request : 83 bytes
|
||||
- Link Proof : 115 bytes
|
||||
- Link RTT packet : 99 bytes
|
||||
- Link keepalive : 20 bytes
|
||||
|
||||
|
||||
.. _understanding-announcepropagation:
|
||||
|
||||
Announce Propagation Rules
|
||||
--------------------------
|
||||
|
||||
The following table illustrates the rules for automatically propagating announces
|
||||
from one interface type to another, for all possible combinations. For the purpose
|
||||
of announce propagation, the *Full* and *Gateway* modes are identical.
|
||||
|
||||
.. image:: graphics/if_mode_graph_b.png
|
||||
|
||||
See the :ref:`Interface Modes<interfaces-modes>` section for a conceptual overview
|
||||
of the different interface modes, and how they are configured.
|
||||
|
||||
..
|
||||
(.. code-block:: text)
|
||||
Full ────── ✓ ──┐ ┌── ✓ ── Full
|
||||
AP ──────── ✓ ──┼───> Full >───┼── ✕ ── AP
|
||||
Boundary ── ✓ ──┤ ├── ✓ ── Boundary
|
||||
Roaming ─── ✓ ──┘ └── ✓ ── Roaming
|
||||
|
||||
Full ────── ✕ ──┐ ┌── ✓ ── Full
|
||||
AP ──────── ✕ ──┼────> AP >────┼── ✕ ── AP
|
||||
Boundary ── ✕ ──┤ ├── ✓ ── Boundary
|
||||
Roaming ─── ✕ ──┘ └── ✓ ── Roaming
|
||||
|
||||
Full ────── ✓ ──┐ ┌── ✓ ── Full
|
||||
AP ──────── ✓ ──┼─> Roaming >──┼── ✕ ── AP
|
||||
Boundary ── ✕ ──┤ ├── ✕ ── Boundary
|
||||
Roaming ─── ✕ ──┘ └── ✕ ── Roaming
|
||||
|
||||
Full ────── ✓ ──┐ ┌── ✓ ── Full
|
||||
AP ──────── ✓ ──┼─> Boundary >─┼── ✕ ── AP
|
||||
Boundary ── ✓ ──┤ ├── ✓ ── Boundary
|
||||
Roaming ─── ✕ ──┘ └── ✕ ── Roaming
|
||||
|
||||
|
||||
.. _understanding-primitives:
|
||||
|
||||
Cryptographic Primitives
|
||||
------------------------
|
||||
|
||||
Reticulum has been designed to use a simple suite of efficient, strong and modern
|
||||
cryptographic primitives, with widely available implementations that can be used
|
||||
both on general-purpose CPUs and on microcontrollers. The necessary primitives are:
|
||||
|
||||
* Ed25519 for signatures
|
||||
|
||||
* X25519 for ECDH key exchanges
|
||||
|
||||
* HKDF for key derivation
|
||||
|
||||
* Encrypted tokens are based on the Fernet spec
|
||||
|
||||
* Ephemeral keys derived from an ECDH key exchange on Curve25519
|
||||
|
||||
* AES-128 in CBC mode with PKCS7 padding
|
||||
|
||||
* HMAC using SHA256 for message authentication
|
||||
|
||||
* IVs are generated through os.urandom()
|
||||
|
||||
* No Fernet version and timestamp metadata fields
|
||||
|
||||
* SHA-256
|
||||
|
||||
* SHA-512
|
||||
|
||||
In the default installation configuration, the ``X25519``, ``Ed25519`` and ``AES-128-CBC``
|
||||
primitives are provided by `OpenSSL <https://www.openssl.org/>`_ (via the `PyCA/cryptography <https://github.com/pyca/cryptography>`_
|
||||
package). The hashing functions ``SHA-256`` and ``SHA-512`` are provided by the standard
|
||||
Python `hashlib <https://docs.python.org/3/library/hashlib.html>`_. The ``HKDF``, ``HMAC``,
|
||||
``Token`` primitives, and the ``PKCS7`` padding function are always provided by the
|
||||
following internal implementations:
|
||||
|
||||
- ``RNS/Cryptography/HKDF.py``
|
||||
- ``RNS/Cryptography/HMAC.py``
|
||||
- ``RNS/Cryptography/Token.py``
|
||||
- ``RNS/Cryptography/PKCS7.py``
|
||||
|
||||
|
||||
Reticulum also includes a complete implementation of all necessary primitives in pure Python.
|
||||
If OpenSSL & PyCA are not available on the system when Reticulum is started, Reticulum will
|
||||
instead use the internal pure-python primitives. A trivial consequence of this is performance,
|
||||
with the OpenSSL backend being *much* faster. The most important consequence however, is the
|
||||
potential loss of security by using primitives that has not seen the same amount of scrutiny,
|
||||
testing and review as those from OpenSSL.
|
||||
|
||||
.. warning::
|
||||
If you want to use the internal pure-python primitives, it is **highly advisable** that you
|
||||
have a good understanding of the risks that this pose, and make an informed decision on whether
|
||||
those risks are acceptable to you.
|
||||
@@ -0,0 +1,944 @@
|
||||
.. _using-main:
|
||||
|
||||
******************************
|
||||
Using Reticulum on Your System
|
||||
******************************
|
||||
|
||||
Reticulum is not installed as a driver or kernel module, as one might expect
|
||||
of a networking stack. Instead, Reticulum is distributed as a Python module,
|
||||
containing the networking core, and a set of utility and daemon programs.
|
||||
|
||||
This means that no special privileges are required to install or use it. It
|
||||
is also very light-weight, and easy to transfer to, and install on new systems.
|
||||
|
||||
When you have Reticulum installed, any program or application that uses Reticulum
|
||||
will automatically load and initialise Reticulum when it starts, if it is not
|
||||
already running.
|
||||
|
||||
In many cases, this approach is sufficient. When any program needs to use
|
||||
Reticulum, it is loaded, initialised, interfaces are brought up, and the
|
||||
program can now communicate over any Reticulum networks available. If another
|
||||
program starts up and also wants access to the same Reticulum network, the already
|
||||
running instance is simply shared. This works for any number of programs running
|
||||
concurrently, and is very easy to use, but depending on your use case, there
|
||||
are other options.
|
||||
|
||||
Configuration & Data
|
||||
--------------------
|
||||
|
||||
Reticulum stores all information that it needs to function in a single file-system
|
||||
directory. When Reticulum is started, it will look for a valid configuration
|
||||
directory in the following places:
|
||||
|
||||
- ``/etc/reticulum``
|
||||
- ``~/.config/reticulum``
|
||||
- ``~/.reticulum``
|
||||
|
||||
If no existing configuration directory is found, the directory ``~/.reticulum``
|
||||
is created, and the default configuration will be automatically created here.
|
||||
You can move it to one of the other locations if you wish.
|
||||
|
||||
It is also possible to use completely arbitrary configuration directories by
|
||||
specifying the relevant command-line parameters when running Reticulum-based
|
||||
programs. You can also run multiple separate Reticulum instances on the same
|
||||
physical system, either in isolation from each other, or connected together.
|
||||
|
||||
In most cases, a single physical system will only need to run one Reticulum
|
||||
instance. This can either be launched at boot, as a system service, or simply
|
||||
be brought up when a program needs it. In either case, any number of programs
|
||||
running on the same system will automatically share the same Reticulum instance,
|
||||
if the configuration allows for it, which it does by default.
|
||||
|
||||
The entire configuration of Reticulum is found in the ``~/.reticulum/config``
|
||||
file. When Reticulum is first started on a new system, a basic, but fully functional
|
||||
configuration file is created. The default configuration looks like this:
|
||||
|
||||
.. code::
|
||||
|
||||
# This is the default Reticulum config file.
|
||||
# You should probably edit it to include any additional,
|
||||
# interfaces and settings you might need.
|
||||
|
||||
# Only the most basic options are included in this default
|
||||
# configuration. To see a more verbose, and much longer,
|
||||
# configuration example, you can run the command:
|
||||
# rnsd --exampleconfig
|
||||
|
||||
|
||||
[reticulum]
|
||||
|
||||
# If you enable Transport, your system will route traffic
|
||||
# for other peers, pass announces and serve path requests.
|
||||
# This should only be done for systems that are suited to
|
||||
# act as transport nodes, ie. if they are stationary and
|
||||
# always-on. This directive is optional and can be removed
|
||||
# for brevity.
|
||||
|
||||
enable_transport = False
|
||||
|
||||
|
||||
# By default, the first program to launch the Reticulum
|
||||
# Network Stack will create a shared instance, that other
|
||||
# programs can communicate with. Only the shared instance
|
||||
# opens all the configured interfaces directly, and other
|
||||
# local programs communicate with the shared instance over
|
||||
# a local socket. This is completely transparent to the
|
||||
# user, and should generally be turned on. This directive
|
||||
# is optional and can be removed for brevity.
|
||||
|
||||
share_instance = Yes
|
||||
|
||||
|
||||
# If you want to run multiple *different* shared instances
|
||||
# on the same system, you will need to specify different
|
||||
# shared instance ports for each. The defaults are given
|
||||
# below, and again, these options can be left out if you
|
||||
# don't need them.
|
||||
|
||||
shared_instance_port = 37428
|
||||
instance_control_port = 37429
|
||||
|
||||
|
||||
# On systems where running instances may not have access
|
||||
# to the same shared Reticulum configuration directory,
|
||||
# it is still possible to allow full interactivity for
|
||||
# running instances, by manually specifying a shared RPC
|
||||
# key. In almost all cases, this option is not needed, but
|
||||
# it can be useful on operating systems such as Android.
|
||||
# The key must be specified as bytes in hexadecimal.
|
||||
|
||||
# rpc_key = e5c032d3ec4e64a6aca9927ba8ab73336780f6d71790
|
||||
|
||||
|
||||
# You can configure Reticulum to panic and forcibly close
|
||||
# if an unrecoverable interface error occurs, such as the
|
||||
# hardware device for an interface disappearing. This is
|
||||
# an optional directive, and can be left out for brevity.
|
||||
# This behaviour is disabled by default.
|
||||
|
||||
panic_on_interface_error = No
|
||||
|
||||
|
||||
# When Transport is enabled, it is possible to allow the
|
||||
# Transport Instance to respond to probe requests from
|
||||
# the rnprobe utility. This can be a useful tool to test
|
||||
# connectivity. When this option is enabled, the probe
|
||||
# destination will be generated from the Identity of the
|
||||
# Transport Instance, and printed to the log at startup.
|
||||
# Optional, and disabled by default.
|
||||
|
||||
respond_to_probes = No
|
||||
|
||||
|
||||
[logging]
|
||||
# Valid log levels are 0 through 7:
|
||||
# 0: Log only critical information
|
||||
# 1: Log errors and lower log levels
|
||||
# 2: Log warnings and lower log levels
|
||||
# 3: Log notices and lower log levels
|
||||
# 4: Log info and lower (this is the default)
|
||||
# 5: Verbose logging
|
||||
# 6: Debug logging
|
||||
# 7: Extreme logging
|
||||
|
||||
loglevel = 4
|
||||
|
||||
|
||||
# The interfaces section defines the physical and virtual
|
||||
# interfaces Reticulum will use to communicate on. This
|
||||
# section will contain examples for a variety of interface
|
||||
# types. You can modify these or use them as a basis for
|
||||
# your own config, or simply remove the unused ones.
|
||||
|
||||
[interfaces]
|
||||
|
||||
# This interface enables communication with other
|
||||
# link-local Reticulum nodes over UDP. It does not
|
||||
# need any functional IP infrastructure like routers
|
||||
# or DHCP servers, but will require that at least link-
|
||||
# local IPv6 is enabled in your operating system, which
|
||||
# should be enabled by default in almost any OS. See
|
||||
# the Reticulum Manual for more configuration options.
|
||||
|
||||
[[Default Interface]]
|
||||
type = AutoInterface
|
||||
interface_enabled = True
|
||||
|
||||
If Reticulum infrastructure already exists locally, you probably don't need to
|
||||
change anything, and you may already be connected to a wider network. If not,
|
||||
you will probably need to add relevant *interfaces* to the configuration, in
|
||||
order to communicate with other systems.
|
||||
|
||||
You can generate a much more verbose configuration example by running the command:
|
||||
|
||||
``rnsd --exampleconfig``
|
||||
|
||||
The output includes examples for most interface types supported
|
||||
by Reticulum, along with additional options and configuration parameters.
|
||||
|
||||
It is a good idea to read the comments and explanations in the above default config.
|
||||
It will teach you the basic concepts you need to understand to configure your network.
|
||||
Once you have done that, take a look at the :ref:`Interfaces<interfaces-main>` chapter
|
||||
of this manual.
|
||||
|
||||
Included Utility Programs
|
||||
-------------------------
|
||||
|
||||
Reticulum includes a range of useful utilities, both for managing your Reticulum
|
||||
networks, and for carrying out common tasks over Reticulum networks, such as
|
||||
transferring files to remote systems, and executing commands and programs remotely.
|
||||
|
||||
If you often use Reticulum from several different programs, or simply want
|
||||
Reticulum to stay available all the time, for example if you are hosting
|
||||
a transport node, you might want to run Reticulum as a separate service that
|
||||
other programs, applications and services can utilise.
|
||||
|
||||
The rnsd Utility
|
||||
================
|
||||
|
||||
It is very easy to run Reticulum as a service. Simply run the included ``rnsd`` command.
|
||||
When ``rnsd`` is running, it will keep all configured interfaces open, handle transport if
|
||||
it is enabled, and allow any other programs to immediately utilise the
|
||||
Reticulum network it is configured for.
|
||||
|
||||
You can even run multiple instances of ``rnsd`` with different configurations on
|
||||
the same system.
|
||||
|
||||
**Usage Examples**
|
||||
|
||||
Run ``rnsd``:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnsd
|
||||
|
||||
[2023-08-18 17:59:56] [Notice] Started rnsd version 0.5.8
|
||||
|
||||
Run ``rnsd`` in service mode, ensuring all logging output is sent directly to file:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnsd -s
|
||||
|
||||
Generate a verbose and detailed configuration example, with explanations of all the
|
||||
various configuration options, and interface configuration examples:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnsd --exampleconfig
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rnsd.py [-h] [--config CONFIG] [-v] [-q] [-s] [--exampleconfig] [--version]
|
||||
|
||||
Reticulum Network Stack Daemon
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--config CONFIG path to alternative Reticulum config directory
|
||||
-v, --verbose
|
||||
-q, --quiet
|
||||
-s, --service rnsd is running as a service and should log to file
|
||||
--exampleconfig print verbose configuration example to stdout and exit
|
||||
--version show program's version number and exit
|
||||
|
||||
You can easily add ``rnsd`` as an always-on service by :ref:`configuring a service<using-systemd>`.
|
||||
|
||||
The rnstatus Utility
|
||||
====================
|
||||
|
||||
Using the ``rnstatus`` utility, you can view the status of configured Reticulum
|
||||
interfaces, similar to the ``ifconfig`` program.
|
||||
|
||||
**Usage Examples**
|
||||
|
||||
Run ``rnstatus``:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnstatus
|
||||
|
||||
Shared Instance[37428]
|
||||
Status : Up
|
||||
Serving : 1 program
|
||||
Rate : 1.00 Gbps
|
||||
Traffic : 83.13 KB↑
|
||||
86.10 KB↓
|
||||
|
||||
AutoInterface[Local]
|
||||
Status : Up
|
||||
Mode : Full
|
||||
Rate : 10.00 Mbps
|
||||
Peers : 1 reachable
|
||||
Traffic : 63.23 KB↑
|
||||
80.17 KB↓
|
||||
|
||||
TCPInterface[RNS Testnet Dublin/dublin.connect.reticulum.network:4965]
|
||||
Status : Up
|
||||
Mode : Full
|
||||
Rate : 10.00 Mbps
|
||||
Traffic : 187.27 KB↑
|
||||
74.17 KB↓
|
||||
|
||||
RNodeInterface[RNode UHF]
|
||||
Status : Up
|
||||
Mode : Access Point
|
||||
Rate : 1.30 kbps
|
||||
Access : 64-bit IFAC by <…e702c42ba8>
|
||||
Traffic : 8.49 KB↑
|
||||
9.23 KB↓
|
||||
|
||||
Reticulum Transport Instance <5245a8efe1788c6a1cd36144a270e13b> running
|
||||
|
||||
Filter output to only show some interfaces:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnstatus rnode
|
||||
|
||||
RNodeInterface[RNode UHF]
|
||||
Status : Up
|
||||
Mode : Access Point
|
||||
Rate : 1.30 kbps
|
||||
Access : 64-bit IFAC by <…e702c42ba8>
|
||||
Traffic : 8.49 KB↑
|
||||
9.23 KB↓
|
||||
|
||||
Reticulum Transport Instance <5245a8efe1788c6a1cd36144a270e13b> running
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rnstatus [-h] [--config CONFIG] [--version] [-a] [-A]
|
||||
[-l] [-s SORT] [-r] [-j] [-R hash] [-i path]
|
||||
[-w seconds] [-v] [filter]
|
||||
|
||||
Reticulum Network Stack Status
|
||||
|
||||
positional arguments:
|
||||
filter only display interfaces with names including filter
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--config CONFIG path to alternative Reticulum config directory
|
||||
--version show program's version number and exit
|
||||
-a, --all show all interfaces
|
||||
-A, --announce-stats show announce stats
|
||||
-l, --link-stats show link stats
|
||||
-s SORT, --sort SORT sort interfaces by [rate, traffic, rx, tx, announces, arx, atx, held]
|
||||
-r, --reverse reverse sorting
|
||||
-j, --json output in JSON format
|
||||
-R hash transport identity hash of remote instance to get status from
|
||||
-i path path to identity used for remote management
|
||||
-w seconds timeout before giving up on remote queries
|
||||
-v, --verbose
|
||||
|
||||
|
||||
The rnid Utility
|
||||
====================
|
||||
|
||||
With the ``rnid`` utility, you can generate, manage and view Reticulum Identities.
|
||||
The program can also calculate Destination hashes, and perform encryption and
|
||||
decryption of files.
|
||||
|
||||
Using ``rnid``, it is possible to asymmetrically encrypt files and information for
|
||||
any Reticulum destination hash, and also to create and verify cryptographic signatures.
|
||||
|
||||
**Usage Examples**
|
||||
|
||||
Generate a new Identity:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnid -g ./new_identity
|
||||
|
||||
Display Identity key information:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnid -i ./new_identity -p
|
||||
|
||||
Loaded Identity <984b74a3f768bef236af4371e6f248cd> from new_id
|
||||
Public Key : 0f4259fef4521ab75a3409e353fe9073eb10783b4912a6a9937c57bf44a62c1e
|
||||
Private Key : Hidden
|
||||
|
||||
Encrypt a file for an LXMF user:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnid -i 8dd57a738226809646089335a6b03695 -e my_file.txt
|
||||
|
||||
Recalled Identity <bc7291552be7a58f361522990465165c> for destination <8dd57a738226809646089335a6b03695>
|
||||
Encrypting my_file.txt
|
||||
File my_file.txt encrypted for <bc7291552be7a58f361522990465165c> to my_file.txt.rfe
|
||||
|
||||
If the Identity for the destination is not already known, you can fetch it from the network by using the ``-R`` command-line option:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnid -R -i 30602def3b3506a28ed33db6f60cc6c9 -e my_file.txt
|
||||
|
||||
Requesting unknown Identity for <30602def3b3506a28ed33db6f60cc6c9>...
|
||||
Received Identity <2b489d06eaf7c543808c76a5332a447d> for destination <30602def3b3506a28ed33db6f60cc6c9> from the network
|
||||
Encrypting my_file.txt
|
||||
File my_file.txt encrypted for <2b489d06eaf7c543808c76a5332a447d> to my_file.txt.rfe
|
||||
|
||||
Decrypt a file using the Reticulum Identity it was encrypted for:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnid -i ./my_identity -d my_file.txt.rfe
|
||||
|
||||
Loaded Identity <2225fdeecaf6e2db4556c3c2d7637294> from ./my_identity
|
||||
Decrypting ./my_file.txt.rfe...
|
||||
File ./my_file.txt.rfe decrypted with <2225fdeecaf6e2db4556c3c2d7637294> to ./my_file.txt
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rnid.py [-h] [--config path] [-i identity] [-g path] [-v] [-q] [-a aspects]
|
||||
[-H aspects] [-e path] [-d path] [-s path] [-V path] [-r path] [-w path]
|
||||
[-f] [-R] [-t seconds] [-p] [-P] [--version]
|
||||
|
||||
Reticulum Identity & Encryption Utility
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--config path path to alternative Reticulum config directory
|
||||
-i identity, --identity identity
|
||||
hexadecimal Reticulum Destination hash or path to Identity file
|
||||
-g path, --generate path
|
||||
generate a new Identity
|
||||
-v, --verbose increase verbosity
|
||||
-q, --quiet decrease verbosity
|
||||
-a aspects, --announce aspects
|
||||
announce a destination based on this Identity
|
||||
-H aspects, --hash aspects
|
||||
show destination hashes for other aspects for this Identity
|
||||
-e path, --encrypt path
|
||||
encrypt file
|
||||
-d path, --decrypt path
|
||||
decrypt file
|
||||
-s path, --sign path sign file
|
||||
-V path, --validate path
|
||||
validate signature
|
||||
-r path, --read path input file path
|
||||
-w path, --write path
|
||||
output file path
|
||||
-f, --force write output even if it overwrites existing files
|
||||
-R, --request request unknown Identities from the network
|
||||
-t seconds identity request timeout before giving up
|
||||
-p, --print-identity print identity info and exit
|
||||
-P, --print-private allow displaying private keys
|
||||
--version show program's version number and exit
|
||||
|
||||
|
||||
The rnpath Utility
|
||||
====================
|
||||
|
||||
With the ``rnpath`` utility, you can look up and view paths for
|
||||
destinations on the Reticulum network.
|
||||
|
||||
**Usage Examples**
|
||||
|
||||
Resolve path to a destination:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnpath c89b4da064bf66d280f0e4d8abfd9806
|
||||
|
||||
Path found, destination <c89b4da064bf66d280f0e4d8abfd9806> is 4 hops away via <f53a1c4278e0726bb73fcc623d6ce763> on TCPInterface[Testnet/dublin.connect.reticulum.network:4965]
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rnpath [-h] [--config CONFIG] [--version] [-t] [-m hops]
|
||||
[-r] [-d] [-D] [-x] [-w seconds] [-R hash] [-i path]
|
||||
[-W seconds] [-j] [-v] [destination]
|
||||
|
||||
Reticulum Path Discovery Utility
|
||||
|
||||
positional arguments:
|
||||
destination hexadecimal hash of the destination
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--config CONFIG path to alternative Reticulum config directory
|
||||
--version show program's version number and exit
|
||||
-t, --table show all known paths
|
||||
-m hops, --max hops maximum hops to filter path table by
|
||||
-r, --rates show announce rate info
|
||||
-d, --drop remove the path to a destination
|
||||
-D, --drop-announces drop all queued announces
|
||||
-x, --drop-via drop all paths via specified transport instance
|
||||
-w seconds timeout before giving up
|
||||
-R hash transport identity hash of remote instance to manage
|
||||
-i path path to identity used for remote management
|
||||
-W seconds timeout before giving up on remote queries
|
||||
-j, --json output in JSON format
|
||||
-v, --verbose
|
||||
|
||||
|
||||
The rnprobe Utility
|
||||
====================
|
||||
|
||||
The ``rnprobe`` utility lets you probe a destination for connectivity, similar
|
||||
to the ``ping`` program. Please note that probes will only be answered if the
|
||||
specified destination is configured to send proofs for received packets. Many
|
||||
destinations will not have this option enabled, so most destinations will not
|
||||
be probable.
|
||||
|
||||
You can enable a probe-reply destination on Reticulum Transport Instances by
|
||||
setting the ``respond_to_probes`` configuration directive. Reticulum will then
|
||||
print the probe destination to the log on Transport Instance startup.
|
||||
|
||||
**Usage Examples**
|
||||
|
||||
Probe a destination:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnprobe rnstransport.probe 2d03725b327348980d570f739a3a5708
|
||||
|
||||
Sent 16 byte probe to <2d03725b327348980d570f739a3a5708>
|
||||
Valid reply received from <2d03725b327348980d570f739a3a5708>
|
||||
Round-trip time is 38.469 milliseconds over 2 hops
|
||||
|
||||
Send a larger probe:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnprobe rnstransport.probe 2d03725b327348980d570f739a3a5708 -s 256
|
||||
|
||||
Sent 16 byte probe to <2d03725b327348980d570f739a3a5708>
|
||||
Valid reply received from <2d03725b327348980d570f739a3a5708>
|
||||
Round-trip time is 38.781 milliseconds over 2 hops
|
||||
|
||||
If the interface that receives the probe replies supports reporting radio
|
||||
parameters such as **RSSI** and **SNR**, the ``rnprobe`` utility will print
|
||||
these as part of the result as well.
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnprobe rnstransport.probe e7536ee90bd4a440e130490b87a25124
|
||||
|
||||
Sent 16 byte probe to <e7536ee90bd4a440e130490b87a25124>
|
||||
Valid reply received from <e7536ee90bd4a440e130490b87a25124>
|
||||
Round-trip time is 1.809 seconds over 1 hop [RSSI -73 dBm] [SNR 12.0 dB]
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rnprobe [-h] [--config CONFIG] [-s SIZE] [-n PROBES]
|
||||
[-t seconds] [-w seconds] [--version] [-v]
|
||||
[full_name] [destination_hash]
|
||||
|
||||
Reticulum Probe Utility
|
||||
|
||||
positional arguments:
|
||||
full_name full destination name in dotted notation
|
||||
destination_hash hexadecimal hash of the destination
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--config CONFIG path to alternative Reticulum config directory
|
||||
-s SIZE, --size SIZE size of probe packet payload in bytes
|
||||
-n PROBES, --probes PROBES
|
||||
number of probes to send
|
||||
-t seconds, --timeout seconds
|
||||
timeout before giving up
|
||||
-w seconds, --wait seconds
|
||||
time between each probe
|
||||
--version show program's version number and exit
|
||||
-v, --verbose
|
||||
|
||||
|
||||
The rncp Utility
|
||||
================
|
||||
|
||||
The ``rncp`` utility is a simple file transfer tool. Using it, you can transfer
|
||||
files through Reticulum.
|
||||
|
||||
**Usage Examples**
|
||||
|
||||
Run rncp on the receiving system, specifying which identities are allowed to send files:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rncp --listen -a 1726dbad538775b5bf9b0ea25a4079c8 -a c50cc4e4f7838b6c31f60ab9032cbc62
|
||||
|
||||
You can also specify allowed identity hashes (one per line) in the file ~/.rncp/allowed_identities
|
||||
and simply running the program in listener mode:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rncp --listen
|
||||
|
||||
From another system, copy a file to the receiving system:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rncp ~/path/to/file.tgz 73cbd378bb0286ed11a707c13447bb1e
|
||||
|
||||
Or fetch a file from the remote system:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rncp --fetch ~/path/to/file.tgz 73cbd378bb0286ed11a707c13447bb1e
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rncp [-h] [--config path] [-v] [-q] [-S] [-l] [-F] [-f]
|
||||
[-j path] [-b seconds] [-a allowed_hash] [-n] [-p]
|
||||
[-w seconds] [--version] [file] [destination]
|
||||
|
||||
Reticulum File Transfer Utility
|
||||
|
||||
positional arguments:
|
||||
file file to be transferred
|
||||
destination hexadecimal hash of the receiver
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--config path path to alternative Reticulum config directory
|
||||
-v, --verbose increase verbosity
|
||||
-q, --quiet decrease verbosity
|
||||
-S, --silent disable transfer progress output
|
||||
-l, --listen listen for incoming transfer requests
|
||||
-F, --allow-fetch allow authenticated clients to fetch files
|
||||
-f, --fetch fetch file from remote listener instead of sending
|
||||
-j path, --jail path restrict fetch requests to specified path
|
||||
-b seconds announce interval, 0 to only announce at startup
|
||||
-a allowed_hash allow this identity
|
||||
-n, --no-auth accept requests from anyone
|
||||
-p, --print-identity print identity and destination info and exit
|
||||
-w seconds sender timeout before giving up
|
||||
--version show program's version number and exit
|
||||
|
||||
|
||||
The rnx Utility
|
||||
================
|
||||
|
||||
The ``rnx`` utility is a basic remote command execution program. It allows you to
|
||||
execute commands on remote systems over Reticulum, and to view returned command
|
||||
output. For a fully interactive remote shell solution, be sure to also take a look
|
||||
at the `rnsh <https://github.com/acehoss/rnsh>`_ program.
|
||||
|
||||
**Usage Examples**
|
||||
|
||||
Run rnx on the listening system, specifying which identities are allowed to execute commands:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnx --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
|
||||
|
||||
From another system, run a command on the remote:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnx 7a55144adf826958a9529a3bcf08b149 "cat /proc/cpuinfo"
|
||||
|
||||
Or enter the interactive mode pseudo-shell:
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnx 7a55144adf826958a9529a3bcf08b149 -x
|
||||
|
||||
The default identity file is stored in ``~/.reticulum/identities/rnx``, but you can use
|
||||
another one, which will be created if it does not already exist
|
||||
|
||||
.. code:: text
|
||||
|
||||
$ rnx 7a55144adf826958a9529a3bcf08b149 -i /path/to/identity -x
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rnx [-h] [--config path] [-v] [-q] [-p] [-l] [-i identity] [-x] [-b] [-n] [-N]
|
||||
[-d] [-m] [-a allowed_hash] [-w seconds] [-W seconds] [--stdin STDIN]
|
||||
[--stdout STDOUT] [--stderr STDERR] [--version] [destination] [command]
|
||||
|
||||
Reticulum Remote Execution Utility
|
||||
|
||||
positional arguments:
|
||||
destination hexadecimal hash of the listener
|
||||
command command to be execute
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--config path path to alternative Reticulum config directory
|
||||
-v, --verbose increase verbosity
|
||||
-q, --quiet decrease verbosity
|
||||
-p, --print-identity print identity and destination info and exit
|
||||
-l, --listen listen for incoming commands
|
||||
-i identity path to identity to use
|
||||
-x, --interactive enter interactive mode
|
||||
-b, --no-announce don't announce at program start
|
||||
-a allowed_hash accept from this identity
|
||||
-n, --noauth accept files from anyone
|
||||
-N, --noid don't identify to listener
|
||||
-d, --detailed show detailed result output
|
||||
-m mirror exit code of remote command
|
||||
-w seconds connect and request timeout before giving up
|
||||
-W seconds max result download time
|
||||
--stdin STDIN pass input to stdin
|
||||
--stdout STDOUT max size in bytes of returned stdout
|
||||
--stderr STDERR max size in bytes of returned stderr
|
||||
--version show program's version number and exit
|
||||
|
||||
|
||||
The rnodeconf Utility
|
||||
=====================
|
||||
|
||||
The ``rnodeconf`` utility allows you to inspect and configure existing :ref:`RNodes<rnode-main>`, and
|
||||
to create and provision new :ref:`RNodes<rnode-main>` from any supported hardware devices.
|
||||
|
||||
**All Command-Line Options**
|
||||
|
||||
.. code:: text
|
||||
|
||||
usage: rnodeconf [-h] [-i] [-a] [-u] [-U] [--fw-version version]
|
||||
[--fw-url url] [--nocheck] [-e] [-E] [-C]
|
||||
[--baud-flash baud_flash] [-N] [-T] [-b] [-B] [-p] [-D i]
|
||||
[--display-addr byte] [--freq Hz] [--bw Hz] [--txp dBm]
|
||||
[--sf factor] [--cr rate] [--eeprom-backup] [--eeprom-dump]
|
||||
[--eeprom-wipe] [-P] [--trust-key hexbytes] [--version] [-f]
|
||||
[-r] [-k] [-S] [-H FIRMWARE_HASH] [--platform platform]
|
||||
[--product product] [--model model] [--hwrev revision]
|
||||
[port]
|
||||
|
||||
RNode Configuration and firmware utility. This program allows you to change
|
||||
various settings and startup modes of RNode. It can also install, flash and
|
||||
update the firmware on supported devices.
|
||||
|
||||
positional arguments:
|
||||
port serial port where RNode is attached
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
-i, --info Show device info
|
||||
-a, --autoinstall Automatic installation on various supported devices
|
||||
-u, --update Update firmware to the latest version
|
||||
-U, --force-update Update to specified firmware even if version matches
|
||||
or is older than installed version
|
||||
--fw-version version Use a specific firmware version for update or
|
||||
autoinstall
|
||||
--fw-url url Use an alternate firmware download URL
|
||||
--nocheck Don't check for firmware updates online
|
||||
-e, --extract Extract firmware from connected RNode for later use
|
||||
-E, --use-extracted Use the extracted firmware for autoinstallation or
|
||||
update
|
||||
-C, --clear-cache Clear locally cached firmware files
|
||||
--baud-flash baud_flash
|
||||
Set specific baud rate when flashing device. Default
|
||||
is 921600
|
||||
-N, --normal Switch device to normal mode
|
||||
-T, --tnc Switch device to TNC mode
|
||||
-b, --bluetooth-on Turn device bluetooth on
|
||||
-B, --bluetooth-off Turn device bluetooth off
|
||||
-p, --bluetooth-pair Put device into bluetooth pairing mode
|
||||
-D i, --display i Set display intensity (0-255)
|
||||
--display-addr byte Set display address as hex byte (00 - FF)
|
||||
--freq Hz Frequency in Hz for TNC mode
|
||||
--bw Hz Bandwidth in Hz for TNC mode
|
||||
--txp dBm TX power in dBm for TNC mode
|
||||
--sf factor Spreading factor for TNC mode (7 - 12)
|
||||
--cr rate Coding rate for TNC mode (5 - 8)
|
||||
--eeprom-backup Backup EEPROM to file
|
||||
--eeprom-dump Dump EEPROM to console
|
||||
--eeprom-wipe Unlock and wipe EEPROM
|
||||
-P, --public Display public part of signing key
|
||||
--trust-key hexbytes Public key to trust for device verification
|
||||
--version Print program version and exit
|
||||
-f, --flash Flash firmware and bootstrap EEPROM
|
||||
-r, --rom Bootstrap EEPROM without flashing firmware
|
||||
-k, --key Generate a new signing key and exit
|
||||
-S, --sign Display public part of signing key
|
||||
-H FIRMWARE_HASH, --firmware-hash FIRMWARE_HASH
|
||||
Display installed firmware hash
|
||||
--platform platform Platform specification for device bootstrap
|
||||
--product product Product specification for device bootstrap
|
||||
--model model Model code for device bootstrap
|
||||
--hwrev revision Hardware revision for device bootstrap
|
||||
|
||||
|
||||
For more information on how to create your own RNodes, please read the :ref:`Creating RNodes<rnode-creating>`
|
||||
section of this manual.
|
||||
|
||||
Remote Management
|
||||
-----------------
|
||||
|
||||
It is possible to allow remote management of Reticulum
|
||||
systems using the various built-in utilities, such as
|
||||
``rnstatus`` and ``rnpath``. To do so, you will need to set
|
||||
the ``enable_remote_management`` directive in the ``[reticulum]``
|
||||
section of the configuration file. You will also need to specify
|
||||
one or more Reticulum Identity hashes for authenticating the
|
||||
queries from client programs. For this purpose, you can use
|
||||
existing identity files, or generate new ones with the rnid utility.
|
||||
|
||||
The following is a truncated example of enabling remote management
|
||||
in the Reticulum configuration file:
|
||||
|
||||
.. code:: text
|
||||
|
||||
[reticulum]
|
||||
...
|
||||
enable_remote_management = yes
|
||||
remote_management_allowed = 9fb6d773498fb3feda407ed8ef2c3229, 2d882c5586e548d79b5af27bca1776dc
|
||||
...
|
||||
|
||||
For a complete example configuration, you can run ``rnsd --exampleconfig``.
|
||||
|
||||
Improving System Configuration
|
||||
------------------------------
|
||||
|
||||
If you are setting up a system for permanent use with Reticulum, there is a
|
||||
few system configuration changes that can make this easier to administrate.
|
||||
These changes will be detailed here.
|
||||
|
||||
|
||||
Fixed Serial Port Names
|
||||
=======================
|
||||
|
||||
On a Reticulum instance with several serial port based interfaces, it can be
|
||||
beneficial to use the fixed device names for the serial ports, instead
|
||||
of the dynamically allocated shorthands such as ``/dev/ttyUSB0``. Under most
|
||||
Debian-based distributions, including Ubuntu and Raspberry Pi OS, these nodes
|
||||
can be found under ``/dev/serial/by-id``.
|
||||
|
||||
You can use such a device path directly in place of the numbered shorthands.
|
||||
Here is an example of a packet radio TNC configured as such:
|
||||
|
||||
.. code:: text
|
||||
|
||||
[[Packet Radio KISS Interface]]
|
||||
type = KISSInterface
|
||||
interface_enabled = True
|
||||
outgoing = true
|
||||
port = /dev/serial/by-id/usb-FTDI_FT230X_Basic_UART_43891CKM-if00-port0
|
||||
speed = 115200
|
||||
databits = 8
|
||||
parity = none
|
||||
stopbits = 1
|
||||
preamble = 150
|
||||
txtail = 10
|
||||
persistence = 200
|
||||
slottime = 20
|
||||
|
||||
Using this methodology avoids potential naming mix-ups where physical devices
|
||||
might be plugged and unplugged in different orders, or when device name
|
||||
assignment varies from one boot to another.
|
||||
|
||||
.. _using-systemd:
|
||||
|
||||
Reticulum as a System Service
|
||||
=============================
|
||||
|
||||
Instead of starting Reticulum manually, you can install ``rnsd`` as a system
|
||||
service and have it start automatically at boot.
|
||||
|
||||
Systemwide Service
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you installed Reticulum with ``pip``, the ``rnsd`` program will most likely
|
||||
be located in a user-local installation path only, which means ``systemd`` will not
|
||||
be able to execute it. In this case, you can simply symlink the ``rnsd`` program
|
||||
into a directory that is in systemd's path:
|
||||
|
||||
.. code:: text
|
||||
|
||||
sudo ln -s $(which rnsd) /usr/local/bin/
|
||||
|
||||
You can then create the service file ``/etc/systemd/system/rnsd.service`` with the
|
||||
following content:
|
||||
|
||||
.. code:: text
|
||||
|
||||
[Unit]
|
||||
Description=Reticulum Network Stack Daemon
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
# If you run Reticulum on WiFi devices,
|
||||
# or other devices that need some extra
|
||||
# time to initialise, you might want to
|
||||
# add a short delay before Reticulum is
|
||||
# started by systemd:
|
||||
# ExecStartPre=/bin/sleep 10
|
||||
Type=simple
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
User=USERNAMEHERE
|
||||
ExecStart=rnsd --service
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
Be sure to replace ``USERNAMEHERE`` with the user you want to run ``rnsd`` as.
|
||||
|
||||
To manually start ``rnsd`` run:
|
||||
|
||||
.. code:: text
|
||||
|
||||
sudo systemctl start rnsd
|
||||
|
||||
If you want to automatically start ``rnsd`` at boot, run:
|
||||
|
||||
.. code:: text
|
||||
|
||||
sudo systemctl enable rnsd
|
||||
|
||||
Userspace Service
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
Alternatively you can use a user systemd service instead of a system wide one. This way the whole setup can be done as a regular user.
|
||||
Create a user systemd service files ``~/.config/systemd/user/rnsd.service`` with the following content:
|
||||
|
||||
.. code:: text
|
||||
|
||||
[Unit]
|
||||
Description=Reticulum Network Stack Daemon
|
||||
After=default.target
|
||||
|
||||
[Service]
|
||||
# If you run Reticulum on WiFi devices,
|
||||
# or other devices that need some extra
|
||||
# time to initialise, you might want to
|
||||
# add a short delay before Reticulum is
|
||||
# started by systemd:
|
||||
# ExecStartPre=/bin/sleep 10
|
||||
Type=simple
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
ExecStart=RNS_BIN_DIR/rnsd --service
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
||||
Replace ``RNS_BIN_DIR`` with the path to your Reticulum binary directory (eg. /home/USERNAMEHERE/rns/bin).
|
||||
|
||||
Start user service:
|
||||
|
||||
.. code:: text
|
||||
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user start rnsd.service
|
||||
|
||||
If you want to automatically start ``rnsd`` without having to log in as the USERNAMEHERE, do:
|
||||
|
||||
.. code:: text
|
||||
|
||||
sudo loginctl enable-linger USERNAMEHERE
|
||||
systemctl --user enable rnsd.service
|
||||
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
******************
|
||||
What is Reticulum?
|
||||
******************
|
||||
|
||||
Reticulum is a cryptography-based networking stack for building both local and
|
||||
wide-area networks with readily available hardware, that can continue to operate
|
||||
under adverse conditions, such as extremely low bandwidth and very high latency.
|
||||
|
||||
Reticulum allows you to build wide-area networks with off-the-shelf tools, and
|
||||
offers end-to-end encryption, forward secrecy, autoconfiguring cryptographically
|
||||
backed multi-hop transport, efficient addressing, unforgeable packet
|
||||
acknowledgements and more.
|
||||
|
||||
From a users perspective, Reticulum allows the creation of applications that
|
||||
respect and empower the autonomy and sovereignty of communities and individuals.
|
||||
Reticulum enables secure digital communication that cannot be subjected to
|
||||
outside control, manipulation or censorship.
|
||||
|
||||
Reticulum enables the construction of both small and potentially planetary-scale
|
||||
networks, without any need for hierarchical or bureaucratic structures to control
|
||||
or manage them, while ensuring individuals and communities full sovereignty
|
||||
over their own network segments.
|
||||
|
||||
Reticulum is a **complete networking stack**, and does not need IP or higher
|
||||
layers, although it is easy to utilise IP (with TCP or UDP) as the underlying
|
||||
carrier for Reticulum. It is therefore trivial to tunnel Reticulum over the
|
||||
Internet or private IP networks. Reticulum is built directly on cryptographic
|
||||
principles, allowing resilience and stable functionality in open and trustless
|
||||
networks.
|
||||
|
||||
No kernel modules or drivers are required. Reticulum can run completely in
|
||||
userland, and will run on practically any system that runs Python 3. Reticulum
|
||||
runs well even on small single-board computers like the Pi Zero.
|
||||
|
||||
|
||||
Current Status
|
||||
==============
|
||||
**Please know!** Reticulum should currently be considered beta software. All core protocol
|
||||
features are implemented and functioning, but additions will probably occur as
|
||||
real-world use is explored. *There will be bugs*. The API and wire-format can be
|
||||
considered complete and stable at the moment, but could change if absolutely warranted.
|
||||
|
||||
|
||||
What does Reticulum Offer?
|
||||
==========================
|
||||
|
||||
* Coordination-less globally unique addressing and identification
|
||||
|
||||
* Fully self-configuring multi-hop routing over heterogeneous carriers
|
||||
|
||||
* Flexible scalability over heterogeneous topologies
|
||||
|
||||
* Reticulum can carry data over any mixture of physical mediums and topologies
|
||||
|
||||
* Low-bandwidth networks can co-exist and interoperate with large, high-bandwidth networks
|
||||
|
||||
* Initiator anonymity, communicate without revealing your identity
|
||||
|
||||
* Reticulum does not include source addresses on any packets
|
||||
|
||||
* Asymmetric X25519 encryption and Ed25519 signatures as a basis for all communication
|
||||
|
||||
* The foundational Reticulum Identity Keys are 512-bit Elliptic Curve keysets
|
||||
|
||||
* Forward Secrecy is available for all communication types, both for single packets and over links
|
||||
|
||||
* Reticulum uses the following format for encrypted tokens:
|
||||
|
||||
* Ephemeral per-packet and link keys and derived from an ECDH key exchange on Curve25519
|
||||
|
||||
* AES-128 in CBC mode with PKCS7 padding
|
||||
|
||||
* HMAC using SHA256 for authentication
|
||||
|
||||
* IVs are generated through os.urandom()
|
||||
|
||||
* Unforgeable packet delivery confirmations
|
||||
|
||||
* Flexible and extensible interface system
|
||||
|
||||
* Reticulum includes a large variety of built-in interface types
|
||||
|
||||
* Ability to load and utilise custom user- or community-supplied interface types
|
||||
|
||||
* Easily create your own custom interfaces for communicating over anything
|
||||
|
||||
* Authentication and virtual network segmentation on all supported interface types
|
||||
|
||||
* An intuitive and easy-to-use API
|
||||
|
||||
* Simpler and easier to use than sockets APIs and simpler, but more powerful
|
||||
|
||||
* Makes building distributed and decentralised applications much simpler
|
||||
|
||||
* Reliable and efficient transfer of arbitrary amounts of data
|
||||
|
||||
* Reticulum can handle a few bytes of data or files of many gigabytes
|
||||
|
||||
* Sequencing, compression, transfer coordination and checksumming are automatic
|
||||
|
||||
* The API is very easy to use, and provides transfer progress
|
||||
|
||||
* Lightweight, flexible and expandable Request/Response mechanism
|
||||
|
||||
* Efficient link establishment
|
||||
|
||||
* Total cost of setting up an encrypted and verified link is only 3 packets, totalling 297 bytes
|
||||
|
||||
* Low cost of keeping links open at only 0.44 bits per second
|
||||
|
||||
* Reliable sequential delivery with Channel and Buffer mechanisms
|
||||
|
||||
|
||||
Where can Reticulum be Used?
|
||||
============================
|
||||
Over practically any medium that can support at least a half-duplex channel
|
||||
with greater throughput than 5 bits per second, and an MTU of 500 bytes. Data radios,
|
||||
modems, LoRa radios, serial lines, AX.25 TNCs, amateur radio digital modes,
|
||||
ad-hoc WiFi, free-space optical links and similar systems are all examples
|
||||
of the types of interfaces Reticulum was designed for.
|
||||
|
||||
An open-source LoRa-based interface called `RNode <https://unsigned.io/rnode>`_
|
||||
has been designed as an example transceiver that is very suitable for
|
||||
Reticulum. It is possible to build it yourself, to transform a common LoRa
|
||||
development board into one, or it can be purchased as a complete transceiver
|
||||
from various vendors.
|
||||
|
||||
Reticulum can also be encapsulated over existing IP networks, so there's
|
||||
nothing stopping you from using it over wired Ethernet or your local WiFi
|
||||
network, where it'll work just as well. In fact, one of the strengths of
|
||||
Reticulum is how easily it allows you to connect different mediums into a
|
||||
self-configuring, resilient and encrypted mesh.
|
||||
|
||||
As an example, it's possible to set up a Raspberry Pi connected to both a
|
||||
LoRa radio, a packet radio TNC and a WiFi network. Once the interfaces are
|
||||
added, Reticulum will take care of the rest, and any device on the WiFi
|
||||
network can communicate with nodes on the LoRa and packet radio sides of the
|
||||
network, and vice versa.
|
||||
|
||||
Interface Types and Devices
|
||||
===========================
|
||||
Reticulum implements a range of generalised interface types that covers the communications hardware that Reticulum can run over. If your hardware is not supported, it's simple to :ref:`implement an interface class<example-custominterface>`. Currently, Reticulum can use the following devices and communication mediums:
|
||||
|
||||
* Any Ethernet device
|
||||
|
||||
* WiFi devices
|
||||
|
||||
* Wired Ethernet devices
|
||||
|
||||
* Fibre-optic transceivers
|
||||
|
||||
* Data radios with Ethernet ports
|
||||
|
||||
* LoRa using `RNode <https://unsigned.io/rnode>`_
|
||||
|
||||
* Can be installed on `many popular LoRa boards <https://github.com/markqvist/rnodeconfigutil#supported-devices>`_
|
||||
|
||||
* Can be purchased as a `ready to use transceiver <https://unsigned.io/rnode>`_
|
||||
|
||||
* Packet Radio TNCs, such as `OpenModem <https://unsigned.io/openmodem>`_
|
||||
|
||||
* Any packet radio TNC in KISS mode
|
||||
|
||||
* Ideal for VHF and UHF radio
|
||||
|
||||
* Any device with a serial port
|
||||
|
||||
* The I2P network
|
||||
|
||||
* TCP over IP networks
|
||||
|
||||
* UDP over IP networks
|
||||
|
||||
* Anything you can connect via stdio
|
||||
|
||||
* Reticulum can use external programs and pipes as interfaces
|
||||
|
||||
* This can be used to easily hack in virtual interfaces
|
||||
|
||||
* Or to quickly create interfaces with custom hardware
|
||||
|
||||
For a full list and more details, see the :ref:`Supported Interfaces<interfaces-main>` chapter.
|
||||
|
||||
|
||||
Caveat Emptor
|
||||
==============
|
||||
Reticulum is an experimental networking stack, and should be considered as
|
||||
such. While it has been built with cryptography best-practices very foremost in
|
||||
mind, it has not yet been externally security audited, and there could very well be
|
||||
privacy-breaking bugs. To be considered secure, Reticulum needs a thorough
|
||||
security review by independent cryptographers and security researchers. If you
|
||||
want to help out with this, or can help sponsor an audit, please do get in touch.
|
||||
Reference in New Issue
Block a user