Introduction
Staex is a VPN for IoT devices that enhances your security with tunnels.
- The network traffic is only allowed to go through tunnels. Any other traffic is blocked.
- Tunnels simplify otherwise obscure configuration of a firewall, DNAT, and port forwarding.
- Each tunnel is encrypted individually and can be disabled without affecting other tunnels.
Staex turns your network into a collection of tunnels radically simplifying network management. Learn more about tunnels…
Quick start
In this setup you will know how to install an MCC node and a tunnel.
Prerequisites
A Debian/Ubuntu Linux based machine with Internet access. Other distributions are also possible however you may need to use another package manager. See here for more details.
Prepare a network certificate
Sign in to your Staex account or create a new one at https://cas.staex.io/. On the New network page of self-service portal create a new network certificate. You will get a private key of your network - save it for further steps. Also copy the network certificate.
Install the node
Install MCC client.
curl -o /tmp/staex-repo.noarch.deb \
https://packages.staex.io/linux/deb/staex-repo.noarch.deb
sudo apt-get install /tmp/staex-repo.noarch.deb
sudo apt-get update
sudo apt-get install mcc
Now you need to initialize the node with your network certificate. You will be asked for the network certificate and the private key of your network.
sudo mcc init --parents public.staex.io
sudo systemctl enable --now mcc
Check the logs to validate MCC is running:
sudo journalctl -u mcc
Example output would be:
Started mcc.service - Staex VPN daemon.
INFO [mcc::core::node] node id: gbkjnr7ydpj13bwjf8wcpwkemrnpfch0cfdtsvvgwpedjaa3we70
INFO [mcc::core::node] trying parent 88.99.68.57:9376
INFO [mcc::core::node] active parent is 88.99.68.57:9376
INFO [mcc::crypto::cas_client] network certificate `/etc/mcc/network-certificate.txt` has been updated
INFO [mcc::crypto::cas_client] network certificate `/etc/mcc/public-network-certificate.txt` has been updated
Setup a tunnel
The public node runs a simple HTTP service. Let's create a tunnel to it.
Here hello
is a name of the service, and s12d3qsn3qd0jaaj5rmrxv7rjfyshx9a87ede8455av7xrtmm5tg
is an ID of the public
node.
sudo mcc create-tunnel --role client --name hello --remote-node s12d3qsn3qd0jaaj5rmrxv7rjfyshx9a87ede8455av7xrtmm5tg
You will be asked for the private key of your network.
Example output would be:
server endpoint: f1t5y0mkhvw2s8nyrz7xbsa9jgmj0z38c6tr3drexs1wewjwdz0g
client endpoint: scmhygm53q3wkwpy82pnwn4915cth86dhrvy8mrrejtg905dpveg
Once the tunnel is created you need to wait 2-3 minutes until changes are propagated over the network.
Or you can run sudo systemctl restart mcc
to force it.
Use the tunnel
Let's try to resolve a tunnel address by its name:
mcc resolve hello
Example output would be:
10.83.0.2
Now you can use it to access the service:
curl http://hello.staex:8090
What's next?
Explore how to setup two nodes with your own service.
Quick start for two nodes
In this setup you will know how to install MCC nodes and a tunnel.
Prerequisites
Two Debian/Ubuntu Linux based machines with Internet access. Other distributions are also possible however you may need to use another package manager. See here for more details.
Prepare a network certificate
Sign in to your Staex account or create a new one at https://cas.staex.io/. On the New network page of self-service portal create a new network certificate. You will get a private key of your network - save it for further steps. Also copy the network certificate.
Install the nodes
Install MCC client on both nodes.
curl -o /tmp/staex-repo.noarch.deb \
https://packages.staex.io/linux/deb/staex-repo.noarch.deb
sudo apt-get install /tmp/staex-repo.noarch.deb
sudo apt-get update
sudo apt-get install mcc
Now you need to initialize nodes with your network certificate. You will be asked for the network certificate and the private key of your network.
sudo mcc init --parents public.staex.io
sudo systemctl enable --now mcc
Check the logs to validate MCC is running:
sudo journalctl -u mcc
Example output would be:
Started mcc.service - Staex VPN daemon.
INFO [mcc::core::node] node id: gbkjnr7ydpj13bwjf8wcpwkemrnpfch0cfdtsvvgwpedjaa3we70
INFO [mcc::core::node] trying parent 88.99.68.57:9376
INFO [mcc::core::node] active parent is 88.99.68.57:9376
INFO [mcc::crypto::cas_client] network certificate `/etc/mcc/network-certificate.txt` has been updated
INFO [mcc::crypto::cas_client] network certificate `/etc/mcc/public-network-certificate.txt` has been updated
When both nodes are installed and running, you can proceed with creating a tunnel.
Get the ID of the first node
Go to the first node and run the following command to obtain an ID:
mcc id
Example output would be:
root@mcc1:~# mcc id
gbkjnr7ydpj13bwjf8wcpwkemrnpfch0cfdtsvvgwpedjaa3we70
Install the demo service on the second node and create a tunnel
Go to the second node. We need a service that we will be accessing through a tunnel. Let's use a simple web server running on port 8080. Install Docker if it is not yet there.
docker run --rm -d -p 8080:80 --name mcc-demo-service nginx
Once the web server is running, create a tunnel.
Replace <NODE_1_ID>
with the one from the previous step.
You will be asked for the private key of your network.
sudo mcc create-tunnel \
--targets tcp:8080 \
--dns-names my-service1 \
--remote-node <NODE_1_ID>
Once the tunnel is created you need to wait 2-3 minutes until changes are propagated over the network.
Or you can run sudo systemctl restart mcc
to force it.
Use the tunnel
Go to the first node and resolve the tunnel address by its name.
mcc resolve my-service1
Example output would be:
10.83.0.2
Now you can use it to access the service:
curl http://my-service1.staex:8080
You should see nginx welcome page, and the tunnel is working!
What's next?
- Explore MCC DNS service
dig my-service1 @127.0.0.1 -p 8353 +short
dig my-service1.staex @127.0.0.1 -p 8353 +short
- Exlore other nodes of your network
mcc nodes
- Explore how to create tunnels to remote devices
sudo mcc create-tunnel \
--external-ip-address 192.168.1.1 \
--targets tcp:8080 \
--dns-names my-service-remote \
--remote-node <NODE_1_ID>
Know more about tunnels.
Installation
Please select the relevant platform on the top of this page.
Your first node
In essence, just run sudo mcc init
and follow the instructions.
- Sign in to your Staex account or create a new one at https://cas.staex.io/.
- On the New network page of self-service portal create a new network certificate.
- Install MCC by following instructions on Staex repository page.
- Run
sudo mcc init <NETWORK-CERTIFICATE-BASE64>
to generate node private key and certificate. Here<NETWORK-CERTIFICATE-BASE64>
is the network certificate in BASE64 format that you can copy from the Network page. The command will ask for the network key that you've generated on the previous step. Alternatively follow the instructions on New node page to do the same manually. - Now you're ready to go! Start
mcc
service and enjoy your self-hosted, multi-hop network.
# start and enable on boot
sudo systemctl enable --now mcc
# get status
sudo systemctl status mcc
# restart
sudo systemctl restart mcc
# view logs
sudo systemctl -u mcc -e
# start and enable on boot
service mcc enable
service mcc start
# get status
service mcc status
# restart
service mcc restart
# view the last 50 lines of logs
logread -e mcc -l 50
# On OpenWRT you need to run these additional commands
# to configure Dnsmasq to resolve node IDs.
uci set dhcp.@dnsmasq[-1].domainneeded=0
uci set dhcp.@dnsmasq[-1].rebind_protection=0
uci set dhcp.@dnsmasq[-1].confdir=/etc/dnsmasq.d
uci commit dhcp
service dnsmasq restart
service firewall reload
# start
sudo launchctl start io.staex.mcc
# get status
sudo launchctl list io.staex.mcc
# restart (restarts automatically after stopping)
sudo launchctl stop io.staex.mcc
# fully stop
sudo launchctl unload /Library/LaunchDaemons/io.staex.mcc.plist
sudo launchctl stop io.staex.mcc
# view logs
sudo less +G /Library/Logs/mcc.log
# enable on boot
# add <key>RunAtLoad</key><true/> to /Library/LaunchDaemons/io.staex.mcc.plist
Other nodes
Run the following command substituting x.x.x.x
with the IP address/DNS name of the first node
and network-certificate-base64
with the network certificate in BASE64 format.
sudo mcc init --parents x.x.x.x <NETWORK-CERTIFICATE-BASE64>
# for public network use
# sudo mcc init --parents public.staex.io <NETWORK-CERTIFICATE-BASE64>
Replace <NETWORK-CERTIFICATE-BASE64>
with yours.
Usually a parent node has public IP address but this is not required. You can chain-link nodes to create multi-hop network. Staex ensures global connectivity even if a child node can only "see" its parent but not the other nodes.
Don't forget to open port 9376 for UDP traffic on each node.
If everything went well your new nodes should be visible in the output of the following command on the parent node.
mcc nodes
They will also be visible on Networks page in self-service portal.
How to setup a network of a certain topology?
In this guide we will setup networks of different topologies. Please read quick start guide for installation instructions.
Tree topology
Run the following commands.
# on 10.0.0.2
mcc init --parents public.staex.io network-certificate-base64
# on 10.0.0.3
mcc init --parents public.staex.io network-certificate-base64
Linear topology
Run the following commands.
# on 10.0.0.2
mcc init --parents public.staex.io network-certificate-base64
# on 10.0.0.3
mcc init --parents 10.0.0.2 network-certificate-base64
How to add IP-based devices to network?
Often you want to add an IoT device that speaks IPv4 to your VPN but you can not install VPN on this device. One example of such device is IP camera.
Staex offers tunnels feature that helps solve this problem. Currently this is Linux-only feature.
To connect an IoT device to one of your regular Staex nodes use the following command.
mcc create-tunnel --remote-node NODEID --targets tcp:80 --external-ip-address x.x.x.x
Here x.x.x.x
is IPv4 address of the IoT device,
NODEID
is the node id of the client endpoint
and tcp:80
is the protocol and port specification.
The command creates necessary configuration files under /etc/mcc/tunnels
directory.
The tunnel is activated without the need to restart mcc
.
systemctl restart mcc
Now you can verify that the server and client endpoints appeared in the routing table.
mcc nodes
NODE_ID ADDRESS LAST_SEEN PARENT TAGS TYPE
3zb3xe4gh757dnhdsyrzxxv6efvpgkzg82m08a8w88a5sf48w7x0 x.x.x.x 4cc9pkyvvj6accsnc3ac79wy7zstw25cra7ka596tc3a8sg7k5ag server-endpoint
pvyts5x5rmtv9wkbzvvcr0vbwkmcqqpc7v6b51qc605vcy01b3yg 4cc9pkyvvj6accsnc3ac79wy7zstw25cra7ka596tc3a8sg7k5ag client-endpoint
4cc9pkyvvj6accsnc3ac79wy7zstw25cra7ka596tc3a8sg7k5ag y.y.y.y:9376 2023-10-17T10:48:34.485+0200 kd2npmmtvp6p02v7yhgqjdpg58xs9v2sw19k2a8skz4vbdqq1f50
kd2npmmtvp6p02v7yhgqjdpg58xs9v2sw19k2a8skz4vbdqq1f50 y.y.y.y:9376 2023-10-17T10:48:34.485+0200
Here 3zb3xe4gh757dnhdsyrzxxv6efvpgkzg82m08a8w88a5sf48w7x0
is the
node id
of your IoT device.
You can use this id with any command in place of DNS name from any other node in Staex network.
ping 3zb3xe4gh757dnhdsyrzxxv6efvpgkzg82m08a8w88a5sf48w7x0
See also
How to configure built-in DNS?
MCC includes built-in DNS to ease the configuration of human-friendly names for network nodes. Built-in DNS is only able to assign names to node ids and vice versa. There is currently no support for any other DNS records.
To configure a DNS name for a network node
specify
resolver.domain
and
dns-names
in the main configuration file like the following.
resolver.domain = .staex
dns-names = node1
Then you can use node1.staex
instead of the corresponding node id anywhere.
$ ping node1.staex
PING node1.staex (10.83.0.10): 56 data bytes
64 bytes from 10.83.0.10: icmp_seq=0 ttl=55 time=69.577 ms
64 bytes from 10.83.0.10: icmp_seq=1 ttl=55 time=82.023 ms
...
To assign a name to a tunnel
specify dns-names
in tunnel configuration file
like the following.
dns-names = light1
Then you can use light1.staex
instead of the corresponding node id anywhere.
$ ping light1.staex
PING light1.staex (10.83.0.11): 56 data bytes
64 bytes from 10.83.0.11: icmp_seq=0 ttl=55 time=69.577 ms
64 bytes from 10.83.0.11: icmp_seq=1 ttl=55 time=82.023 ms
...
How to configure built-in SSL?
MCC allows us to easily distribute SSL CA certificates across all network nodes. These certificates are installed on each network node as trusted. After that any application can access web sites that use certificates signed by CA like any other trusted web site.
To accomplish this specify ssl-install=true
in the main configuration file
and supply a path to your SSL CA certificate using
ssl-certificates
.
After that restart MCC and your certificate(s) will be distributed across all network nodes. Distribution happens incrementally, i.e. if you do not update your certificate, then no updates are sent over the network periodically.
Certificate installation into a trusted store happens via ssl-manage-script
.
We provide default script that should work on most of Linux distributions as well as on MacOS.
Please note that recent MacOS interactively request your password via graphical UI to install the certificate in the trusted store.
If certificate installation does not work on your system,
please adjust trusted store paths in the default script under /usr/libexec/mcc-ssl
path.
How to configure Dnsmasq for Android clients?
Staex on Android resolves node ids to IP addresses using the parent node. This is due to Android OS not allowing us to run local DNS resolver on the device, leaving us with the option of using the resolver with an external IP address. The parent node hosts such a resolver.
In this how-to we use Dnsmasq as DNS resolver. We use Dnsmasq due to its simple configuration and due to the fact that it is widely available across many Linux distributions.
First we install Dnsmasq using platform's package manager.
apt-get install dnsmasq
dnf install dnsmasq
opkg install dnsmasq
Next we configure Dnsmasq to listen on all addresses on port 53.
# file /etc/dnsmasq.conf
# listen on all addresses
listen-address = 0.0.0.0
# listen on loopback for local name resolution
listen-address = 127.0.0.1
# use MCC to resolve .home.arpa domains
server=/home.arpa/127.0.0.1#8353
# use MCC to resolve DNS names without domains
server=//127.0.0.1#8353
# use MCC to resolve dynamic IP addresses from 10.83.0.0/16 network
server=/83.10.in-addr.arpa./127.0.0.1#8353
Now we enable Dnsmasq to run on boot and restart it to apply the new configuration.
systemctl enable dnsmasq
systemctl restart dnsmasq
service enable dnsmasq
service restart dnsmasq
Done! Now when you specify this server as the parent of the Android device, the device will use Dnsmasq to resolve all DNS names from MCC network and from the Internet. Please continue to IP forwarding how-to to enable Internet browsing for Android clients.
Note. Dnsmasq listening on a public IP is vulnerable to DDoS attacks. How to protect from such attacks is out of scope of this article. Please do your own research before opening port 53 to the public.
See also
How to configure IP forwarding for Android clients?
Staex on Android not only uses the parent node to route the traffic inside MCC network, but also uses it as the default gateway for any other traffic. This tutorial explains how to configure parent node to route the traffic from your Android device to the Internet.
First of all you need to enable IP forwarding on the parent node.
To do that create a file /etc/sysctl.d/01-ip-forward.conf
with the following contents.
net.ipv4.ip_forward=1
This file ensures that IP forwarding is enabled on boot. Then enable IP forwarding manually for the running system like this.
sysctl -w net.ipv4.ip_forward=1
The next step is to setup firewall rules that control how the traffic is forwarded between MCC network and the Internet. We will use Iptables to write these rules. First we install the package that enables the rules on boot.
apt-get install iptables-persistent
dnf install iptables-services
Now we add the following rules to /etc/sysconfig/iptables
.
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.83.0.0/16 -o eth0 -j MASQUERADE
COMMIT
*filter
:FORWARD DROP [0:0]
-A FORWARD -i mcc0 -o mcc0 -j ACCEPT
-A FORWARD -i mcc0 -o eth0 -j ACCEPT
-A FORWARD -i eth0 -o mcc0 -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT
If the file already contains *nat
or *filter
sections,
add the corresponding rules to the existing sections.
Now use iptables-apply
command to test if the rules are working
without locking yourself out of the server.
iptables-apply < /etc/sysconfig/iptables
# use iptables-restore --test < /etc/sysconfig/iptables
# if iptables-apply is not available
Finally enable system service to apply Iptables rules now and restore them on each boot.
systemctl enable --now netfilter-persistent
systemctl enable --now iptables
Done! Now the parent node will forward the traffic from your Android device to the Internet.
See also
StaexFleet quick start
StaexFleet is a fleet management system that gets geolocation data from GPS trackers.
The data is end-to-end encrypted and delivered to your servers in JSON format via HTTP POST
request.
We will configure your GPS trackers to send the data to the provided HTTPS URLs.
The HTTPS POST request looks like the following.
POST / HTTP/1.1
content-type: application/json
host: your-server.tld
content-length: 1100
[
{
"id": "43bc4f423976ffc3ef47c626f1d8d0a6",
"device_id": "st-7028906584",
"timestamp": 1715629621,
"latitude": 52.4537,
"longitude": 13.3852,
"speed": 1.0,
"direction": 77.0
},
...
]
The body of the request is a JSON array each item of which is a record obtained from a GPS tracker. Record fields are documented here.
Request failure handling
We buffer records on the intermediate server and send them to your server in batches periodically. If the request fails it will be retried in the next period until the data is fully sent. We assume that you either process all records from a single request or none of the records are processed. If you process only some of the records and then fail, in the next batch we will send you records that might already be in your database. In this case we recommend updating the existing records (although they should be exactly the same that we sent in previous unsuccessful batches).
Chronology
The records from a particular device are always sent in chronological order. We make best effort to maintain this order across all your devices, however, if some of them send the data late (due to intermittent connectivity issues for example) then the order might deviate from the chronological.
Test your server
Use the following command to send test data to your server.
curl https://your-server.tld/some/path \
-H 'Content-Type: application/json' \
-d '[{
"id":"43bc4f423976ffc3ef47c626f1d8d0a6",
"device_id":"st-7028906584",
"timestamp":1715629621,
"latitude":52.4537,
"longitude":13.3852,
"speed":1.0,
"direction":77.0
}]'
See also
How to setup a tunnel between different companies
In this guide we will setup a tunnel between different companies.
Please read quick start guide for installation instructions and how to setup Staex network between two ndoes. This article explain quite the same but the difference is in network certificates exchange betweene different companies.
Let's say first company is Capybara and second company is Steax.
Capybara wants to give an access to their device (node) to Staex.
- Capybara registers in Staex CAS
- Capybara creates new network in CAS
... Staex does same steps ...
- Capybara sends network certificate (public part) to Staex
- Staex sends network certificate (public part) to Capybara
- Bots companies add partner's network certificate to Staex MCC config file. Using this config file field.
- Capybara gets Staex network certificate and creates a tunnel with it.
- So to apply new configuration in the network topology you need to wait for several minutes or restart your node.
- After these steps Staex has an access to Capybara's device.
What is a node id?
A node id is both its address in Staex network and its public key. Such a tight coupling helps prevent man-in-the-middle attacks: spoofing node id amounts to stealing node's private key — something that should not happen under normal circumstances. Node, network and Staex public keys form a chain of trust that is used to verify legitimacy of each node in Staex network.
Node id is presented in the output of many commands as BASE32-encoded string. In this form node id can be used in place of a DNS name in any configuration file and any command that you type in a terminal. Make sure to execute this command from a host that runs Staex.
Use mcc id
command to show the current node's id (public key).
Use mcc certificates
command to show node and network certificates.
What is a node certificate?
A node certificate is a public key of the node (or a node id as we call it) plus some additional information that is cryptographically signed by a network private key. Node, network and Staex certificates form a chain of trust that is used to verify legitimacy of each node in Staex network.
What is a network certificate?
A network certificate is a public key of the network plus some additional information that is cryptographically signed by Staex private key. A network certificate is used to verify that a node certificate belongs to the corresponding network. To sign the node certificate you need the corresponding network private key. Node, network and Staex certificates form a chain of trust that is used to verify legitimacy of each node in Staex network.
Unless specified otherwise two nodes certificates of which were signed by different network keys can not communicate with each other.
This behavior can be overridden with
trusted-nodes
and
trusted-networks
settings.
Network certificates are presented in the arguments to many commands as BASE64-encoded strings.
This is the string that mcc init
command expects, for example.
Use mcc certificates
command to show node and network certificates.
What is a tunnel?
A tunnel is a secure communication channel between two endpoints. There are client and server endpoints. Each endpoint is associated with a unique pair of private and public keys, that are used to encrypt the data sent over the tunnel.
A tunnel defines the list of protocol/port pairs that constrain the communication to the specified protocol and port pairs.
In addition to that server endpoint might be associated with a list of DNS names and a static IP address.
Finally, the server endpoint might be located outside MCC network under local IP address. In this case the traffic is forwarded to this address upon reaching the MCC node where the server endpoint is defined. In this case the traffic is encrypted until the server endpoint, after that it is sent in the original form over the local network.
Microcontroller-based devices that speak IPv4 are good candidates for such external endpoints: IP cameras, network printers and scanners, smart meters, smart light bulbs etc.
See also
What routing algorithm Staex network uses?
Staex network topology is a directed graph. The edge goes from child node to parent node. Each node can be simultaneously a child and a parent.
The node state (e.g. its static IPv4 address, domain name, certificates) propagates from child to parent nodes, and the root of the topology — a node that does not have any parents but can reach any other node via edges — has a copy of each other node's state, i.e. knows everything about the network.
The routing uses Dijkstra algorithm that finds the shortest path between the source and destination nodes of a packet. If the path can not be found by the local node, the packet is sent to the parent node. This repeats until the root node is reached. If the root node can not find the path, then the packet is dropped.
We permit cycles in the graph, however, we encourage to stick to tree-like topologies to optimize node state propagation.
We also permit a node to have multiple parents. In this case only one parent is active at a time. When it goes offline, the child automatically switches to the next parent in the list. This allows the network to gracefully handle root node failures and restarts.
To summarize,
- we support any network topology that is a directed graph,
- we use shortest-path algorithm to find the best route for each packet,
- we have built-in support for root node failures that otherwise would be single point of failures.
Such flexibility allows us to support use cases where some nodes have Internet connectivity, but others do not. The nodes that do not have direct access to the Internet would be able to get it via Staex network. With this multi-hop architecture it is possible to setup networks in hard-to-reach locations: forests, mountains, and even between two islands if there is enough traffic that hosts Staex nodes that work as relays.
StaexWeb
The daemon (staex-web
) is responsible for managing MCC.
It is installed on every node in the network.
The default configuration file path is /etc/staex-web
.
StaexWeb configuration file
This file is located under /etc/staex-web/staex-web.conf
path by default.
To override the path pass the new one as the argument to
staex-web
.
log-level = info
Log verbosity level.
Possible values: off
, error
, warn
, info
, debug
, trace
.
password-file = password.txt
Password file that contains hashed password. The path is relative to the configuration directory.
valid-users = staex
Users that are allowed to log in with the password from the password-file
.
http-listen = 0.0.0.0:8383
HTTP server listen address and port (ip:port
).
static-files-path = /usr/share/staex-web/www
Web root directory.
pre-session-timeout = 1h
Pre-session timeout.
max-pre-sessions = 999
Max. no of pre-sessions.
session-timeout = 1h
Session timeout.
max-sessions = 999
Max. no of sessions.
mcc-config-dir = /etc/mcc
MCC configuration directory.
The same directory should be specified as mccd
argument.
mcc-restart-command = systemctl restart mcc
mcc-restart-command = /etc/init.d/mcc restart
mcc-restart-command = launchctl stop io.staex.mcc
MCC restart command. A different command is used by default for each platform.
StaexWeb command line usage (staex-web
)
# run the daemon
staex-web path/to/staex-web/config-dir
# print version
staex-web --version
# print default configuration file
staex-web -C
See also
MCC
The daemon (mccd
) is responsible for maintaining the overlay network.
It is installed on every node in the network.
The default configuration file path is /etc/mcc
.
The client (mcc
) is used to interact with the daemon (mccd
).
It is installed on every node in the network.
MCC main configuration file
This file is located under /etc/mcc/mcc.conf
path by default.
To override the path pass the new one as the argument to
mccd
.
listen-addr = 0.0.0.0:9376
Listen address (ip:port
).
parents
Parent nodes' socket addresses (ip:port
, hostname:port
, ...).
parents-resolve-period = 1h
How frequently the parents' hostnames need to be resolved.
resolver.ipv4-network = 10.83.0.0/16
IPv4 network that is used to resolve node IDs. Beware that the addresses from this network are always local to the current node and are assigned dynamically. The same address on different nodes may point to a different node ID. The address is reassigned only if the system runs out of IP addresses, i.e. you resolve over 65536 unique node IDs from a single node.
resolver.ipv6-network = 200::/7
IPv6 network that is used to resolve node IDs. The default is unused IPv6 range deprecated in RFC 4048.
resolver.mac-address-mask = AE:00:00:00:00:00
MAC address mask that is used to resolve node IDs.
resolver.domain = .home.arpa
Domain under which node IDs are resolved.
The default is .home.arpa
(RFC 8375).
resolver.ttl = 0
TTL of DNS entries in seconds.
unix-socket-path = /tmp/.mcc-socket
UNIX socket path used by mcc
command.
unix-enable = true
Enable UNIX socket server.
Without this server mcc
commands do not work.
keep-alive-period = 30s
How frequently the parent node needs to be checked.
topology-update-period = 2m
How frequently topology needs to be sent to the parent node.
rejoin-period = 1m
How frequently a node tries to switch to the first parent.
log-level = info
Log verbosity level.
Possible values: off
, error
, warn
, info
, debug
, trace
.
log-file
Redirect all MCC output to the specified file.
data-dir = /var/lib/mcc
Internal data storage directory.
tun-device-name = mcc0
tun-device-name = utun83
TUN device name (utun83
on MacOS, mcc0
otherwise).
tun-device-mtu = 1280
TUN device MTU.
firewall-chain-name = MCC
Firewall chain name.
dns-addr = 127.0.0.1:8353
Bind address (ip:port
) of internal DNS server that is used to resolve node IDs.
dns-enable = true
Enable local DNS server. Without this server node ID resolution does not work on Musl-based Linux distributions and MacOS, but still works on Glibc-based Linux distributions via NSS module.
node-certificate = /etc/mcc/node-certificate.txt
Node's certificate path.
node-private-key = /etc/mcc/node-private-key.txt
Node's private key path.
network-certificates = /etc/mcc/network-certificate.txt
Comma-separated list of files with trusted network certificates.
compression = none
Compression method for tunneled packets.
Possible values: none
, lz4
.
cert-update-addr = cas.staex.io:8081
The address (ip:port
) of a server to get updated certificates from.
cert-update-enable = true
Enable automatic update of network certificates.
cert-update-period = 3h
How frequently to update network certificates.
dns-names
Comma-separated list of DNS names associated with the node.
tunnels = /etc/mcc/tunnels
A directory that contains tunnels configuration files.
dependent-nodes = /etc/mcc/dependent-nodes
tunnels
instead.
A directory that contains dependent nodes configuration files.
static-addr = 10.115.0.0/16
Static IP address of this node in overlay network. Please note that dynamic IP addresses is more secure against man-in-the-middle attacks than static ones: dynamic addresses resolve to node ids locally whereas static addresses resolve to node ids by contacting a parent node. This also means that dynamic addresses are much faster to resolve than static ones.
network-lookup-ttl = 64
Network lookup TTL, i.e. the maximum number of hops a packet will travel before being dropped. This applies to static IP address and DNS name resolution.
network-lookup-timeout = 20s
Network lookup timeout. This applies to static IP address and DNS name resolution.
forwarding-rules = /etc/mcc/forwarding-rules.conf
Packet forwarding rules.
forwarding-rules-commit-timeout = 7s
The timeout of applying new forwarding rules with
mcc apply-forwarding-rules
command.
dnsmasq-enable
Enable Dnsmasq integration.
When enabled MCC will generate configuration file for Dnsmasq and
place it under dnsmasq-directory
.
The integration is enabled by default if dnsmasq-directory
exists.
Note that MCC does not restart Dnsmasq and does not delete generated configuration file.
dnsmasq-directory = /etc/dnsmasq.d
Dnsmasq directory that contains additional (usually per-domain) configuration files.
dnsmasq-restart-command
Dnsmasq restart shell command.
By default MCC does not restart Dnsmasq after the configuration file is generated,
because it may interfere with system boot sequence.
If you are sure that this is not an issue, specify restart command here.
Something like systemctl restart dnsmasq
.
exit-node = false
Allow to route the traffic outside MCC network through this node. Use in conjunction with gateway to tunnel all the traffic through MCC network. Disabled by default.
gateway
The node id of the exit-node through which all the traffic generated by/routed through this node will go.
gateway-post-add-hook
Shell script that is executed after the gateway IP rules are added. Use this option to not route the traffic that goes through another VPN through MCC gateway. This is useful when you run multiple VPNs per node.
For example if you have another VPN running on port 1234 the script that makes this port bypass the gateway looks like this.
gateway-post-add-hook = ip rule add sport 1234 lookup main
gateway-post-delete-hook = ip rule del sport 1234 lookup main || true
Please refer to ip-rule
documentation to learn what other options do you have.
gateway-post-delete-hook
Shell script that is executed after the gateway IP rules are deleted. Please see gateway-post-add-hook for more information.
kill-switch = false
Disallow to route the traffic via the gateway when MCC is not running.
This option adds blackhole
route
that is not removed even if mcc0
device is deleted (i.e. when MCC is restarted).
It is a good idea to test this option when you have physical access to your node,
otherwise it is easy to cut yourself out of the node.
nat-table-expiry = 60s
NAT table entries TTL. Network address translation (NAT) is used to route the traffic in/out of MCC network. You should increase this value only if you experience frequent connection drops.
reroute-dns
Reroute DNS traffic to the specified network node in MCC network specified by node-id:port
.
Rerouting is implemented for any packet that goes to port 53.
Use this option in conjunction with Stubby to encrypt your DNS traffic.
reroute-ntp
Reroute NTP traffic to the specified network node in MCC network specified by node-id:port
.
Rerouting is implemented for any packet that goes to port 123.
Use this option in conjunction with Chrony to encrypt your NTP traffic.
trusted-nodes
Node ids to/from which it is allowed to send/receive packets. By default only nodes from the same network (i.e. with the same network certificate) are allowed to communicate.
trusted-networks
Network public keys (in BASE64 format) to/from which it is allowed to send/receive packets. By default only nodes from the same network (i.e. with the same network certificate) are allowed to communicate. You can copy network public key from CAS.
ssl-install = false
Add SSL CA certificates obtained via MCC into the local trusted store using ssl-manage-script
.
ssl-manage-script
The script that is used to install SSL CA certificates into the local trusted store. The script is called in the following way.
# Add new certificates to the store.
# The certificates are read from stdin as PEM encoded strings, one certificate per line.
# For each certificate the script should output the filename where it was stored.
./script.sh add
# Remove certificates from the store
# The certificates are read from stdin as PEM encoded strings, one certificate per line.
./script.sh remove
# Remove all certificates added by MCC from the store.
./script.sh cleanup
ssl-certificates
Comma-separated list of files with PEM-encoded SSL CA certificates.
ssl-storage-timeout = 24h
How long SSL CA certificates are kept without an update.
ssl-storage-cleanup-period = 1h
How frequently expired SSL CA certificates are cleaned up.
ssl-certificates-ttl = 64
TTL of SSL-related packets, i.e. the maximum number of hops a packet will travel before being dropped.
ssl-update-batch-size = 10
The maximum number of SSL-related messages that are sent in parallel by a parent to its child nodes.
ssl-update-send-period = 30s
How frequently batches of SSL-related messages are sent by a parent to its child nodes.
See also
MCC tunnel configuration file
This file is located in /etc/mcc/tunnels
directory by default.
MCC reads all the files with names ending with .conf
.
To override the path use
tunnels
property in the
main configuration file.
certificate
Dependent node's certificate path.
Use mcc create-tunnel
command to generate a new one.
private-key
Dependent node's private key path.
Use mcc create-tunnel
command to generate a new one.
external-ip-address = 0.0.0.0
IPv4 address outside MCC network to which the traffic will be directed. Only addresses from private networks (RFC 1918) are allowed here. 0.0.0.0 means no external address. If this address is specified the packet that reached the server is forwarded to the specified address, and the reply is forwarded back to the client.
dns-names
Comma-separated list of DNS names associated with the server endpoint.
static-addr = 10.115.0.0/16
Static IP address of the server endpoint in overlay network. 10.115.0.0/16 means no static address.
See also
MCC forwarding rules configuration file
This file is located under /etc/mcc/forwarding-rules.conf
path by default.
To override the path use
forwarding-rules
property in the
main configuration file.
port from PORT1 to IP:PORT2 protocol PROTOCOL
This rule forwards port PORT1
from the local node to port PORT2
on another node.
IP address must belong to MCC network.
Protocol can be tcp
or udp
.
See also
MCC daemon command line usage (mccd
)
# run the daemon
mccd path/to/mcc/config-dir
# print version
mccd --version
# print default configuration file
mccd -C
See also
MCC client command line usage (mcc
)
General options
-s /tmp/.mcc-socket
--unix /tmp/.mcc-socket
--unix /tmp/.mcc-socket
The daemon's UNIX socket path. The client uses this socket to talk to the daemon.
Commands
mcc --help
Print help.
mcc --version
Print MCC version.
mcc id
Get current node's ID.
mcc parent
Get parent node's socket address (ip:port
).
mcc health
Get MCC daemon health status. Exit code 0
means success, otherwise failure.
mcc resolve [options] address
Resolve between node IDs, IPv4/IPv6 addresses, and MAC addresses.
-t format
--target-format format
--target-format format
The address format into which you want to resolve node ID.
Possible values: ipv4
, ipv6
, mac6
, node-id
. The default is ipv4
.
address
The IPv4/IPv6/MAC address or node ID that you want to resolve.
mcc route destination [source]
Get the route to the specified node. The nodes are defined by their IDs.
destination
Destination node ID.
source
Source node ID.
mcc init [options] [network-certificate-base64]
Initialize the current node, i.e. generate node certificate, private key, and setup the parent node if any.
-p
--parents
--parents
Parents node or nodes. Comma-separated list of ip:port
or ip
items.
--stdin
Read network private key from standard input.
-y
--force
--force
Overwrite existing files without asking.
-C /etc/mcc
--config-dir /etc/mcc
--config-dir /etc/mcc
MCC configuration directory. Default is /etc/mcc
mcc generate-node-certificate [options] [output-directory]
Generate node certificate and private key. This is alternative way of provisioning the nodes that does not require using self-service portal. Easy to automate with IaC tools.
-p /etc/mcc/network-certificate.txt
--parent /etc/mcc/network-certificate.txt
--parent /etc/mcc/network-certificate.txt
Path to your network certificate.
--stdin
Read network private key from standard input.
output-directory
Output directory (default is /etc/mcc
).
mcc generate-dependent-node-certificate [options] ipv4-address [output-directory]
mcc create-tunnel
instead.
-p /etc/mcc/network-certificate.txt
--parent /etc/mcc/network-certificate.txt
--parent /etc/mcc/network-certificate.txt
Path to your network certificate.
--stdin
Read network private key from standard input.
--dns-names
Comma-separated list of DNS names associated with the node.
--static-address 10.115.0.0/16
Static IP address of this node in overlay network.
ip-address
IPv4 address outside MCC network to which the traffic will be directed. Only addresses from private networks (RFC 1918) are allowed here.
output-directory
Output directory (default is /etc/mcc/dependent-nodes
).
mcc create-tunnel [options] --targets targets --remote-node remote-node [output-directory]
Create a network tunnel between two endpoints with unique encryption keys on both sides.
There are client and server endpoints.
The tunnel can only be created on the server side.
Both the client and the server nodes have to trust each other
(see trusted-networks
and trusted-nodes
).
Currently tunnels support tcp
and udp
protocols only.
You can assign DNS names and static IP addresses to the tunnels and use their public keys to address specific server endpoints. Please note, the server endpoint can only be addressed from the corresponding client node. On other nodes the endpoint public key will not resolve into a dynamic IP address. This is in contrast to network nodes public keys of which are always resolved into dynamic IP addresses.
-p /etc/mcc/network-certificate.txt
--parent /etc/mcc/network-certificate.txt
--parent /etc/mcc/network-certificate.txt
Path to your network certificate.
--stdin
Read network private key from standard input.
--targets
Comma-separated list of server endpoints specified as protocol:port
pairs. Example: tcp:80,udp:2222
. Mandatory argument.
--remote-node
Remote node id. Mandatory argument.
--dns-names
Comma-separated list of DNS names associated with the server endpoint.
--static-ip-address 10.115.0.0/16
Static IP address of the server endpoint in overlay network. 10.115.0.0/16 means no static address.
--external-ip-address 0.0.0.0
IPv4 address outside MCC network to which the traffic will be directed. Only addresses from private networks (RFC 1918) are allowed here. 0.0.0.0 means no external address. If this address is specified the packet that reached the server is forwarded to the specified address, and the reply is forwarded back to the client.
output-directory
Output directory (default is /etc/mcc/tunnels
).
mcc certificates [configuration-file]
Show the current certificates.
configuration file
Configuration file (default is /etc/mcc/mcc.conf
).
mcc nodes [options]
Show known nodes in table or graph format.
-f table
--output-format table
--output-format table
Output format.
Possible values: table
, graphviz
.
Default is table
.
mcc apply-forwarding-rules [options] file
Safely replace existing rules with forwarding rules from the specified file. This command interactively asks for the confirmation after the new rules are applied. If the answer is not received (because your SSH connection dropped), the rules are reverted after a timeout.
mcc help [subcommand]
Print help of the given subcommand.
See also
NSS module usage (libnss_mcc.so.2
)
Name Service Switch (NSS) module is used to integrate node IDs and DNS names into the system. The module is supplied for all GNU C library-based Linux distributions (currently all Linux distributions that we support except OpenWRT).
After you install mcc
package the module is added to /etc/nsswitch.conf
file.
You can check that the module was added correctly with the following command.
grep mcc /etc/nsswitch.conf
The command should output a line similar to the following.
hosts: files mcc [SUCCESS=return] dns
Note the mcc [SUCCESS=return]
in the output.
This particular line means that the system first looks DNS name in files (/etc/hosts
),
then calls mcc
module,
then contacts pre-configured DNS servers (/etc/resolv.conf
).
If mcc
module returns positive answer, the rest modules are skipped.
Environment variables
NSS module is configured via environment variables. Since the module is loaded to any binary that tries to resolve DNS names, you have to put this variable in the configuration of every daemon that needs DNS name resolution. It is often easier to just use the default values.
MCC_UNIX_SOCKET_PATH
Specify UNIX socket path. Default is /tmp/.mcc-socket
.
See also
StaexFleet record fields
id
Unique record identifier.
device_id
Unique device identifier.
timestamp
64-bit UNIX timestamp.
latitude
Latitude in degrees from -90° to 90°. Positive latitude means northern hemisphere, negative means southern.
longitude
Longitude in degrees from -180° to 180°. Positive longitude means eastern hemisphere, negative means western.
speed
Speed in km/h.
direction
Direction in degrees (clockwise). 0° is north.
Tunnels
Unparalleled security isolation level
Tunnels is the flagship Staex feature that aims to simplify network management and aid in implementing EU NIS2 Directive (2023) and recent EU Cyber resilience act (2024). Tunnels isolate individual communication channels to prevent lateral movement in the network If one of the tunnel endpoints is hacked, the tunnel can be deactivated without affecting other endpoints. Tunnels provide more granular isolation compared to VPNs that isolate either network nodes or whole networks but not individual communication channels.
Straightforward zero-trust implementation
Staex implements zero trust through tunnels. Each tunnel specifies a client and a server endpoint, a range of ports and a protocol. The packets are transmitted and received over the network only if they match the specification of one of the tunnels. Both the source and the destination nodes have to define the tunnel for it to function. Any network packet that try to bypass the tunnels is dropped.
In addition to that each tunnel end-to-end encrypts the traffic between the source and the destination network node. Deactivating (revoking the corresponding certificate) the tunnel only affects the traffic that goes through this tunnel, and does not affect the other traffic that goes through the network node. This is the main advantage over node-based security where deactivating a network node also deactivates all the traffic that goes through this node.
Hide real IP addresses of your IoT devices in the field
Tunnels hide real IP addresses of your IoT devices in the field. Applications address tunnels' endpoints by their public keys, and for each public key a dynamic IP address is automatically generated by Staex. This means that real IP addresses of your devices in the field (and thus their geolocation) can not be tracked by malicious actors even if you use Staex public network. This is in contrast to many other VPNs that might expose real IP addresses via NAT hole punching.
Radically simplify network configuration
Tunnels turn your network configuration — including firewall, DNAT and port forwarding — into a collection of tunnel specifications. If a packets matches one of the specifications, it is allowed to flow through the network. Any other network packet is prohibited by default. This greatly simplifies otherwise obscure network configuration.
Make legacy protocols as secure as mTLS
Tunnels upgrade security of legacy protocols which are frequently used in IoT devices (DNS, NTP, RTSP, ModBus, MAVLink2 etc.) to match that of modern protocols like mTLS. All the traffic is end-to-end encrypted, and before sending any packet the mutual trust between endpoints is established using certificates. Tunnels enable secure usage of legacy protocols over the Internet thus enabling use cases that were not possible before (i.e. ever wanted to securely access ModBus data directly from your EV charger?).
Communicate securely through network boundaries
Tunnels pierce through underlying network boundaries. Tunnel source and destination may be located in different local area networks. Staex ensures seamless communication between them. This is possible because Staex provides shared address space for all nodes and does not use network isolation. If a tunnel is defined between any two network nodes, the traffic will flow through this tunnel even if the nodes move from one physical underlying network to another (e.g. roam between telco towers).
Low data usage
We studied several VPNs before releasing the first version of Staex and identified two main sources of excessive data usage in a VPN:
- Idle data usage: When a VPN connection is active, it consumes a small amount of auxiliary traffic even if it stays idle, i.e., no actual user data is being sent.
- Packet overhead: This refers to the amount of service data appended to each packet, and it depends on the routing algorithms, encryption methods, and other VPN peculiarities.
Due to the long history of VPNs, various implementations have emerged. The most up-to-date solutions are more efficient than older ones. Sometimes, older VPNs are challenging to improve because they are already integrated into the kernel, like an IPSec.
Staex v1 was designed from the ground up to minimize data usage. We use differential updates to reduce idle data usage and we use public keys of the nodes as addresses to reduce packet overhead. On top of that we offer an option to compress the traffic between nodes (the graphs on this page do not account for compression).
The highest savings come when sending large number of small messages. Our benchmarks show that for a particular MVNO and for 200 MiB of traffic we can save up to 1.7 EUR per device per month (even without data compression!).
High performance
We did a benchmark to estimate how many nodes Staex can handle. In this benchmark we launched one Staex node on cloud node A and 12k Staex nodes on cloud node B. All of these nodes were connected to the first one. Then we measured memory usage of each cloud node and how much time is needed to bootstrap the network, i.e. to reach fully operational state.
System configuration
- 2 cloud nodes.
- CPU: AMD EPYC (16 cores).
- RAM: 32 GiB.
- Cloud node 1: one Staex node (bootnode).
- Cloud node 2: 12800 Staex nodes (800 nodes per processor core, 12800 Linux processes in total).
Memory usage
- Cloud node 1: 25 MiB
- Cloud node 2: 6 GiB (0.48 MiB per Staex node).
Staex v0
This release is the legacy that we inherited from DT. Produced by 80+ engineers using industry's best practices this piece of software was massive and heavily inspired by blockchains. Over time we cut all the rough corners and eventually figured out that we need drastically different routing algorithm for IoT. Nevertheless, we still have most of the features of the original product except routing.
Introduction
A comprehensive guide to understanding and implementing the MCC (Mesh Communication Component) in your distributed system architecture, including its basic services, security features, DHT technology, and service discovery and tunnelling functionality.
The MCC is a generic component that simplifies the creation and deployment of distributed architectures.
In order to achieve this, it provides two basic services:
- Service discovery. Service providers can register their services in the network and then clients can query them from any node of the network. The service discovery allows many providers to register for any given service, thus allowing redundancy and load-balancing between services.
- Tunneling. In order to simplify connectivity to services, no matter if they are behind NAT/firewalls and/or other network configurations, MCC provides a tunnel to access services. This way clients can send their requests to the MCC network and they will be routed to its destination, independently of where the source and destination are.
The MCC works itself as a decentralized and distributed network, it is based on a Kademlia DHT.
In the MESH ecosystem, MCC would have the role of the communication enabler. Allowing edge nodes to be deployed anywhere while always keeping connectivity to the core services (such as the API). Nodes can now be anywhere in the network, even behind NATs, and still be accessible. There is no need to deploy everything on the same node. And since the service discovery allows more than one provider per service, it is very easy to add load balancing and redundancy in services.
The zen of MCC
- Ready like a warrior. (AKA batteries included.) MCC should be easy to deploy and use, no complex configuration required, it just works, always.
- Transparent like water. MCC should try to be as transparent as possible, requiring existing applications with no or almost no modification to be compatible with MCC.
- Flexible like bamboo. Distributed systems are complex and always evolving, although it is impossible to adapt to every single use case (present or future), MCC should strive to be as flexible as possible.
- Simple like a monk. MCC should be as simple as possible, and we must resist the temptation to add more features than needed.
Security
MCC aspires to be a truly decentralized, consortium-aware technology. This means that several organizations can share a single network, and still be independent from each other. Each organization would control their own nodes and be able to choose what to share and what not to share with other organizations. This allows each member of the consortium to be independent and to freely choose what level of cooperation and involvement it wants to have.
In order to achieve this, a number of obstacles have to be solved. First of all, it is important to find a technology that would not generate very large messages, in order to avoid MTU issues. Also we need a technology that would be fast and easy to implement. For these reasons we have chosen Elliptic Curve Cryptography (ECC) as our cryptography solution. We will therefore use ECC to sign messages and derive encryption keys using elliptic curve Diffie-Hellman (ECDH).
In ECC there is a number of curves that can be used for cryptographic purposes, and we have chosen to use the Curve25519 due to its multiple advantages (it is patent-free, it is very fast, it is designed for ECDH, there are no known backdoors or cryptographic flaws on it, and keys are just 256bit long while still providing high security).
Each MCC node has an ID which is also a public key and a point on the elliptic curve. All messages in the network are encrypted. We can represent an encryption key as F(x, y), where x is the sender's private key, and y is the receiver's public key. This way a key is unique for any pair of nodes.
DHT
MCC is based on a Distributed Hash Table (DHT). A DHT is simply a key-value store that instead of storing all keys in the memory of a single machine, it uses a deterministic algorithm to spread it across a number of machines. This way, keys can be always retrieved, no matter where in the network they were stored. We have chosen Kademlia as the underlying DHT technology.
Kademlia, however, defines a 1-to-1 key/value lookup, as specified by its paper, and it would be desirable for us to have a 1-to-many discovery, so that many providers can be registered for the same service, allowing for fault-tolerance and scalability. In order to achieve this we have implemented an extension to the Kademlia protocol.
The MCC exposes a REST API for the Apps and the Service Providers to use. MCC nodes talk to each other using a custom Protobuf-based UDP protocol.
For these reasons, DHT acts as a network and storage layer for the MCC, therefore the MCC stack would look like this:
Service discovery
The service discovery service, as mentioned above, runs on top of the DHT. Whenever a new provider registers a service, the node will go to the DHT and write this service in the corresponding keys.
An endpoint identifier is assigned per each service instance. It can be thought of as the address of a service inside the MCC network. A group of endpoint IDs can be associated with a human readable service name. In a typical use case, a node in the network requests available endpoints by a service name, and then connects to one of them using a tunnel.
Tunneling
Service providers and service consumers can communicate with each other via the MCC network. Each of them connects to the closest MCC node, and sends its traffic through the virtual network interface. The network encrypts, signs, and sends packets to the destination.
In order to fully utilize the bandwidth, MCC uses Google BBR congestion control algorithm to control the traffic flow. It performs greatly for network connections with packet losses.
NAT traversal
NAT is a technique that allows multiple devices inside a network to talk to the outside world using only one public IP address. Without NAT, every single device inside the network would need a publicly routable IP address. However, if one wants to contact a node behind a NAT, it might be a tricky task. It becomes even more complicated if both nodes are behind different NATs.
The NAT traversal is an integral part of the MCC protocol. The NAT traversal requires no additional central servers and it scales as the network scales. The network can detect the NAT status of each node and adjust to it, and even use nodes as a relay for the communication between two NATed nodes. This way it is ensured that there is always a way to connect two nodes.
Also, MCC uses the UDP hole punching technique to connect NATed nodes directly. In order to do that, the network looks up for a relay node that can communicate with the receiver. Then, the sender sends a message to the relay node, and the relay node passes a message to the receiver. After that, the receiver tries to reply directly to the sender bypassing the relay node. In case of success, these two nodes can continue further communication directly. However, this might not work due to the network setup, and in that case nodes will continue communicating via the relay.
Summary
MCC is a great tool for simplifying and rebuilding your network in a distributed manner. Features like a distributed storage, service discovery and secure tunnels make it usable for many use cases.
Staex v1
This release introduced the new routing algorithm that reduced idle data usage by an order of magnitude. Another change is full rewrite in Rust that brought high performance and low memory usage even on the smallest IoT devices.
Low data usage, low memory usage and high performance are the flagship features of this release. This is the foundation that we build upon to create the most secure VPN for IoT devices.
What routing algorithm Staex network uses?
Staex network topology is a directed graph. The edge goes from child node to parent node. Each node can be simultaneously a child and a parent.
The node state (e.g. its static IPv4 address, domain name, certificates) propagates from child to parent nodes, and the root of the topology — a node that does not have any parents but can reach any other node via edges — has a copy of each other node's state, i.e. knows everything about the network.
The routing uses Dijkstra algorithm that finds the shortest path between the source and destination nodes of a packet. If the path can not be found by the local node, the packet is sent to the parent node. This repeats until the root node is reached. If the root node can not find the path, then the packet is dropped.
We permit cycles in the graph, however, we encourage to stick to tree-like topologies to optimize node state propagation.
We also permit a node to have multiple parents. In this case only one parent is active at a time. When it goes offline, the child automatically switches to the next parent in the list. This allows the network to gracefully handle root node failures and restarts.
To summarize,
- we support any network topology that is a directed graph,
- we use shortest-path algorithm to find the best route for each packet,
- we have built-in support for root node failures that otherwise would be single point of failures.
Such flexibility allows us to support use cases where some nodes have Internet connectivity, but others do not. The nodes that do not have direct access to the Internet would be able to get it via Staex network. With this multi-hop architecture it is possible to setup networks in hard-to-reach locations: forests, mountains, and even between two islands if there is enough traffic that hosts Staex nodes that work as relays.
Low data usage
We studied several VPNs before releasing the first version of Staex and identified two main sources of excessive data usage in a VPN:
- Idle data usage: When a VPN connection is active, it consumes a small amount of auxiliary traffic even if it stays idle, i.e., no actual user data is being sent.
- Packet overhead: This refers to the amount of service data appended to each packet, and it depends on the routing algorithms, encryption methods, and other VPN peculiarities.
Due to the long history of VPNs, various implementations have emerged. The most up-to-date solutions are more efficient than older ones. Sometimes, older VPNs are challenging to improve because they are already integrated into the kernel, like an IPSec.
Staex v1 was designed from the ground up to minimize data usage. We use differential updates to reduce idle data usage and we use public keys of the nodes as addresses to reduce packet overhead. On top of that we offer an option to compress the traffic between nodes (the graphs on this page do not account for compression).
The highest savings come when sending large number of small messages. Our benchmarks show that for a particular MVNO and for 200 MiB of traffic we can save up to 1.7 EUR per device per month (even without data compression!).
High performance
We did a benchmark to estimate how many nodes Staex can handle. In this benchmark we launched one Staex node on cloud node A and 12k Staex nodes on cloud node B. All of these nodes were connected to the first one. Then we measured memory usage of each cloud node and how much time is needed to bootstrap the network, i.e. to reach fully operational state.
System configuration
- 2 cloud nodes.
- CPU: AMD EPYC (16 cores).
- RAM: 32 GiB.
- Cloud node 1: one Staex node (bootnode).
- Cloud node 2: 12800 Staex nodes (800 nodes per processor core, 12800 Linux processes in total).
Memory usage
- Cloud node 1: 25 MiB
- Cloud node 2: 6 GiB (0.48 MiB per Staex node).
Staex v2
The major feature of this version would be the introduction of tunnels. Each end of the tunnel has its own private and public key, and each tunnel has a protocol and a port. Staex will prohibit all the traffic outside tunnels. The tunnels is a lightweight replacement for VLANs, IP access/deny lists, user authentication, and network-based isolation in general.
The tunnel does not specify the node on which the application runs, this is determined dynamically. Decoupling applications and network nodes severely limits lateral movement within the network, and enables us to make another step towards ultimate zero trust architecture.
Introduction
The tunnels force network traffic to go through them. Any network packets that try to bypass tunnels are dropped. If no tunnels are defined, no network traffic is allowed.
Why tunnels?
In IoT world the attack vectors that are common for the servers in the cloud are complemented by attack vectors specific to devices as well as physical attack vectors. For example, for a server you can probably get away with using unencrypted DNS protocol— if a man-in-the-middle tampers the returned IP address the actual protocol (HTTPS, SSH etc.) that is used to speak to this server will most likely fail to authenticate. In IoT world even an encrypted DNS packet can actually reveal geographical location of the device that sent this packet which might constitute mission-critical data. This happens because many devices use cellular networks and connect to the Internet through the routers from the nearest cell tower. The same goes not only for DNS packets but for any other packet transmitted by the device. This is the exact reason why IoT devices need another type of security system to protect from the mission-critical data leakage.
One way to solve this mission-critical data leakage is to block any network traffic by default and then selectively establish secure end-to-end encrypted tunnels from clients to servers to protect the traffic. These tunnels differ in their destinations and thus can be divided into regular tunnels, internet tunnels and external tunnels.
Regular tunnels
This type of tunnels is the most common one. They go from clients to specific servers inside Staex overlay network. They use unique pair of encryption keys to encrypt the traffic and to establish mutual trust between the client and the server endpoint. You also have to specify exact protocol and port that a packet should use. If a packet fully matches tunnel specification, it is allowed to be sent and received. Otherwise, the packets is silently dropped. Thanks to unique keys you can selectively deactivate an individual tunnel (prohibit any traffic temporarily) without affecting others.
We consider regular tunnels the main building block of the network.
Internet tunnels
This type of tunnels is used to route all the traffic that goes to the Internet. This traffic goes from the clients in Staex network to the servers on the Internet. As we already mentioned sending this type of traffic directly to the Internet may leak mission-critical information. Internet tunnel prevents that by routing all the traffic (except local networks and Staex traffic itself) through a gateway. A gateway is a node in Staex network that forwards the packet from Staex network to the Internet and sends replies back. With the gateway DNS, NTP and other third-party servers will not see the actual IP address of the device, they will see the address of the gateway.
Internet tunnels work exactly the same as any VPNs that change your geographic location, but Staex gives you full control of both the client and the gateway node, meaning that Staex (as a company) will not see your real IP addresses either.
External tunnels
This type of tunnels is the variation of regular tunnels, but the destination is an IP address from the local network of the server. This means that when the packet reaches the server node it is automatically forwarded to the specified IP address. External tunnels are useful to talk to IoT devices that can not run Staex: IP cameras, smart home appliances, some low-end routers etc. Some IoT networks may contain only such devices, and it is essential for an overlay network to support such use cases.
Conclusion
The newest Staex release blocks network traffic by default and features tunnels as the main building block of your IoT network. Tunnels are versatile:
- regular tunnels route traffic between two endpoints on Staex network,
- internet tunnels route traffic between an endpoint on Staex network and an endpoint on the Internet, and
- external tunnels route traffic between en endpoint on Staex network and a device in the local network (directly attacked to one of the Staex nodes).
Tunnels elevate IoT network security to a whole new level. It is no longer possible for third parties to track geographical location of your devices. In the extreme event of a device breach the damage is contained within the tunnels attached to this device, and deactivating these tunnels will permanently block the spread of the malicious activity within the network. Finally, tunnels unprecedentedly simplify firewall configuration and network management in general for system administrators: when everything is a tunnel it is difficult to make mistake in the configuration.
Stay tuned for more updates! We will soon release a web UI that allows one to securely manage the whole IoT network without the cloud. It has been eye-opening experience to use this UI for our network management, and we can not wait for you to try it yourself.
Introduction
Staex public network is a zero trust network that is the backbone for the todays’ demand of the Internet of Things. In this article we discuss why we are creating such a network and how it can be useful to anyone dealing with IoT devices.
Why public network?
Today IoT devices — IP cameras, smart meters, smart lights, smart sockets, smart fridges, etc. — are made available on the Internet through numerous cloud services, and while this solution currently works (no one can access your devices unless they hack the cloud provider) in many cases cloud does not add any meaningful functionality to what is already available through the device itself using standard protocols like HTTP, RTSP, MQTT.
The reason that we can not use this functionality without a cloud is two-fold: some of these protocols were never designed to work over the Internet and the Internet was never designed as a network for such devices. HTTP (without "S"), RTSP and many other protocols do not use encryption and public key exchange to initiate secure connection, and even if they did, bringing resource-constrained devices to the Internet will expose them to DDoS attacks and make it easy for adversaries to exploit zero-day vulnerabilities in the firmware.
The current solution to this problem (connecting these devices to the cloud) is quite an overkill for implementing secure communication channel. What we really need is the security on the network level so that IoT device vendors would not need to reimplement security for each of their devices. Solving this problem on a network level also improves users' privacy because they no longer need to rely on the cloud providers that often attract hackers by storing user data in one central location.
What is Staex public network?
Staex public network is an Internet overlay that hides real IP addresses of the devices, uses public keys as addresses, and prohibits any traffic by default. Staex provides end-to-end encryption and trust on the network level, and automates making IoT devices a part of the network (port forwarding and DNAT).
Public keys as addresses
Staex uses public keys of the nodes as their addresses. This approach, pioneered by Yggdrasil network, aims to protect from the whole class of address spoofing attacks — the only way to spoof the address is to steal the private key, and the private key never leaves the node.
How do we map public keys to IP addresses? We use public keys as DNS names and resolve them locally on each node to dynamic IP addresses that are used to actually send IP packets.
Hiding real IP addresses
With public keys as addresses it is straightforward to hide the real IP address: if the traffic goes through at least one intermediate node, then there is no way to know the real IP address of the device. To support such a use case Staex implements multi-hop routing: the network has tree-like topology and nodes always use shortest path between each other for the communication.
We accumulate routing tables of all the nodes in the root node. If a node can not find packet's destination in its own routing table, it forwards the packet to its parent until it reaches the root node. This means that the root node knows the topology of the whole network and can actually find the shortest path. This does not mean that the root node is different from others, in fact it runs the same program and makes routing decisions the same way as any other node. So, if you have another intermediate node between the leaf and the root and the destination node can be reached via this node, then the traffic will not reach root node at all. You can read more about the routing in the documentation.
Restricting traffic
Having node keys is not enough for the secure communication, you also need to sign them with network-wide key. Every user has such a key and this key is used to sign node keys and the packets that carry initial public key exchange data. This signature protects the traffic from man-in-the-middle attacks and relieves you from manually adding a list of authorized keys to each node (this is in contrast to how OpenSSH works by default).
Network-wide keys are also used to segment the public network into subnetworks without using the usual prefixes and network masks. By default nodes will not communicate with each other if their keys are signed by different network keys, however, you can override that by adding other network or node keys as trusted.
Conclusion and future plans
Staex public network is a zero-trust network that is the backbone for the today's demand of the Internet of Things. Prohibiting any communication by default and any direct communication in principle is paradoxical for something that we call "a network", however, resource-constrained IoT devices and legacy protocols can not be safely used over the modern Internet. Staex makes certificate-based trust and end-to-end encryption the default for any protocol whether it is legacy or modern.
We plan to update our built-in DNS to work properly in public network (it was designed to work in a network with single owner), and enable endpoint-based security (per-endpoint private keys and trust) with the release of Staex v2.
Introduction
SPN is a decentralized network designed to address the costly and insecure management of DePIN networks, providing efficient execution and enhanced security through its native token, Staex Token (SPNX).
Business problem solved
The current management and services of DePIN networks suffer from inefficiencies and vulnerabilities due to centralized structures and old Internet protocols from the 90s. SPN streamlines network management and enhances security through decentralized architecture and protocols powered by the Staex Token SPNX.
The IT costs of DePIN service creation are very high for businesses and DePIN creators have difficulties making their businesses profitable. In SPN DePIN creators get a secure cost-optimized environment where they can create affordable DePIN applications using the power of their own devices and web3.
The IT fragmentation in DePIN is also very high. DePIN creators end up using multiple solutions from different suppliers which raises the complexity of their operations. With Staex, DePIN creators get everything DePIN integrated into the SPN directly: DePIN connectivity, web3 services, and services.
Technical reasoning
SPN solves the technical challenges of DePIN networks by providing cryptographic certificates for every device, addressing the inefficiencies of batch IP address allocation, and enabling secure remote connections through end-to-end encryption. Staex software acts as a notary, ensuring authenticity and security in device communication via cryptographic certificates.
Every device and every service that runs on the device needs a certificate to ensure secure access to the device/service and prevent lateral movement of the threat actor when device/service is compromised.
IPv4/v6 addresses are sold in batches, and the batches are too big (minimum 256 addresses for IPv4 and 264 for IPv6) to purchase for personal use or even small businesses. Individuals and small businesses have to rely on cloud providers to provide them an IP address for a web site or a service.
As a host you have to configure the IP addresses manually for each device, whereas SPN public keys can be provisioned automatically.
SPN is designed for DePIN devices that can not run a VPN — IP cameras, smart meters, smart lights, smart sockets, smart fridges, etc. — but also runs on regular DePIN devices — routers, servers, single-board computers.
SPN hides real IP addresses of the devices, uses public keys as addresses, and prohibits any traffic by default. This prevents the whole class of IP address spoofing attacks.
SPN allows one to securely share their devices (i.e. allow network access) with selected network nodes. This is in contrast to existing peer-to-peer VPNs that only provide network isolation and in contrast to the Internet that allows access to anyone by default.
Technical benefits of tokenization
High baseline security level. Network participants benefit from security provided to their devices with non-public IP addresses: the real IP address is hidden, DDoS attacks are not possible, the communication is always end-to-end encrypted, and mutual trust is established between endpoints via the cryptographic certificates.
Network governance. Root node owners’ may participate in determining how SPN software and SPN itself evolve.
Short- and long-term value creation
In the short term, SPN facilitates efficient routing of traffic in DePIN networks, provision of certificates, and secure remote connections.
Long-term goals include simplifying access, enhancing connectivity, and enabling machine-to-machine payments.
Cost-efficient and secure DePIN service creation with the possibility to build innovative multi-party business models.
Token economics
SPNX is an utility token that can be used to purchase cryptographic certificates (as NFTs) from a root node to give the buyer the ability to route the traffic via this root node.
Network participants that run root nodes sell cryptographic certificates (as NFTs) as a means for other participants to connect to the root node to route traffic between their nodes that do not have public IP addresses.
Non-binary trust. The trust provided by the certificates is non-binary (this is in contrast to regular trust that is binary) and the level of trust is determined by how many tokens the corresponding root node currently has. The root node that has a lot of tokens may increase the price of their certificates.
Certificate revocation. If a device owner is not satisfied with the service provided by the root node, it may voluntarily revoke the certificate. In this case only the time period during which the certificate was active is billed. This should discourage root nodes from providing subpar service.
Certificate lifecycle. Root node owners issue certificates for at least a month. They will receive tokens for the certificate only when the month passes or the client decides to revoke the certificate earlier. This should discourage root nodes from providing subpar service.
Staking. Both root node owners and regular users have to stake tokens to use the network. The staked amount is returned to them after a predefined time period. This incentivizes honest behavior of the participants in order for them not to decrease the prices of the token.
Incentive for DePIN devices’ owners. SPN provides a higher standard of security compared to the regular Internet. The real IP addresses of the nodes are hidden, DDoS attacks are not possible, the communication is always end-to-end encrypted, and mutual trust is established between endpoints via the cryptographic certificates, the communication between endpoints is only possible if the parties agreed upon creating a tunnel.
Incentive for root nodes’ owners. Root nodes’ owners benefit from selling excess Staex tokens via the cryptocurrency exchanges for profit. Non-binary trust gives root nodes’ owners the incentive to compete with each other and not sell all the excess tokens for profit.
Incentive for Staex. Staex runs its own root nodes and earns money the same way as other root node owners.
Governance. After a certain threshold root node owners’ may participate in SPN governance: determine how SPN software and SPN itself evolve.
Benefits of tokenization
Tokenization streamlines transactions, incentivizes network participation, and enables transparent governance within the ecosystem.
Token metrics
- Initial Supply → tbd
- Launch of SPNX depends on the progress of SPN
- Distribution is as follows.
Stakeholders
Manufacturers: Benefit from streamlined DePIN network management and enhanced security.
Service Providers: Access new revenue streams and opportunities for service provision within SPN.
Developers: Engage in network development and governance, contributing to ecosystem growth.
Regulatory implications
Securities Compliance: Staex GmbH must adhere to securities laws for token offerings representing shares. This involves registration, disclosure, and investor protection.
Crowdfunding Regulations: Compliance with crowdfunding laws is necessary for token sales, including fundraising limits and investor accreditation.
Data Protection: SPN must comply with data protection regulations such as GDPR, ensuring privacy and transparency in data handling.
AML and KYC: Robust AML and KYC procedures are essential to prevent money laundering and verify token purchasers' identities.
Taxation: SPN and token holders are subject to taxation, requiring adequate reporting and compliance mechanisms.
Smart Contract Audits: Smart contracts need security audits to identify and mitigate vulnerabilities.
Jurisdictional Considerations: SPN must navigate regulatory differences across jurisdictions where it operates.
Continuous Compliance: Continuous monitoring and adaptation to regulatory changes are essential for long-term compliance and trust-building.
Technical requirements
The governance structure for the execution of the Staex Public Network would consist of companies that also bring value to the network.
Governing companies must provide computing power to run Staex’s public nodes.
Risks and challenges
Regulatory uncertainties, network scalability, and security vulnerabilities pose risks. Overcoming these challenges requires robust governance, technological innovation, and community engagement.