This commit is contained in:
Mark Qvist
2025-04-08 14:06:07 +02:00
parent 008afd88d1
commit d13b034cab
83 changed files with 35339 additions and 3 deletions
+142
View File
@@ -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>`_.
+4
View File
@@ -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.
+335
View File
@@ -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>`_.
+43
View File
@@ -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
+169
View File
@@ -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.
+214
View File
@@ -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>
+44
View File
@@ -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.
+910
View File
@@ -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, Reticulums *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 lets 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 its *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.
Its 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.
+944
View File
@@ -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
+192
View File
@@ -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.