Difference between revisions of "Freedomstack"
(Created page with "On Thursday, April 21 2022 a meeting was held at meet.gr0x0rd.com where we discussed the necessity of building a local alternative to the internet. We agreed that we would use...") |
|||
| (32 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
| − | On Thursday, April 21 2022 a meeting was held at meet.gr0x0rd.com where we discussed the necessity of building a local alternative to the internet. We agreed that we would use raspberry pi devices running linux that could serve as hosts for a mesh network based on reticulum and qortal. I was tasked with getting an image up and running that could be deployed to pi devices within the community, and to provide that image. | + | =Overview= |
| + | |||
| + | On Thursday, April 21 2022 a meeting was held at meet.gr0x0rd.com where we discussed the necessity of building a local alternative to the internet. We agreed that we would use raspberry pi devices running linux that could serve as hosts for a mesh network based on reticulum and qortal, and that the devices would communicate with each other using LoRa radios. I was tasked with getting an image up and running that could be deployed to pi devices within the community, and to provide that image. | ||
<br><br> | <br><br> | ||
My intention here is to provide the instructions for building said image so that can be reviewed by the community and leveraged by others. | My intention here is to provide the instructions for building said image so that can be reviewed by the community and leveraged by others. | ||
| + | <br><br> | ||
| + | After some [https://www.slant.co/topics/5304/~linux-distributions-that-run-on-arm-architecture basic research] I have, at least initially, chosen to implement this project using Archlinux. | ||
| + | ==Why Archlinux?== | ||
| + | There will probably be some questions on why I would choose Archlinux to run on the Raspberry Pi ARM architecture as opposed to the default Raspberry Pi OS or some other more common or vanilla distro. Some justification for that thought process: | ||
| + | * Customization. Arch is highly customizable and lean, but doesn't suffer from the "build your own excitement brick by brick" heavy lifting of Gentoo and other from-source distros. | ||
| + | * Heterogeneity. The most commonly used distros, and those will some sort of corporate structure attached (for example Red Hat and Ubuntu) will be early targets. | ||
| + | * It's Canadian. Yes, Arch is still a Canadian based project, as far as I know eh. | ||
| + | * Documentation. The community docs are great (I haven't ever had to ask a question on the forums and have run it nearly 5 years) and have expanded on that here in this wiki. | ||
| + | |||
| + | ==Project Objectives== | ||
| + | * 20220504: To have a text-chat based meeting between the project founders using only the hardware and software outlined in this wiki without use of the internet. | ||
| + | |||
| + | =Meetings= | ||
| + | * Kick-off meeting: [[freedomstack_20220421 | 20220421]] | ||
| + | * Follow-up meeting: [[freedomstack_20220505 | 20220505]] | ||
| + | |||
| + | =Hardware you will need= | ||
| + | * A Raspberry Pi 3/4 with a power supply, cooling (fan or heatsink), case, and sdcard | ||
| + | * A LoRa radio http://www.lilygo.cn/claprod_view.aspx?TypeId=62&Id=1281&FId=t28:62:28 | ||
| + | ==Latest version of the image== | ||
| + | The latest version of the image is available at https://www.gr0x0rd.com/freedomstack-latest.img.gz . | ||
| + | <br><br> | ||
| + | If you need instructions on how to load this image onto your sdcard, you can find instructions for linux [[Create_a_disk_image_of_an_sdcard | here]] . If you just want to get started, you should be able to just flash this image onto your sdcard, plug it into your pi, and off you go. | ||
| + | <br><br> | ||
| + | If you would rather build your own image, you can follow the steps below if you want to build it using Archlinux, or just take away a few of the useful steps if you choose some other operating system. | ||
| + | |||
| + | =Install= | ||
| + | |||
| + | If you are unfamiliar with the raspberry pi and how it works, you may benefit from browsing some of my [[Building_a_Streaming_Media_Center|previous documentation]]. | ||
| + | ==Download the image files== | ||
| + | I procured the ArchLinux ARM image files for the raspberry pi from https://archlinuxarm.org/about/downloads . You will want the image for the Raspberry Pi 3/4, which is the ARMv8 image. I noted that the download was not secure as it lacked a security certificate (fucking guys too lazy for letsencrypt I guess). I didn't bother with the md5 checksums, but I did a quick clamscan on it to make sure there weren't any nasties in the archive. | ||
| + | ==Create sdcard partitions== | ||
| + | Insert your sd card into a reader and connect it to your system. Note that these instructions are for linux. Someone may want to make instructions for Windows eventually, but time would likely be better spent teaching Windows users to use linux (my opinion). This guide assumes a kernel assignment for the sd cards of /dev/sdX . I usually use | ||
| + | $ ls -al /dev/sd* | ||
| + | To identify the drive. Before you overwrite it with the image, if there is anything precious on it, you may want to [[Create_a_disk_image_of_an_sdcard|make an image of it for later]]. If any of the sdcard partitions auto-mounted in your desktop UI, unmount (but do no eject) them. Next, we will prepare the sdcard. | ||
| + | $ sudo fdisk /dev/sdX | ||
| + | Press d until the existing partitions are deleted, if they exist. Press p to display partitions, and you should see none. Now create a 128MB boot partition. | ||
| + | Command (m for help): n | ||
| + | Partition type | ||
| + | p primary (0 primary, 0 extended, 4 free) | ||
| + | e extended (container for logical partitions) | ||
| + | Select (default p): <press enter> | ||
| + | Using default response p. | ||
| + | Partition number (1-4, default 1): <press enter> | ||
| + | First sector (2048-15351807, default 2048): <press enter> | ||
| + | Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-??????, default ??????): +128M | ||
| + | |||
| + | Created a new partition 1 of type 'Linux' and of size 128 MiB. | ||
| + | Next we will set the boot partition to type FAT32. | ||
| + | Command (m for help): t | ||
| + | Hex code or alias (type L to list all): c | ||
| + | Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'. | ||
| + | Mark the partition as active so it's bootable. Note fdisk defaults to the second partition, which is not what we want. | ||
| + | <pre> | ||
| + | Command (m for help): a | ||
| + | Partition number (1,2, default 2): 1 | ||
| + | |||
| + | The bootable flag on partition 1 is enabled now. | ||
| + | </pre> | ||
| + | Now we will create the root partition, which will essentially be the rest of the disk. | ||
| + | <pre> | ||
| + | Command (m for help): n | ||
| + | Partition type | ||
| + | p primary (1 primary, 0 extended, 3 free) | ||
| + | e extended (container for logical partitions) | ||
| + | Select (default p): | ||
| + | |||
| + | Using default response p. | ||
| + | Partition number (2-4, default 2): | ||
| + | First sector (264192-15351807, default 264192): | ||
| + | Last sector, +/-sectors or +/-size{K,M,G,T,P} (264192-15351807, default 15351807): | ||
| + | |||
| + | Created a new partition 2 of type 'Linux' and of size 7.2 GiB. | ||
| + | </pre> | ||
| + | Write the new partitions to the disk. | ||
| + | <pre> | ||
| + | Command (m for help): w | ||
| + | The partition table has been altered. | ||
| + | Calling ioctl() to re-read partition table. | ||
| + | Syncing disks. | ||
| + | </pre> | ||
| + | To confirm the partitions have been correctly created, check devices. If the paritions auto-mount, you can skip this step, but be sure to unmount but not eject the partitions. | ||
| + | $ sudo ls -al /dev/sd* | ||
| + | You should see partitions '''/dev/sdX1''' and '''/dev/sdX2'''. Now, let's apply a vfat filesystem to the boot partition. | ||
| + | ==Create filesystems== | ||
| + | $ sudo mkfs.vfat /dev/sdX1 | ||
| + | Next we apply a linux filesystem to the root partition. | ||
| + | $ sudo mkfs.ext4 /dev/sdX2 | ||
| + | The command should complete with a note about superblocks. | ||
| + | ==Copy the image files== | ||
| + | In order to copy the files you'll need to mount them. Create a folder in your favorite workspace | ||
| + | $ mkdir sdcard | ||
| + | $ cd sdcard | ||
| + | Create a folder for the boot partition and mount the sdcard boot partition there. | ||
| + | $ mkdir boot | ||
| + | $ sudo mount /dev/sdX1 boot | ||
| + | Create a folder for the root partition and mount the sdcard root partition there. | ||
| + | $ mkdir root | ||
| + | $ sudo mount /dev/sdX2 root | ||
| + | Next you will want to extract the archive you downloaded. I extracted it to a file called ~/arch_arm which I will use in the example below. | ||
| + | $ sudo mv ~/arch_arm/boot/* ~/sdcard/boot/ | ||
| + | Running the above command will spit some errors are the kernel attempts to set permissions on the newly copied files but is unable to do so because of the filesystem type. This can be ignored. Next we will move the rest of the files to the root volume. | ||
| + | $ sudo mv ~/arch_arm/* ~/sdcard/root/ | ||
| + | I ran into an issue where the extracted files inherited the UID/GID of my local user. Check the files in the root folder, and if this is the case | ||
| + | $ sudo chown -R root:root ~/sdcard/root/* | ||
| + | That should be all we need for the sdcard. Unmount the partitions. | ||
| + | $ sudo umount ~/sdcard/root | ||
| + | $ sudo umount ~/sdcard/boot | ||
| + | ==Boot the pi== | ||
| + | Insert the sdcard into the pi. Ensure it has power and ethernet, because wifi will not work OOTB (unless your security is really, really bad). Connect a monitor and keyboard if you want to watch it boot and interact with it. If not, you'll probably need to find it on your LAN. Substitute your local class c (or otherwise) subnet for '''192.168.1.0/24''' below as needed. The default device name is alarm so we can find it by grepping for that. | ||
| + | $ sudo nmap -sn 192.168.1.0/24 | grep alarm | ||
| + | Note the IP. You can now ssh into the pi. | ||
| + | ==ssh into the pi== | ||
| + | $ ssh alarm@<ip from above command> | ||
| + | The password is '''alarm'''. | ||
| + | ==Set up sudo== | ||
| + | The alarm account does not have sudo powers OOTB, nor can it su to root. The ssh daemon is also configure to prevent root logins, which is just good security. As such it was necessary to log in manually as root (password root) and set up basic sudo access for the alarm user. First, initialize the package manager and do a system update. Archlinux's package manager is called pacman. | ||
| + | # pacman-key --init | ||
| + | # pacman-key --populate archlinuxarm | ||
| + | # pacman -Syu | ||
| + | Next, install the sudo package. | ||
| + | # pacman -S sudo | ||
| + | After the package has been installed, edit the sudoers file. | ||
| + | # nano /etc/sudoers | ||
| + | Remove the comment from the line allowing the '''wheel''' group to run privileged commands. Check to comfirm that the alarm user is in the wheel group: | ||
| + | # groups alarm | ||
| + | If you see wheel in the results you're good to go. Reboot the pi to apply the system updates. | ||
| + | # reboot | ||
| + | You can now log in via ssh as the alarm user and run privileged commands. | ||
| + | ==Set home permissions== | ||
| + | I noted an error when ssh'ing in, likely because I thumped the permissions when I extracted the archive and recursively set them to root. Grant alarm access to its home folder. | ||
| + | $ sudo chown -R alarm:alarm /home/alarm | ||
| + | |||
| + | ==Set the locale== | ||
| + | By default everything will be set to GMT so we will need to configure the timezone. | ||
| + | $ sudo ln -sf /usr/share/zoneinfo/Canada/Pacific /etc/localtime | ||
| + | ==Install helpful packages== | ||
| + | ssh into your pi as alarm. We will install some basic networking packages and other tools. | ||
| + | $ sudo pacman -S dnsutils net-tools nmap cronie | ||
| + | cronie is a cron daemon so it makes sense to enable and start the cron service. | ||
| + | $ sudo pacman -S cronie | ||
| + | $ sudo systemctl enable cronie | ||
| + | $ sudo systemctl start cronie | ||
| + | ==Enabling AUR== | ||
| + | I expect we will also be needing packages from the Archlinux User Repository (AUR) so we will set up yay, a pacman equivalent. | ||
| + | $ sudo pacman -S --needed base-devel | ||
| + | Press enter to install all options (default) then press enter again. This will install a bunch of necessary components for building packages including gcc, make and libtool. Next, create a folder to house the yay source files. | ||
| + | $ sudo mkdir -p /usr/local/aur | ||
| + | $ sudo chmod -R 777 /usr/local/aur | ||
| + | $ cd /usr/local/aur | ||
| + | Install the git package. | ||
| + | $ sudo pacman -S git | ||
| + | Pull down the yay sources from git. | ||
| + | $ https://aur.archlinux.org/yay.git | ||
| + | Navigate into the folder and build yay. | ||
| + | $ cd yay | ||
| + | $ makepkg -si | ||
| + | The image should now be in great shape to install reticulum, qortal, umbrel, helium... time to take an image. | ||
| + | |||
| + | =Installing reticulum= | ||
| + | The reticulum [https://markqvist.github.io/Reticulum/manual/gettingstartedfast.html getting started fast guide] and other documentation references pip so we will need to install that prerequisite. | ||
| + | $ sudo pacman -S python-pip | ||
| + | Once installed, as per the documentation | ||
| + | $ sudo pip3 install rns | ||
| + | ==Configuring the rnsd service== | ||
| + | We want this to be running with our pi so a service is required. As per the docs, create a symlink to the binary created by the pip installer | ||
| + | $ sudo ln -s $(which rnsd) /usr/local/bin/ | ||
| + | Now create the file for the systemd service. | ||
| + | $ sudo nano /etc/systemd/system/rnsd.service | ||
| + | Paste in the code from the documentation. Note we are using the alarm user to run the service. | ||
| + | <pre> | ||
| + | [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=alarm | ||
| + | ExecStart=rnsd --service | ||
| + | |||
| + | [Install] | ||
| + | WantedBy=multi-user.target | ||
| + | </pre> | ||
| + | Save the file. With the service ready to go, let's enable and start the service. | ||
| + | $ sudo systemctl enable rnsd | ||
| + | $ sudo systemctl start rnsd | ||
| + | Looks like the service is running: | ||
| + | [alarm@alarm ~]$ ps aux | grep rnsd | ||
| + | alarm 767 22.0 2.8 550572 26092 ? Ssl 20:57 0:01 /usr/bin/python /usr/local/bin/rnsd --service | ||
| + | To test and confirm, a reboot of the pi later: | ||
| + | <pre> | ||
| + | [alarm@alarm ~]$ rnstatus | ||
| + | |||
| + | Shared Instance[37428] | ||
| + | Status: Up | ||
| + | Connected applications: 0 | ||
| + | RX: 0 B | ||
| + | TX: 0 B | ||
| + | |||
| + | AutoInterface[Default Interface] | ||
| + | Status: Up | ||
| + | RX: 0 B | ||
| + | TX: 0 B | ||
| + | </pre> | ||
| + | Time for another image. | ||
| + | =Using Nomadnet= | ||
| + | |||
| + | todo: add some screenshots from my other systems | ||
| + | |||
| + | Test Scenario: | ||
| + | Try and get two nomadnet clients connecting to each other on the test network. | ||
| + | Hardware: Raspberry Pi and Linux laptop | ||
| + | |||
| + | Status: | ||
| + | As of Sunday May 8, I have connected to the test network from my RPI and Laptop. | ||
| + | I have also run a couple of Docker containers that are each running the client. One small observation is that the application runs better in Docker. On my Linux machine, when i hit C-e to view Peer Info on a node, the client would crash. When I debugged the client, it appeared that the 'window' event loop and handlers lost control of the process, necessitating the closing of the application. | ||
| + | |||
| + | After some experience and experimenting I would summarise the communication with the client like this: | ||
| + | |||
| + | You connect to the network and wait for peers to signal they are available to talk to. | ||
| + | When you see a peer, you have the option to save the node info and name the node. You can also connect to the node. Each node can be configured to serve up data to share, much like a simple static web page. You can add links to your pages (written in markup) and links can be to other pages, or to files that you want to share. | ||
| + | |||
| + | Each node has a couple of address of note, and for communication, namely sending messages, the useful address is the xxx address | ||
| + | [insert image] | ||
| + | |||
| + | |||
| + | First Steps: | ||
| + | The default reticulum config needs to be changed. | ||
| + | The two config files that should be reviewed are | ||
| + | * ~/.reticulum/config | ||
| + | * ~/.nomadnet/config. | ||
| + | |||
| + | I added the additional section *RNS Testnet Frankfurt* to my config file as instructed on [https://markqvist.github.io/Reticulum/manual/gettingstartedfast.html#connect-to-the-public-testnet Public Testnet]. | ||
| + | If you are going add this interface then I expect the *Default Interface" should be turned off. | ||
| + | |||
| + | [[Default Interface]] | ||
| + | <nowiki>[[Default Interface]] | ||
| + | type = AutoInterface | ||
| + | interface_enabled = False</nowiki> | ||
| + | |||
| + | [[RNS Testnet Frankfurt]] | ||
| + | <nowiki>[[RNS Testnet Frankfurt]] | ||
| + | type = TCPClientInterface | ||
| + | interface_enabled = yes | ||
| + | outgoing = True | ||
| + | target_host = frankfurt.rns.unsigned.io | ||
| + | target_port = 4965</nowiki> | ||
| + | |||
| + | |||
| + | Another change I made to the configuration was to edit the nomadnet config file to set the following settings: | ||
| + | |||
| + | * enable_node = yes | ||
| + | * node_name = <your choice here> | ||
| + | |||
| + | some resources used | ||
| + | [https://www.simplilearn.com/tutorials/docker-tutorial/what-is-dockerfile?source=sl_frs_nav_playlist_video_clicked] | ||
| + | |||
| + | [https://www.ctl.io/developers/blog/post/dockerfile-entrypoint-vs-cmd/] | ||
| + | |||
| + | [https://help.ubuntu.com/stable/ubuntu-help/screen-shot-record.html] | ||
| + | |||
| + | =Installing qortal= | ||
| + | Java is required. | ||
| + | $ sudo pacman -S jdk-openjdk | ||
| + | Download the qortal.zip archive from https://qortal.org/downloads/ . I extracted it to /opt . Give permissions to alarm | ||
| + | $ sudo chown -R alarm:alarm /opt/qortal | ||
| + | Make the bash scripts executable | ||
| + | $ chmod +x /opt/qortal/*.sh | ||
| + | Run the start script. | ||
| + | [alarm@alarm qortal]$ ./start.sh | ||
| + | Passed Java version check | ||
| + | qortal running as pid 5542 | ||
| + | ==Configure the qortal service== | ||
| + | Now let's configure a service for it. First, stop the running instance. | ||
| + | $ ./stop.sh | ||
| + | Create a service file for qortal. | ||
| + | $ sudo nano /usr/lib/systemd/system/qortal.service | ||
| + | Paste the following: | ||
| + | <pre> | ||
| + | [Unit] | ||
| + | Description=Qortal Service | ||
| + | After=syslog.target network.target rpcbind.service | ||
| + | |||
| + | [Service] | ||
| + | User=alarm | ||
| + | Group=users | ||
| + | ExecStart=/opt/qortal/start.sh | ||
| + | WorkingDirectory=/opt/qortal | ||
| + | |||
| + | [Install] | ||
| + | WantedBy=multi-user.target | ||
| + | </pre> | ||
| + | Save the file. Now reload systemd | ||
| + | $ sudo systemctl daemon-reload | ||
| + | Enable and start the service. | ||
| + | $ sudo systemctl start qortal.service | ||
| + | This didn't seem to work. Need to do more research. Do we need a UI? | ||
Latest revision as of 21:20, 9 May 2022
Overview
On Thursday, April 21 2022 a meeting was held at meet.gr0x0rd.com where we discussed the necessity of building a local alternative to the internet. We agreed that we would use raspberry pi devices running linux that could serve as hosts for a mesh network based on reticulum and qortal, and that the devices would communicate with each other using LoRa radios. I was tasked with getting an image up and running that could be deployed to pi devices within the community, and to provide that image.
My intention here is to provide the instructions for building said image so that can be reviewed by the community and leveraged by others.
After some basic research I have, at least initially, chosen to implement this project using Archlinux.
Why Archlinux?
There will probably be some questions on why I would choose Archlinux to run on the Raspberry Pi ARM architecture as opposed to the default Raspberry Pi OS or some other more common or vanilla distro. Some justification for that thought process:
- Customization. Arch is highly customizable and lean, but doesn't suffer from the "build your own excitement brick by brick" heavy lifting of Gentoo and other from-source distros.
- Heterogeneity. The most commonly used distros, and those will some sort of corporate structure attached (for example Red Hat and Ubuntu) will be early targets.
- It's Canadian. Yes, Arch is still a Canadian based project, as far as I know eh.
- Documentation. The community docs are great (I haven't ever had to ask a question on the forums and have run it nearly 5 years) and have expanded on that here in this wiki.
Project Objectives
- 20220504: To have a text-chat based meeting between the project founders using only the hardware and software outlined in this wiki without use of the internet.
Meetings
Hardware you will need
- A Raspberry Pi 3/4 with a power supply, cooling (fan or heatsink), case, and sdcard
- A LoRa radio http://www.lilygo.cn/claprod_view.aspx?TypeId=62&Id=1281&FId=t28:62:28
Latest version of the image
The latest version of the image is available at https://www.gr0x0rd.com/freedomstack-latest.img.gz .
If you need instructions on how to load this image onto your sdcard, you can find instructions for linux here . If you just want to get started, you should be able to just flash this image onto your sdcard, plug it into your pi, and off you go.
If you would rather build your own image, you can follow the steps below if you want to build it using Archlinux, or just take away a few of the useful steps if you choose some other operating system.
Install
If you are unfamiliar with the raspberry pi and how it works, you may benefit from browsing some of my previous documentation.
Download the image files
I procured the ArchLinux ARM image files for the raspberry pi from https://archlinuxarm.org/about/downloads . You will want the image for the Raspberry Pi 3/4, which is the ARMv8 image. I noted that the download was not secure as it lacked a security certificate (fucking guys too lazy for letsencrypt I guess). I didn't bother with the md5 checksums, but I did a quick clamscan on it to make sure there weren't any nasties in the archive.
Create sdcard partitions
Insert your sd card into a reader and connect it to your system. Note that these instructions are for linux. Someone may want to make instructions for Windows eventually, but time would likely be better spent teaching Windows users to use linux (my opinion). This guide assumes a kernel assignment for the sd cards of /dev/sdX . I usually use
$ ls -al /dev/sd*
To identify the drive. Before you overwrite it with the image, if there is anything precious on it, you may want to make an image of it for later. If any of the sdcard partitions auto-mounted in your desktop UI, unmount (but do no eject) them. Next, we will prepare the sdcard.
$ sudo fdisk /dev/sdX
Press d until the existing partitions are deleted, if they exist. Press p to display partitions, and you should see none. Now create a 128MB boot partition.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): <press enter>
Using default response p.
Partition number (1-4, default 1): <press enter>
First sector (2048-15351807, default 2048): <press enter>
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-??????, default ??????): +128M
Created a new partition 1 of type 'Linux' and of size 128 MiB.
Next we will set the boot partition to type FAT32.
Command (m for help): t Hex code or alias (type L to list all): c Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.
Mark the partition as active so it's bootable. Note fdisk defaults to the second partition, which is not what we want.
Command (m for help): a Partition number (1,2, default 2): 1 The bootable flag on partition 1 is enabled now.
Now we will create the root partition, which will essentially be the rest of the disk.
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (2-4, default 2):
First sector (264192-15351807, default 264192):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (264192-15351807, default 15351807):
Created a new partition 2 of type 'Linux' and of size 7.2 GiB.
Write the new partitions to the disk.
Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.
To confirm the partitions have been correctly created, check devices. If the paritions auto-mount, you can skip this step, but be sure to unmount but not eject the partitions.
$ sudo ls -al /dev/sd*
You should see partitions /dev/sdX1 and /dev/sdX2. Now, let's apply a vfat filesystem to the boot partition.
Create filesystems
$ sudo mkfs.vfat /dev/sdX1
Next we apply a linux filesystem to the root partition.
$ sudo mkfs.ext4 /dev/sdX2
The command should complete with a note about superblocks.
Copy the image files
In order to copy the files you'll need to mount them. Create a folder in your favorite workspace
$ mkdir sdcard $ cd sdcard
Create a folder for the boot partition and mount the sdcard boot partition there.
$ mkdir boot $ sudo mount /dev/sdX1 boot
Create a folder for the root partition and mount the sdcard root partition there.
$ mkdir root $ sudo mount /dev/sdX2 root
Next you will want to extract the archive you downloaded. I extracted it to a file called ~/arch_arm which I will use in the example below.
$ sudo mv ~/arch_arm/boot/* ~/sdcard/boot/
Running the above command will spit some errors are the kernel attempts to set permissions on the newly copied files but is unable to do so because of the filesystem type. This can be ignored. Next we will move the rest of the files to the root volume.
$ sudo mv ~/arch_arm/* ~/sdcard/root/
I ran into an issue where the extracted files inherited the UID/GID of my local user. Check the files in the root folder, and if this is the case
$ sudo chown -R root:root ~/sdcard/root/*
That should be all we need for the sdcard. Unmount the partitions.
$ sudo umount ~/sdcard/root $ sudo umount ~/sdcard/boot
Boot the pi
Insert the sdcard into the pi. Ensure it has power and ethernet, because wifi will not work OOTB (unless your security is really, really bad). Connect a monitor and keyboard if you want to watch it boot and interact with it. If not, you'll probably need to find it on your LAN. Substitute your local class c (or otherwise) subnet for 192.168.1.0/24 below as needed. The default device name is alarm so we can find it by grepping for that.
$ sudo nmap -sn 192.168.1.0/24 | grep alarm
Note the IP. You can now ssh into the pi.
ssh into the pi
$ ssh alarm@<ip from above command>
The password is alarm.
Set up sudo
The alarm account does not have sudo powers OOTB, nor can it su to root. The ssh daemon is also configure to prevent root logins, which is just good security. As such it was necessary to log in manually as root (password root) and set up basic sudo access for the alarm user. First, initialize the package manager and do a system update. Archlinux's package manager is called pacman.
# pacman-key --init # pacman-key --populate archlinuxarm # pacman -Syu
Next, install the sudo package.
# pacman -S sudo
After the package has been installed, edit the sudoers file.
# nano /etc/sudoers
Remove the comment from the line allowing the wheel group to run privileged commands. Check to comfirm that the alarm user is in the wheel group:
# groups alarm
If you see wheel in the results you're good to go. Reboot the pi to apply the system updates.
# reboot
You can now log in via ssh as the alarm user and run privileged commands.
Set home permissions
I noted an error when ssh'ing in, likely because I thumped the permissions when I extracted the archive and recursively set them to root. Grant alarm access to its home folder.
$ sudo chown -R alarm:alarm /home/alarm
Set the locale
By default everything will be set to GMT so we will need to configure the timezone.
$ sudo ln -sf /usr/share/zoneinfo/Canada/Pacific /etc/localtime
Install helpful packages
ssh into your pi as alarm. We will install some basic networking packages and other tools.
$ sudo pacman -S dnsutils net-tools nmap cronie
cronie is a cron daemon so it makes sense to enable and start the cron service.
$ sudo pacman -S cronie $ sudo systemctl enable cronie $ sudo systemctl start cronie
Enabling AUR
I expect we will also be needing packages from the Archlinux User Repository (AUR) so we will set up yay, a pacman equivalent.
$ sudo pacman -S --needed base-devel
Press enter to install all options (default) then press enter again. This will install a bunch of necessary components for building packages including gcc, make and libtool. Next, create a folder to house the yay source files.
$ sudo mkdir -p /usr/local/aur $ sudo chmod -R 777 /usr/local/aur $ cd /usr/local/aur
Install the git package.
$ sudo pacman -S git
Pull down the yay sources from git.
$ https://aur.archlinux.org/yay.git
Navigate into the folder and build yay.
$ cd yay $ makepkg -si
The image should now be in great shape to install reticulum, qortal, umbrel, helium... time to take an image.
Installing reticulum
The reticulum getting started fast guide and other documentation references pip so we will need to install that prerequisite.
$ sudo pacman -S python-pip
Once installed, as per the documentation
$ sudo pip3 install rns
Configuring the rnsd service
We want this to be running with our pi so a service is required. As per the docs, create a symlink to the binary created by the pip installer
$ sudo ln -s $(which rnsd) /usr/local/bin/
Now create the file for the systemd service.
$ sudo nano /etc/systemd/system/rnsd.service
Paste in the code from the documentation. Note we are using the alarm user to run the service.
[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=alarm ExecStart=rnsd --service [Install] WantedBy=multi-user.target
Save the file. With the service ready to go, let's enable and start the service.
$ sudo systemctl enable rnsd $ sudo systemctl start rnsd
Looks like the service is running:
[alarm@alarm ~]$ ps aux | grep rnsd alarm 767 22.0 2.8 550572 26092 ? Ssl 20:57 0:01 /usr/bin/python /usr/local/bin/rnsd --service
To test and confirm, a reboot of the pi later:
[alarm@alarm ~]$ rnstatus Shared Instance[37428] Status: Up Connected applications: 0 RX: 0 B TX: 0 B AutoInterface[Default Interface] Status: Up RX: 0 B TX: 0 B
Time for another image.
Using Nomadnet
todo: add some screenshots from my other systems
Test Scenario: Try and get two nomadnet clients connecting to each other on the test network. Hardware: Raspberry Pi and Linux laptop
Status: As of Sunday May 8, I have connected to the test network from my RPI and Laptop. I have also run a couple of Docker containers that are each running the client. One small observation is that the application runs better in Docker. On my Linux machine, when i hit C-e to view Peer Info on a node, the client would crash. When I debugged the client, it appeared that the 'window' event loop and handlers lost control of the process, necessitating the closing of the application.
After some experience and experimenting I would summarise the communication with the client like this:
You connect to the network and wait for peers to signal they are available to talk to. When you see a peer, you have the option to save the node info and name the node. You can also connect to the node. Each node can be configured to serve up data to share, much like a simple static web page. You can add links to your pages (written in markup) and links can be to other pages, or to files that you want to share.
Each node has a couple of address of note, and for communication, namely sending messages, the useful address is the xxx address [insert image]
First Steps:
The default reticulum config needs to be changed.
The two config files that should be reviewed are
- ~/.reticulum/config
- ~/.nomadnet/config.
I added the additional section *RNS Testnet Frankfurt* to my config file as instructed on Public Testnet. If you are going add this interface then I expect the *Default Interface" should be turned off.
[[Default Interface]] type = AutoInterface interface_enabled = False
[[RNS Testnet Frankfurt]] type = TCPClientInterface interface_enabled = yes outgoing = True target_host = frankfurt.rns.unsigned.io target_port = 4965
Another change I made to the configuration was to edit the nomadnet config file to set the following settings:
- enable_node = yes
- node_name = <your choice here>
some resources used [1]
Installing qortal
Java is required.
$ sudo pacman -S jdk-openjdk
Download the qortal.zip archive from https://qortal.org/downloads/ . I extracted it to /opt . Give permissions to alarm
$ sudo chown -R alarm:alarm /opt/qortal
Make the bash scripts executable
$ chmod +x /opt/qortal/*.sh
Run the start script.
[alarm@alarm qortal]$ ./start.sh Passed Java version check qortal running as pid 5542
Configure the qortal service
Now let's configure a service for it. First, stop the running instance.
$ ./stop.sh
Create a service file for qortal.
$ sudo nano /usr/lib/systemd/system/qortal.service
Paste the following:
[Unit] Description=Qortal Service After=syslog.target network.target rpcbind.service [Service] User=alarm Group=users ExecStart=/opt/qortal/start.sh WorkingDirectory=/opt/qortal [Install] WantedBy=multi-user.target
Save the file. Now reload systemd
$ sudo systemctl daemon-reload
Enable and start the service.
$ sudo systemctl start qortal.service
This didn't seem to work. Need to do more research. Do we need a UI?