You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

868 lines
18 KiB

10 months ago
---
title: A slim D-STAR gateway on a Raspberry Pi 2
10 months ago
summary: I wrote down the installation of a forked DStarGateway with a slim
2 months ago
dashboard based on Javascript on a Raspberry Pi 2 -- using Archlinux.
date: 2024-02-03T06:33:16+0100
2 months ago
lastmod: 2024-09-28T23:48:07+0000
10 months ago
categories:
- amateur-radio
tags:
- archlinux
- dstar
- hotspot
- linux
- mmdvm
- raspberry-pi
---
## Installation of Archlinux
I usually setup any Raspberry Pi without screen and keyboard but I make use of
the [serial console](https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-uarts).
This procedure is taken from
[archlinuxarm.org](https://archlinuxarm.org/platforms/armv7/broadcom/raspberry-pi-2)
-- a more detailed tutorial is shown there.
10 months ago
![Raspi 2 with wires connected to GPIO Pins GND, RXD and TXD](setup_console.jpg "I haven't changed a thing
of the initial configuration -- the serial console works just out of the box")
10 months ago
### Preparations (microSD card)
Partition the microSD card on your PC or laptop.
2 months ago
```console
10 months ago
$ sudo fdisk /dev/sda
2 months ago
```
10 months ago
2 months ago
```
10 months ago
Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 411647 409600 200M c W95 FAT32 (LBA)
/dev/sda2 411648 15759359 15347712 7.3G 83 Linux
2 months ago
```
10 months ago
Format filesystems.
2 months ago
```console
10 months ago
$ sudo mkfs.vfat /dev/sda1
$ sudo mkfs.ext4 /dev/sda2
2 months ago
```
10 months ago
I am curerntly in `~/mnt`.
2 months ago
```console
10 months ago
$ mkdir boot root
$ sudo mount /dev/sda1 boot
$ sudo mount /dev/sda2 root
$ wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-armv7-latest.tar.gz
$ sudo bsdtar -xpf ArchLinuxARM-rpi-armv7-latest.tar.gz -C root
$ sync
$ sudo mv root/boot/* boot/
$ sudo umount boot root
2 months ago
```
10 months ago
So, place the microSD card in the Raspberry Pi and boot it up (with the serial console connected).
### First start
There are the following two users pre-defined:
2 months ago
| Username | Password |
| -------- | -------- |
| _root_ | _root_ |
| _alarm_ | _alarm_ |
10 months ago
I prefer my username as _dominic_, so I changed it:
2 months ago
```console
10 months ago
# usermod -l dominic -d /home/dominic -m alarm
# groupmod -n dominic alarm
2 months ago
```
10 months ago
{{< alert circle-info >}}
The user _alarm_ may come from **A**rch**L**inux **ARM**.
{{< /alert >}}
So the first real thing is upgrading the system. We start as this:
2 months ago
```console
10 months ago
# pacman-key --init
# pacman-key --populate archlinuxarm
# pacman -Syu
2 months ago
```
10 months ago
Some general system administration tasks, such as timezone setup network
setup etc...
10 months ago
I'm using NetworkManager on the Raspi so I install it
2 months ago
```console
10 months ago
# pacman -S networkmanager
10 months ago
# systemctl enable --now NetworkManager
10 months ago
# nmcli device wifi connect {network-ssid} --ask
2 months ago
```
10 months ago
Now we may login via ssh.
I had some problems with date and time, so a look at `systemd-timesyncd.service`,
`timedatectl status`, `timedatectl show-timesync` and `timedatectl timesync-status`
could be useful.
## Installation of DStarGateway
I prefer compiling as normal user so I login as _dominic_. We will need some packages.
2 months ago
```console
10 months ago
$ sudo pacman -S --needed base-devel wget boost man-db gtest bind
2 months ago
```
10 months ago
I hope I got all that we need, if you run into errors, just install the missing ones :wink:
2 months ago
```console
10 months ago
$ mkdir git && cd git
$ git clone https://github.com/F4FXL/DStarGateway.git
$ cd DStarGateway
$ make
2 months ago
```
10 months ago
This ran for 38 minutes -- I will not forget to run `make -j4` the next time :face_with_rolling_eyes:
{{< alert "circle-info" >}}
**Update**: This took <mark>3m 40s</mark> on my Raspberry Pi 4 2GB when run with `make -j4`.
{{< /alert >}}
10 months ago
You would now typically install the files but this is the part that made me stop for a while.
2 months ago
```console
10 months ago
$ sudo make install
2 months ago
```
10 months ago
2 months ago
It will break, but at least it installs the binary files into `/usr/local/bin`.
10 months ago
{{< alert "circle-info" >}}
**Update**: I did not have these problems on the Raspberry Pi 4 any more.
{{< /alert >}}
10 months ago
Whatever I was doing, it won't work automated. I'm not a developer, but to me this looks
like as if `make -C` enters the directory before it runs the top-level Makefile so the
`export ...` lines never get executed and the Makefiles in the sub-directories will never
know about them, I have to manually install the `Data` folder contents (AMBE files, Hostfiles).
Move to the `Data` directory and add the following line on top of the file:
2 months ago
```make
10 months ago
export DATA_DIR=/usr/local/share/dstargateway.d
2 months ago
```
10 months ago
Then run `sudo make install` within the `Data` directory again and all should be fine.
Also install the hostfiles (this will need the program _wget_).
10 months ago
2 months ago
```console
10 months ago
$ sudo make newhostfiles
2 months ago
```
10 months ago
Copy the systemd unit files to the right directory per hand:
{{< alert "circle-info" >}}
**Update**: Again, on the Pi 4 this was not needed. It looks like I messed something
up on the Raspberry Pi 2. Yet I leave the hints, they may become useful hopefully.
{{< /alert >}}
2 months ago
```console
10 months ago
$ sudo cp debian/* /usr/lib/systemd/system/
2 months ago
```
10 months ago
{{< alert >}}
Inspect them because you may edit some paths.
{{< /alert >}}
Also have a look at the configuration files in `/usr/local/etc/`.
Enable the services, but I don't start them yet (except for a short test) because
the hotspot will connect to the DSTAR reflector but we can't talk or hear anything.
Once they are enabled, they will autostart at the next reboot.
To enable the services:
2 months ago
```console
10 months ago
$ sudo systemctl daemon-reload
$ sudo systemctl enable dstargateway.service
$ sudo systemctl enable dgwtimeserver.service
2 months ago
```
10 months ago
The second is only needed if you want time announcements.
## Installation of MMDVMHost
Also this requires special packages:
2 months ago
```console
10 months ago
$ sudo pacman -S libsamplerate
2 months ago
```
10 months ago
2 months ago
```console
10 months ago
$ git clone git@github.com:g4klx/MMDVMHost.git
$ cd MMDVMHost
$ make -j4
$ sudo make install-service
2 months ago
```
10 months ago
That would probably fail, but we can do it by hand.
Setup the user _mmdvm_:
2 months ago
```console
10 months ago
$ sudo useradd --user-group -M --system mmdvm --shell /bin/false
$ sudo usermod --groups uucp --append mmdvm
2 months ago
```
10 months ago
So we run the command one more time:
2 months ago
```console
10 months ago
$ sudo make install-service
2 months ago
```
10 months ago
Binaries are installed and the systemd unit files too.
Modify the configuration file `/etc/MMDVM.ini`.
Enable the service:
2 months ago
```console
10 months ago
$ sudo systemctl daemon-reload
$ sudo systemctl enable mmdvmhost.service
2 months ago
```
10 months ago
## Setup the UART
We can't start MMDVMHost right away (well, we can, but it will not work yet).
Enable the UART in `/boot/config.txt`:
2 months ago
```ini
enable_uart=1
2 months ago
```
{{< alert "circle-info" >}}
**Update**: On the Raspberry Pi 4 again, we would write something like
2 months ago
```ini
enable_uart=1
dtoverlay=disable-bt
2 months ago
```
But we should not need to disable the serial console `serial-getty@ttyAMA0.service`.
{{< /alert >}}
Add this near the top or after `[All]`.
10 months ago
We need to disable the serial console because we need the UART at the GPIO pins
for our modem hardware.
Disable the serial console service:
10 months ago
2 months ago
```console
10 months ago
$ sudo systemctl disable serial-getty@ttyAMA0.service
2 months ago
```
10 months ago
Open `/boot/cmdline.txt` and remove `console=serial0,115200` from the line.
Save and reboot.
10 months ago
## Configuration
Make sure to check them before bringing up any service.
### DStarGateway
I removed unused configuration parts, you can leave them in your config, but I
want this code here as small as possible without loosing too much of information.
2 months ago
```ini
10 months ago
[Gateway]
type=hotspot
callsign=CALLSIGN
10 months ago
address=0.0.0.0
icomAddress=172.16.0.20
icomPort=20000
hbAddress=
hbPort=20010
latitude=0.0
longitude=0.0
description1=
description2=
url=
language=english_us
[ircddb_1]
enabled=true
hostname=ircv4.openquad.net
username=
password=
[ircddb_2]
enabled=false
# [...]
[ircddb_3]
enabled=false
# [...]
[ircddb_4]
enabled=false
# [...]
[Repeater_1]
enabled=true
band=E
callsign=CALLSIGN
10 months ago
address=
port=20011
type=hb
reflector=REF096 A
reflectorAtStartup=
reflectorReconnect=5
frequency=432.7625
offset=-0.0
rangeKm=20
latitude=0.0
longitude=0.0
agl=
description1=
description2=
url=
band1=
band2=
band3=
[Repeater_2]
enabled=false
# [...]
[Repeater_3]
enabled=false
# [...]
[Repeater_4]
enabled=false
# [...]
[APRS]
enabled=false
hostname=rotate.aprs2.net
port=14580
password=12345
positionSource=
[GPSD]
address=
port=
[Log]
path=/var/log/dstargateway/
fileRoot=
fileRotate=
fileLevel=
displayLevel=
[Paths]
data=/usr/local/share/dstargateway.d
10 months ago
[DExtra]
enabled=true
maxDongles=5
[DPlus]
enabled=true
maxDongles=5
login=
[DCS]
enabled=true
[XLX]
enabled=true
hostfileUrl=http://xlxapi.rlx.lu/api.php?do=GetXLXDMRMaster
[DRats]
enabled=false
[Remote]
enabled=false
port=4242
password=CHANGE_ME
[AccessControl]
whiteList=
blackList=
restrictList=
[Daemon]
daemon=false
pidfile=/var/run/dstargateway/dstargateway.pid
user=dstar
2 months ago
```
10 months ago
You can set `band=B` or `band=C` in `[Repeater_1]`. I have `E` because I sometimes
test a dual-hat hotspot which used to have `B` set and I've already setup `E` in my
DSTAR terminal settings on [regist.dstargateway.org](https://regist.dstargateway.org/).
### MMDVMHost
This would be a very long list, I removed things that I did not change from the example
config file. I also changed some values to not have a duplicate of my hotspot running
wild somewhere, so make sure you change all the options to match your own setup.
2 months ago
```ini
10 months ago
[General]
Callsign=CALLSIGN
Id={DMR_ID} # or CCS or whatever this is called
Timeout=180
Duplex=0
RFModeHang=10
NetModeHang=3
Display=None
Daemon=1
[Info]
RXFrequency=432762500
TXFrequency=432762500
Power=1
Latitude=0.0
Longitude=0.0
Height=0
Location=Home
Description=DSTAR Hotspot
URL=https://oe7drt.com
[Log]
DisplayLevel=0
FileLevel=2
FilePath=/var/log/mmdvm/
FileRoot=MMDVM
FileRotate=1
[CW Id]
Enable=0
Time=10
[DMR Id Lookup]
File=DMRIds.dat
Time=24
[NXDN Id Lookup]
File=NXDN.csv
Time=24
[Modem]
Protocol=uart
UARTPort=/dev/ttyAMA0
UARTSpeed=115200
TXInvert=1
RXInvert=0
PTTInvert=0
TXDelay=100
RXOffset=-75
TXOffset=-75
DMRDelay=0
RXLevel=50
TXLevel=50
RXDCOffset=0
TXDCOffset=0
RFLevel=100
RSSIMappingFile=/usr/local/etc/RSSI.dat
10 months ago
UseCOSAsLockout=0
Trace=0
Debug=0
[Transparent Data]
Enable=0
# [...]
[D-Star]
Enable=1
Module=E
SelfOnly=1
AckReply=1
AckTime=750
AckMessage=0
ErrorReply=1
RemoteGateway=0
WhiteList=
[DMR]
Enable=0
# [...]
[System Fusion]
Enable=0
# [...]
[P25]
Enable=0
# [...]
[NXDN]
Enable=0
# [...]
[M17]
Enable=0
# [...]
[FM]
Enable=0
# [...]
[AX.25]
Enable=0
# [...]
[D-Star Network]
Enable=1
LocalAddress=127.0.0.1
LocalPort=20011
GatewayAddress=127.0.0.1
GatewayPort=20010
Debug=0
[DMR Network]
Enable=0
# [...]
[System Fusion Network]
Enable=0
# [...]
[P25 Network]
Enable=0
# [...]
[NXDN Network]
Enable=0
# [...]
[M17 Network]
Enable=0
# [...]
[POCSAG Network]
Enable=0
# [...]
[FM Network]
Enable=0
# [...]
[AX.25 Network]
Enable=0
# [...]
2 months ago
```
10 months ago
2 months ago
```console
$ sudo cp /home/dominic/git/MMDVMHost/RSSI.dat /usr/local/etc/
2 months ago
```
10 months ago
### dgwtimeserver
2 months ago
```ini
10 months ago
[TimeServer]
callsign=CALLSIGN
10 months ago
address=
format=voice
language=english_us_2
interval=60
[Paths]
data=/usr/local/share/dstargateway.d/
[Repeater_1]
enabled=true
band=E
[Repeater_2]
enabled=false
band=
[Repeater_3]
enabled=false
band=
[Repeater_4]
enabled=false
band=
[Log]
path=/var/log/dstargateway/
fileRoot=
fileRotate=
fileLevel=
displayLevel=
[Daemon]
daemon=false
pidfile=/var/run/dstargateway/dstargateway.pid
user=dstar
2 months ago
```
10 months ago
## Updating hostfiles
{{< alert "circle-info" >}}
This paragraph has been added on 18 Feb 2024
{{< /alert >}}
So we will probably update our hostfiles and I made a little script that
fetches actual hostfiles from trusted sources. But since Archlinux does not
come with any cron installed I could either install one or just use systemd timers.
I went with the latter one of the options and assuming the script that updates the hostfiles
is located in `/home/dominic/bin/update-hosts.sh` I used these unit-files that I put into
`/usr/lib/systemd/system/`:
### update-hosts.service
2 months ago
```systemd
[Unit]
Description="Update D-STAR hostfiles"
After=network.target
[Service]
Type=oneshot
ExecStart=/home/dominic/bin/update-hosts.sh
ExecStartPost=/usr/bin/systemctl restart dstargateway.service
[Install]
WantedBy=default.target
2 months ago
```
### update-hosts.timer
2 months ago
```systemd
[Unit]
Description="Update D-STAR hostfiles timer"
[Timer]
OnBootSec=5min
OnCalendar=daily
RandomizedDelaySec=20min
Unit=update-hosts.service
[Install]
WantedBy=default.target
2 months ago
```
Enable the timer and it will run now and daily in future.
2 months ago
```console
$ sudo systemctl enable --now update-hosts.timer
2 months ago
```
10 months ago
## Install a dashboard
I will install the [dashboard from John Hays (K7VE)](https://github.com/johnhays/dsgwdashboard)
as my first look at it looked promising.
{{< alert >}}
I've created an [issue](https://github.com/johnhays/dsgwdashboard/issues/2) in January 2024
regarding the crash of the dashboard when other gateways connect to our hotspot and the
actual problem is still not yet resolved - there have been made some modifications to actually enable
redirecting of the HTTP port but the HTTPS certs are still needed and since I don't use them
on the hotspot and all HTTPS traffic is handled by a reverse proxy in my network this is just
another complexity that I don't need.
I have also uploaded my fork of it (including the modifications below) on my git repo:
<https://gits.oe7drt.net/dominic/dsgwdashboard/src/branch/only_http>
You can see the dashboard in action at: <https://hotspot.oe7drt.net/>
{{< /alert >}}
10 months ago
But: I will not install this as it is in his instructions, because I don't like
when these kind of applications (simple dashboards for example) have to be run
as the _root_ user. I will therefore create a new user called _dashboard_ who
will run the webserver later.
We need a few packages for this:
2 months ago
```console
10 months ago
$ sudo pacman -S nodejs npm
2 months ago
```
10 months ago
Create and impersonate our new user:
2 months ago
```console
10 months ago
$ sudo useradd --user-group -m --system dashboard --shell /bin/bash
$ sudo su - dashboard
2 months ago
```
10 months ago
Now we are the user _dashboard_ and we will install the dashboard:
2 months ago
```console
10 months ago
$ git@github.com:johnhays/dsgwdashboard.git
$ cd dsgwdashboard
$ node -v
$ npm install -save
2 months ago
```
10 months ago
We would now install some certificates to let the webserver be accessible
via HTTPS, but I maintain a reverse-proxy at my home which will take care
of all the https-connections.
Therefore I modify the `index.js` file according to the following patch:
2 months ago
```patch
10 months ago
diff --git a/index.js b/index.js
index 0c71092..b8a7aba 100644
10 months ago
--- a/index.js
+++ b/index.js
@@ -1,4 +1,4 @@
-const https = require("https");
+const http = require("http");
const fs = require("fs");
const ini = require("ini");
const lineReader = require('line-reader');
@@ -32,12 +32,8 @@ updatelinks();
let serverPort = inifile.config.port;
-const server = https
+const server = http
.createServer(
- {
- key: fs.readFileSync("key.pem"),
- cert: fs.readFileSync("cert.pem"),
- },
app
)
.listen(serverPort, ()=>{
@@ -83,7 +79,7 @@ function updatelinks() {
};
let i = 0;
while (i < lines.length) {
- if(lines[i] != "") {
+ if(lines[i] != "" && lines[i].match(linksregex)) {
var mylinks = lines[i].match(linksregex);
// console.log(JSON.stringify(lines[i]));
var linkrec = {'timestamp':mylinks[1].substr(0,19) , 'protocol':mylinks[2] , 'device':mylinks[4],
2 months ago
```
10 months ago
Modify the `dashboard.ini` file to change the port from 443 to 8443.
Why? Because I want to run the webserver as non-root user[^1]!
2 months ago
```ini
10 months ago
[config]
dgwconfig=/usr/local/etc/dstargateway.cfg
host=hotspot.oe7drt.net
port=8443
2 months ago
```
10 months ago
{{< alert circle-info >}}
This might be confusing now, the **actual host** above does not listen to port 8443 because
there is a reverse-proxy in-between (and actually a firewall/router too).
{{< /alert >}}
The actual path of this host and how it will be routed:
{{< mermaid >}}
%%{init: {"flowchart": {"htmlLabels": false}} }%%
graph LR;
A([Internet user]):::usr -- "`**HTTPS**`" -->B["`router/firewall
_hotspot.oe7drt.net_`"]:::fw;
B-- "`**HTTPS**`" -->C["`reverse-proxy
_proxy.lan_`"]:::rev;
C-- "`**HTTP**`" -->D["`hotspot dashboard
_hotspot.lan_`"]:::dash;
classDef usr stroke:#faa
classDef fw stroke:#f55
classDef rev stroke:#9f9
classDef dash stroke:#0f0
{{< /mermaid >}}
This configuration is now as slim as I could make, removing encryption on the dashboard
made it even better in terms of performance and maintainability as I don't have to
worry about the certificates on this host and no direct port-forwarding to this host
has been made.
I will now disable the shell for the _dashboard_ user because I won't need
to login as the _dashboard_ user again.
2 months ago
```console
10 months ago
$ sudo chsh -s /bin/false dashboard
2 months ago
```
10 months ago
2 months ago
[^1]:
Ports below <kbd>1024</kbd> can only be used as the _root_ user. Those are socalled
[privileged ports](https://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html).
To run the program as non-root user we need to set the port to something
above <kbd>1024</kbd>.
10 months ago
### Start the dashboard with systemd
John already provides a systemd unit file, we need to copy this to the
right directory.
2 months ago
```console
10 months ago
$ sudo cp /home/dashboard/dsgwdashboard/util/dsgwdashboard.service /usr/lib/systemd/system/
2 months ago
```
10 months ago
Edit the file, because John uses different paths than we do.
2 months ago
```systemd {hl_lines="7 9"}
10 months ago
[Unit]
Description=D-STAR Gateway Dashboard
After=network.target network-online.target
10 months ago
Wants=network-online.target
[Service]
User=dashboard
Type=simple
WorkingDirectory=/home/dashboard/dsgwdashboard
ExecStart=/usr/bin/node index.js
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=0
StandardOutput=syslog
StandardError=syslog
[Install]
WantedBy=multi-user.target
2 months ago
```
10 months ago
Enable and start the dashboard:
2 months ago
```console
10 months ago
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now dsgwdashboard.service
2 months ago
```
10 months ago
## DSTAR Registration
A DSTAR registration is needed if you want your transmission to
10 months ago
be heard on original ICOM repeaters. Otherwise your transmission will
not be forwarded and you may be searching for errors...
I registered at <https://regist.dstargateway.org/> but there
10 months ago
is one important thing to add to the webui there: do not choose long
passwords (like those from a password manager) because it will get
cut off somewhere and it took me quite a while to realize that.
{{< alert skull-crossbones >}}
**I can't believe that there are still websites in 2024 that limit
the lenght of a password!**
{{< /alert >}}
This can be an indication, that our passwords are saved in **cleartext**.
{{< alert >}}
This is one reason to not use the same password on different websites/services.
{{< /alert >}}
For your information: 12 characters work -- I couldn't bring me back up to test more.
Many password-reset emails have been sent for this already so I couldn't be
bothered to investigate even more into that.
## Final words
So this note ends right here, hopefully this will be of any help to me in
the future or somebody that found it online.