Plug in stick, log in.
http://192.168.100.1/usbdebug.html
Reboot (unplug, replug)
adb shell
setprop service.adb.root 1; busybox killall adbd
adb reboot edl
edl rf uz801-stock.bin
Then download individual partitions.
edl rl uz801_stock --genxml
Reboot (unplug, replug)
adb reboot bootloader
cd OpenStick/flash/
./flash.sh
sudo mount -o loop ~/firmwares/uz801_stock/modem.bin /mnt/test
to mount the modem.bin file
then copy all the files over to the /lib/firmware folder on the stick.
on the stick: mkdir ~/fw
on the computer you’re using the do the work: scp -r /mnt/test/image/* user@192.168.200.1:~/fw
on the stick: sudo mv /lib/firmware/wlan ~/fw
sudo rm -r /lib/firmware/*
sudo mv ~/fw/* /lib/firmware
change default modem settings depending on SIM card and available network
sudo nmcli con down lte
sudo nmcli con modify lte gsm.apn web.sentel.com
sudo nmcli con modify lte connection.autoconnect yes
sudo nmcli con modify lte connection.autoconnect-retries 0
sudo mmcli -m 0 --set-allowed-modes="4g|3g" --set-preferred-mode=4g
(note this is mmcli, not nmcli)
sudo nmcli con up lte
then update the bookworm install with sudo apt update/upgrade
make user not need sudo password sudo visudo
then replace %sudo ALL=(ALL:ALL) ALL
with %sudo ALL=(ALL) NOPASSWD: ALL
(optional) install node red (before installing anything else, since the installer script requires 100MB RAM). Node-Red, Telegraf and Victoria Metrics seem to be a bit too much for the stick, it is unstable with less than 50MB RAM remaining. Any of the three can be left out.
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
install mosquitto and configure (adapted from here)
sudo apt install mosquitto
sudo nano /etc/mosquitto/mosquitto.conf
and add the following:
listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd-file
now need to establish logins and passwords for various users of your MQTT broker (IOT devices, telegraf, admin)
sudo mosquitto_passwd -c /etc/mosquitto/passwd-file user
(for the first user)
sudo mosquitto_passwd /etc/mosquitto/passwd-file user
(for any users after the first)
install Victoria Metrics and configure
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.104.0/victoria-metrics-linux-arm64-v1.104.0.tar.gz
sudo tar -xvzf victoria-metrics-linux-arm64-v1.104.0.tar.gz -C /usr/local/bin
sudo useradd -s /usr/sbin/nologin victoriametrics
sudo mkdir -p /var/lib/victoria-metrics && sudo chown -R victoriametrics:victoriametrics /var/lib/victoria-metrics
Add a service file:
sudo nano /etc/systemd/system/victoriametrics.service
[Unit]
Description=VictoriaMetrics service
After=network.target
[Service]
Type=simple
User=victoriametrics
Group=victoriametrics
ExecStart=/usr/local/bin/victoria-metrics-prod -storageDataPath=/var/lib/victoria-metrics -retentionPeriod=365d -selfScrapeInterval=10s
SyslogIdentifier=victoriametrics
Restart=always
PrivateTmp=yes
ProtectHome=yes
NoNewPrivileges=yes
ProtectSystem=full
[Install]
WantedBy=multi-user.target
Activate service:
sudo systemctl daemon-reload && sudo systemctl enable --now victoriametrics.service
If needed, install telegraf and configure (from here)
cd ~/
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
gpg --with-fingerprint --show-keys ./influxdata-archive_compat.key
cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list
sudo rm -f /etc/apt/trusted.gpg.d/influxdb.gpg
sudo apt update
sudo apt install telegraf
adjust telegraf.conf to receive data from mqtt (and system metrics if desired) and send to victoria metrics (which can accept influxdb line protocol, so is a drop-in, low memory replacement for influxdb)
sudo nano /etc/telegraf/telegraf.conf
# Telegraf Configuration
#
# Global tags can be specified here in key="value" format.
[global_tags]
# dc = "us-east-1" # will tag all metrics with dc=us-east-1
# rack = "1a"
## Environment variables can be used as tags, and throughout the config file
# user = "$USER"
# Configuration for telegraf agent
[agent]
## Default data collection interval for all inputs
interval = "10s"
## Rounds collection interval to 'interval'
## ie, if interval="10s" then always collect on :00, :10, :20, etc.
round_interval = true
## Telegraf will send metrics to outputs in batches of at most
## metric_batch_size metrics.
## This controls the size of writes that Telegraf sends to output plugins.
metric_batch_size = 1000
## Maximum number of unwritten metrics per output. Increasing this value
## allows for longer periods of output downtime without dropping metrics at the
## cost of higher maximum memory usage.
metric_buffer_limit = 10000
## Collection jitter is used to jitter the collection by a random amount.
## Each plugin will sleep for a random time within jitter before collecting.
## This can be used to avoid many plugins querying things like sysfs at the
## same time, which can have a measurable effect on the system.
collection_jitter = "0s"
## Default flushing interval for all outputs. Maximum flush_interval will be
## flush_interval + flush_jitter
flush_interval = "10s"
## Jitter the flush interval by a random amount. This is primarily to avoid
## large write spikes for users running a large number of telegraf instances.
## ie, a jitter of 5s and interval 10s means flushes will happen every 10-15s
flush_jitter = "0s"
## Precision will NOT be used for service inputs. It is up to each individual
## service input to set the timestamp at the appropriate precision.
precision = "0s"
## Log at debug level.
debug = true
## Log only error level messages.
# quiet = false
## Log target controls the destination for logs and can be one of "file",
## "stderr" or, on Windows, "eventlog". When set to "file", the output file
## is determined by the "logfile" setting.
logtarget = "file"
## Name of the file to be logged to when using the "file" logtarget. If set to
## the empty string then logs are written to stderr.
logfile = "/var/log/telegraf/telegraf.log"
## The logfile will be rotated when it becomes larger than the specified
## size. When set to 0 no size based rotation is performed.
logfile_rotation_max_size = "1MB"
## Maximum number of rotated archives to keep, any older logs are deleted.
## If set to -1, no archives are removed.
logfile_rotation_max_archives = 5
## Pick a timezone to use when logging or type 'local' for local time.
## Example: America/Chicago
log_with_timezone = "local"
## Override default hostname, if empty use os.Hostname()
hostname = ""
## If set to true, do no set the "host" tag in the telegraf agent.
omit_hostname = false
###############################################################################
# OUTPUT PLUGINS #
###############################################################################
[[outputs.influxdb]]
urls = ["http://127.0.0.1:8428"]
# # Configuration for sending metrics to InfluxDB
# [[outputs.influxdb]]
# ## The full HTTP or UDP URL for your InfluxDB instance.
# ##
# ## Multiple URLs can be specified for a single cluster, only ONE of the
# ## urls will be written to each interval.
# # urls = ["unix:///var/run/influxdb.sock"]
# # urls = ["udp://127.0.0.1:8089"]
# urls = ["http://127.0.0.1:8086"]
# ## The target database for metrics; will be created as needed.
# ## For UDP url endpoint database needs to be configured on server side.
database = "telegraf"
##
# ## If true, no CREATE DATABASE queries will be sent. Set to true when using
# ## Telegraf with a user without permissions to create databases or when the
# ## database already exists.
skip_database_creation = false
#
# ## Name of existing retention policy to write to. Empty string writes to
# ## the default retention policy. Only takes effect when using HTTP.
# # retention_policy = ""
#
# ## HTTP Basic Auth
username = "telegraf"
password = "password"
#
###############################################################################
# INPUT PLUGINS #
###############################################################################
[[inputs.cpu]]
percpu = false
#[[inputs.disk]]
#ignore_fs = [ "tmpfs", "devtmpfs" ]
#[[inputs.diskio]]
#[[inputs.kernel]]
[[inputs.mem]]
#[[inputs.processes]]
#[[inputs.swap]]
#[[inputs.system]]
[[inputs.net]]
fieldpass = [ "bytes*" ]
[[inputs.netstat]]
[[inputs.mqtt_consumer]]
alias = "mqtt"
startup_error_behavior = "retry"
servers = ["tcp://127.0.0.1:1883"]
topics = [
"N/0281f08bbe75/system/0/#",
]
client_id = "telegraf"
username = "username"
password = "password"
data_format = "json"
Telegraf is a memory hog and chokes with too many MQTT metrics, so it’s often easier to just capture a few metrics with Node Red and send directly to Victoria Metrics. Leaving telegraf uninstalled allows enough RAM to run a Grafana server (guide adapted from here). Tested working with 11.5.1. However, takes quite a while to fully start up (90ish seconds).
sudo apt-get install -y apt-transport-https software-properties-common wget
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install grafana
Even grafana is quite heavy, and I’ve found a program called Perses that can display basic charts and graphs using Prometheus queries and only needs ~50MB RAM.
wget https://github.com/perses/perses/releases/download/v0.51.0-beta.1/perses_0.51.0-beta.1_linux_arm64.tar.gz
mkdir /opt/perses
tar -xvzf perses_0.51.0-beta.1_linux_arm64.tar.gz -C /opt/perses
sudo chown -R root:root /opt/perses
Create a service file with sudo nano /etc/systemd/system/perses.service
[Unit]
Description=Perses service
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/perses
ExecStart=/opt/perses/perses --config=/opt/perses/config.yaml
SyslogIdentifier=perses
Restart=always
Environment=PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/opt/perses
[Install]
WantedBy=multi-user.target
Start and enable the service
sudo systemctl daemon-reload
sudo systemctl start perses
sudo systemctl enable perses
install pivpn
curl -L https://install.pivpn.io | bash
create reverse ssh tunnel as detailed here.
install chrony and edit conf file
sudo apt install chrony
sudo nano /etc/chrony/chrony.conf
#add to the bottom
allow 192.0.0.0/8
Limit journal size
sudo nano /etc/systemd/journald.conf
#add to bottom
SystemMaxUse=50M
RuntimeMaxUse=50M
sudo timedatectl set-timezone Africa/Dakar
Install cron so various things can be automated
sudo apt install cron
sudo crontab -e
Add the following at the bottom to set the modem to 4g preferred at boot (since the settings don’t seem to save)
@reboot sleep 30 && mmcli -m 0 --set-allowed-modes="4g|3g" --set-preferred-mode=4g
If necessary, install fail2ban and configure. If only exposing OpenVPN port, not necessary.
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
After all the defaults is the [sshd] section, enter the following
enabled = yes
#whatever ips you know you want to always allow through
ignoreip = 127.0.0.1/8 ::1 56.78.0.0/16 12.34.0.0/16
bantime = 24h
maxretry = 2
findtime = 24h
port = ssh
logpath = SYSTEMD-JOURNAL
backend = systemd
Quick guide to using an existing binary on a new stick:
High-level steps:
- Pull full image binary for recovery purposes
- See above
- Pull partition binaries and put them back in after flashing
- get into fastboot mode by holding down the button and plugging in
fastboot oem reboot-edl
for n in fsc fsg modem modemst1 modemst2 persist sec; do edl r ${n} ${n}.bin done
- flash the full binary of the good image
- get back into fastboot mode
for n in fsc fsg modem modemst1 modemst2 persist sec; do fastboot flash ${n} ${n}.bin done
fastboot reboot
- Change hostname
sudo hostnamectl set-hostname stick8
sudo nano /etc/hosts
- Change 127.0.1.1 line to new hostname
- Delete and re-create ssh keys for user and root
sudo rm ~/.ssh/id_rsa*
ssh-keygen
sudo su
rm ~/.ssh/id_rsa*
ssh-keygen
- Copy ssh keys to VPS
scp ~/.ssh/id_rsa.pub pi@192.168.200.149:~/Desktop/root_stick8_id_rsa.pub
exit
scp ~/.ssh/id_rsa.pub pi@192.168.200.149:~/Desktop/user_stick8_id_rsa.pub
- Delete, recreate and copy OVPN profile
sudo rm ~/ovpns/stick5.ovpn
pivpn add
scp ~/ovpns/stick8.ovpn pi@192.168.200.149:~/Desktop/
- Adjust port in ssh-reverse.service
sudo nano /etc/systemd/system/ssh-reverse.service
Misc commands:
scp /home/pi/Desktop/stick13_files/root/* user@192.168.100.1:~/sshcopy
scp /home/pi/Desktop/stick13_files/user/* user@192.168.100.1:~/.ssh
ssh user@192.168.100.1
sudo su
mv /home/user/sshcopy/* ~/.ssh
chown root:root /root/.ssh/*
for n in fsc fsg modem modemst1 modemst2 persist sec; do
edl r ${n} ${n}.bin
done
for n in fsc fsg modem modemst1 modemst2 persist sec; do
fastboot flash ${n} ${n}.bin
done
Hey,
Great post!
Sadly I didn’t pull the image for recovery, do you think you could maybe supply me your file? I use stick version 3.0. or is the content individual and yours wouldn’t work?
Sorry, just saw this. Unfortunately, if you don’t pull the image first, you’ve lost specific data for your stick. If you know the IMEI, you can try replacing it using this command: at+wrimei=111122223333555 and at+wrimei2=111122223333555. Not sure how to do that exactly, maybe this guide will help: https://techship.com/support/faq/how-to-send-at-commands-through-modem-manager/ . But yes, if you want one of my original firmwares, I can stick it on google drive for you.