layout: page title: Getting started with Meshtastic permalink: /blog/getting-started-with-meshtastic/ keywords: meshtastic,networking,ip tunneling,lora,rak wireless,rakwireless description: My first experience with Meshtastic and if and how it is possible to do IP tunneling via Meshtastic. lang: en
I recently came across a new project in Fediverse: Meshtastic Meshtastic is a peer-to-peer mesh network based on LoRa, a proprietary wireless technology.
The thing that particularly attracted me to Meshtastic is that it supports IP tunneling. I always enjoy learning about new routing and networking technologies and I saw Meshtastic as a great way to learn something new.
To join the network, you need a LoRa-enabled device with Meshtastic support. If you want to send something to a node, you send it in messages. Each message has a channel on which it is sent, a port, a TTL and a content. The messages are encoded using Protobuf.
Meshtastic uses Channels for separation. There is a standard channel, which is public. Any number of additional channels can be added (currently only eight due to hardware). The channels have names and, if desired, a password. The messages are then encrypted using AES256-CTR (some devices also have hardware support for this). Any device that participates in the channel and knows the password can decrypt the message. Furthermore, a distinction is made between a "primary" and several "secondary" channels. The primary channel is used for distributing node information (runtime, location, battery status, etc.) and for IP tunneling. Only messages can be exchanged on the secondary channels.
Each Meshtastic message also contains a port. This provides information about what the message contains (text message, node information, IP packet, ...)
The mesh algorithm is quite simple and implements the principle of "flooding". Each node sends each packet to its neighboring node. This node then forwards the packet accordingly. When the packet is forwarded, the TTL is reduced by one. The default TTL is 3 - but it can be set up to 7. A packet with a TTL of 0 is not forwarded.
Personally, I'm more of a software person than a hardware person. I find hardware can be quite unpredictable and worst of all, it doesn't even display error messages. So I needed a fairly simple device. Since I wanted to do IP tunneling, I even needed at least two. As I'm currently a student, the two devices also had to be inexpensive. And since I'm a rather messy person, I also need a cover or case for the devices. Meshtastic offers a list of devices on their website. I had a look at the devices and finally decided on the Meshtastic Starter Kit from RAKwireless.
Then came the challenge of assembly. Fortunately, RAKwireless offers documentation for this.
After I had attached the antennas to the board and screwed them into the housing, I noticed that there were protective films on the housing. None of this was mentioned in the documentation. This meant that I had to unscrew everything again and screw it back together.
Furthermore, not enough screws were included. For the building with all possible add-ons you need 12 screws, my setup without battery holder needs 8 screws - but only 6 screws were supplied.
Another obstacle was attaching the antennas to the housing. The Bluetooth antenna has a small pad with adhesive, but not the LoRa antenna. However, after I had reassembled everything because of the protective film, I could no longer use the adhesive pad for the Bluetooth antenna. I decided to use some hot glue and fix the antennas with it. Since I'm not familiar with hardware, I don't know how good this idea was - I just know that it didn't break anything in my case, fortunately.
Then it was time to set up the devices. Meshtastic offers a command line tool written in Python, a web interface (which didn't work for me) and an Android app. I opted for the command line tool. However, the device was not recognized correctly by the tool. The Android app was also able to explain the reason to me: The firmware is too old.
I then carried out a "factory reset" and then uploaded the latest firmware. With the factory reset, I wanted to make sure that there were no old configuration snippets from RAKwireless.
Once I had set everything up, it was time to try out the IP tunneling function:
$ sudo meshtastic --tunnel
Connected to radio
INFO file:tunnel.py __init__ line:83 Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:
INFO file:tunnel.py __init__ line:95 Node !5687b499 has IP address None.180.153
INFO file:tunnel.py __init__ line:95 Node !148bfdc5 has IP address None.253.197
sh: line 1: ifconfig: command not found
Aborting due to:
ifconfig was not installed on my computer. ifconfig is an old tool that used to be used for network configuration. Nowadays, however, it is recommended to use ip
.
After I had installed ifconfig, I tried the whole thing again:
$ sudo meshtastic --tunnel
Connected to radio
INFO file:tunnel.py __init__ line:83 Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:
INFO file:tunnel.py __init__ line:95 Node !5687b499 has IP address None.180.153
INFO file:tunnel.py __init__ line:95 Node !148bfdc5 has IP address None.253.197
None.180.153: Unknown host
ifconfig: `--help' gives usage information.
Aborting due to: ifconfig command failed.
Apparently ifconfig is prompted to configure the IP address None.180.153
. This is because the app is faulty. The background is that the command line argument is used to specify the subnet. However, if no subnet is specified, the argument is None
.
A possible workaround is:
$ sudo meshtastic --tunnel --subnet 10.115
The interface could then be started:
$sudo meshtastic --tunnel --subnet 10.115
Connected to radio
INFO file:tunnel.py __init__ line:83 Starting IP to mesh tunnel (you must be root for this *pre-alpha* feature to work). Mesh members:
INFO file:tunnel.py __init__ line:95 Node !148bfdc5 has IP address 10.115.253.197
INFO file:tunnel.py __init__ line:95 Node !5687b499 has IP address 10.115.180.153
$ ip address show mesh0
22: mesh0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 200 qdisc fq_codel state UNKNOWN group default qlen 500
link/none
inet 10.115.253.197/16 scope global mesh0
valid_lft forever preferred_lft forever
The subnet 10.115.0.0/16
is in the private area and can therefore actually be used without any problems. However, since the dn42 and the networks connected to it also use networks in this range, I looked for collisions and unfortunately found one. Unfortunately, Freifunk Cuxhaven also uses this network range. However, since they are no longer in the IC-VPN, I created a PR to remove the network. I have instructed my own dn42 network to consider the range 10.115.0.0/16
as invalid and therefore not to route it.
Another obstacle to IP tunneling with Meshtastic is the small MTU of 200 bytes. This automatically prevents IPv6, as IPv6 requires an MTU of at least 1280 bytes. However, it is possible to tunnel IPv6 via IPv4 (GRE, WireGuard, ...).
For IP tunneling the primary channel is always used. No change is currently planned. However, this means that encryption will be difficult:
Another problem with IP tunneling via Meshtastic is the high latency and packet loss:
$ time ping 10.115.253.197 -c 20 -W 600
PING 10.115.253.197 (10.115.253.197) 56(84) bytes of data.
64 bytes from 10.115.253.197: icmp_seq=1 ttl=64 time=12612 ms
64 bytes from 10.115.253.197: icmp_seq=2 ttl=64 time=15457 ms
64 bytes from 10.115.253.197: icmp_seq=4 ttl=64 time=14536 ms
64 bytes from 10.115.253.197: icmp_seq=5 ttl=64 time=14669 ms
64 bytes from 10.115.253.197: icmp_seq=6 ttl=64 time=14803 ms
64 bytes from 10.115.253.197: icmp_seq=8 ttl=64 time=17756 ms
64 bytes from 10.115.253.197: icmp_seq=9 ttl=64 time=19245 ms
64 bytes from 10.115.253.197: icmp_seq=10 ttl=64 time=19234 ms
64 bytes from 10.115.253.197: icmp_seq=11 ttl=64 time=19280 ms
64 bytes from 10.115.253.197: icmp_seq=12 ttl=64 time=19564 ms
64 bytes from 10.115.253.197: icmp_seq=14 ttl=64 time=21571 ms
64 bytes from 10.115.253.197: icmp_seq=16 ttl=64 time=21286 ms
64 bytes from 10.115.253.197: icmp_seq=17 ttl=64 time=21525 ms
64 bytes from 10.115.253.197: icmp_seq=20 ttl=64 time=29039 ms
--- 10.115.253.197 ping statistics ---
20 packets transmitted, 14 received, 30% packet loss, time 19209ms
rtt min/avg/max/mdev = 12611.611/18612.706/29038.582/4040.933 ms, pipe 16
real 0m50.196s
user 0m0.007s
sys 0m0.068s
UDP transmission was also possible without any problems:
$ ncat --verbose --wait 10m --udp 10.115.180.153 8886
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Connected to 10.115.180.153:8886.
Hello World!
^C
$ ncat --listen --verbose --udp --source-port 8886
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Listening on [::]:8886
Ncat: Listening on 0.0.0.0:8886
Ncat: Connection from 10.115.253.197:47920.
Hello World!
^C
However, a simple TCP connection was not possible. This means that Meshtastic cannot be used for the dn42. However, simple chat applications that are based on UDP and tolerate high latencies should be possible.
$ ncat --verbose --wait 10m 10.115.180.153 8886
Ncat: Version 7.94 ( https://nmap.org/ncat )
Ncat: Connection timed out.