UpSnap 5.7.3
Overview
UpSnap is a web dashboard for powering machines on and off. You add your devices by name, IP address and MAC address, and UpSnap shows on one page whether each one is up, using ping and the TCP ports you choose. The page updates live.
This guide covers launching and using the UpSnap 5.7.3 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud network monitoring listing on AWS Marketplace, and you pick it as the software version when you subscribe and launch.
From the dashboard, or on a cron schedule, UpSnap can wake a device with a Wake-on-LAN magic packet or your own wake command. It can shut a device down with your own shell command, for example over SSH, or put it to sleep with Sleep-On-LAN. A network scan with nmap finds the devices on a subnet so you can add them in one go. Users, per-device permissions and device groups are built in, and the data lives in PocketBase, an embedded SQLite database with its own admin UI.
Wake-on-LAN and AWS. A Wake-on-LAN magic packet is a Layer 2 broadcast, and an AWS VPC does not forward broadcasts. A magic packet sent from this instance reaches no other host in the VPC, and EC2 instances are not started that way anyway. On AWS, UpSnap's ping and port status, network scans and scheduled commands work as they do anywhere.
To wake machines on your own office or home network, connect the instance to that network. Use either a site-to-site VPN plus a small always-on relay on the LAN, or a Layer 2 bridge. Step 7 explains both.
What you get:
- Your own administrator, no default account. Each instance creates its own UpSnap administrator with a random password on its first boot. The image contains no database, no account and no password. Self-registration is closed, and only the administrator adds users.
- HTTPS from the first boot. nginx serves UpSnap and the PocketBase admin UI (
/_/) on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS. Requests for a host name the instance does not serve get no answer. - UpSnap listens on localhost only. Its service unit fixes it to
127.0.0.1:8090, so nginx is its only client. - Other web sites cannot act with your login. nginx refuses a wake, sleep, reboot, shutdown or network scan request that another web site's page sends in your browser. It also refuses any change through the API whose browser
Originis not this instance, and it rate limits sign-in attempts per address. PocketBase logs each request with the real client address. - The scanner is not root. UpSnap and the nmap scans and commands it starts run as the unprivileged
upsnapuser in a systemd sandbox. The user has exactly one Linux capability,CAP_NET_RAW(raw sockets for ping and the ARP scan), and cannot gain more. nmap itself carries no setuid bit and no file capabilities. - No access to the instance metadata service. nginx, UpSnap, and every scan and command UpSnap starts are blocked at the kernel level from the EC2 instance metadata service (IPv4 and IPv6). The nmap that UpSnap runs also always skips the metadata address, so a scan never probes it.
- The official release, checked. UpSnap 5.7.3 is installed from its official release archive with a pinned checksum, built with Go 1.27.3 and PocketBase 0.41.1. It has no known reachable vulnerabilities at build time, and there is no compiler on the image.
- Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
On the image: UpSnap 5.7.3 (/usr/local/bin/upsnap, data in /var/lib/upsnap/pb_data), nmap 7.94, nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
Default user: ubuntu | Architecture: x86_64 | Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair, and a VPC subnet that can reach the machines you want to manage.
- A security group that allows TCP 22 (SSH), TCP 443 (UpSnap) and TCP 80 (redirects to HTTPS) from the networks your administrators work from. UpSnap needs no other inbound port.
- For ping status of other EC2 instances, their security groups must allow inbound ICMP echo from this instance. Otherwise, watch a TCP port instead (Step 5).
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick UpSnap 5.7.3 on Ubuntu 24.04 as the software version, choose your Region, then choose Launch through EC2.
Choose m5.large, your key pair, the subnet and a security group as described above. UpSnap itself needs very little, so a smaller instance also works.
To launch with the AWS CLI instead, replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=upsnap}]'Connect to your instance
Connect over SSH to UpSnap 5.7.3 on Ubuntu 24.04 as the user ubuntu:
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services
On first boot, the instance sets the host name, generates the certificate, creates its own UpSnap database and administrator, and then starts UpSnap and nginx. Check that the services are up:
systemctl is-active upsnap-firstboot upsnap nginx
sudo test -f /var/lib/sac/data/upsnap-firstboot.done && echo FIRSTBOOT_DONEAll three units should be active and the first-boot marker present:
active active active FIRSTBOOT_DONEOnly SSH and nginx listen on the network, while UpSnap listens on localhost only:
sudo ss -lntpH | awk '{print $4, $6}' | sed -E 's/users:\(\("([^"]+)".*/\1/' | grep -v '127.0.0.5' | sort -u0.0.0.0:22 sshd 0.0.0.0:443 nginx 0.0.0.0:80 nginx 127.0.0.1:8090 upsnap [::]:22 sshd [::]:443 nginx [::]:80 nginxGet your URL and password
Read the credentials file as root:
sudo cat /var/lib/sac/data/upsnap-credentials.txtOnly root can read this file. It holds the URL and the administrator's email address and password for this instance:
# UpSnap 5.7.3 - generated on first boot by upsnap-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret. UPSNAP_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ UPSNAP_ADMIN_EMAIL=admin@upsnap.local UPSNAP_ADMIN_PASSWORD=<UPSNAP_ADMIN_PASSWORD> UPSNAP_ADMIN_UI=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/_/
#
# Open UPSNAP_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to https) # and sign in with UPSNAP_ADMIN_EMAIL / UPSNAP_ADMIN_PASSWORD. The same account opens the PocketBase admin UI # (UPSNAP_ADMIN_UI). Change the password from the account page after the first sign-in. # Nothing is preloaded: no device, scan range, command or schedule. Wake-on-LAN broadcasts do not cross an AWS VPC: # see the user guide for what works here (status, scheduled commands, a VPN or bridge to your own LAN). # Self-test:
sudo upsnap-selftest Change the served name:
sudo upsnap-set-hostname <your-domain>
# User guide: https://secureanycloud.com/stacks/upsnap-5-7-3/The URL uses the instance's public DNS name from EC2 instance metadata. Opening https://<public-ip>/ redirects you to that name.
The image also includes a self-test. Through nginx, it signs in as the administrator and checks the pages, the closed registration, the request guards, UpSnap's privileges and the metadata block. Run it with:
sudo upsnap-selftestSELFTEST-OK https 301 + healthz + UI + admin UI /_/ + anonymous: 0 devices, scan/wake/settings/superusers/logs refused, registration refused + administrator sign-in 200 / wrong password 400 + exactly 1 superuser (installer gone) + users.createRule null + trusted proxy X-Real-IP, rate limits on, appURL https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com + upsnap uid upsnap, CapEff/Bnd/Amb = CAP_NET_RAW only, NoNewPrivs, listening 127.0.0.1:8090 only + 403 cross-site scan + 403 cross-origin POST + 444 unknown host + metadata 000 inside upsnap and nginx (control 200) + nmap wrapper excludes metadataSign in and add your devices
Open the UPSNAP_URL in your browser. The certificate is self-signed, so your browser asks you to confirm it the first time. You can install your own certificate instead (Step 10). Sign in with UPSNAP_ADMIN_EMAIL and UPSNAP_ADMIN_PASSWORD.
Then change the password. Open the account menu (top right), choose Edit account and set a new one. The credentials file keeps the first-boot password, so if you want upsnap-selftest to keep signing in, put the new password in that file as root.
The dashboard starts empty. Choose New to add a device. Enter a name, its IP address or DNS name, its MAC address and its netmask, and under Ports add the TCP ports UpSnap should check.
The dashboard then shows a card for each device. The power button is green while the device answers ping and grey while it does not, and each port has a green (open) or red (closed) dot. In a fresh instance, UpSnap can watch itself and the subnet's router, which answers ping but has no DNS service on that address.
Click the pencil on a card to edit the device. The device page has the general settings, the ports to check, a link for the device name (for example the device's own web page) and a custom ping command. It also has the wake and shutdown settings (Step 7), Sleep-On-LAN, the magic-packet password and groups.
UpSnap pings with raw ICMP packets, which is why it has CAP_NET_RAW. An EC2 instance answers only if its security group allows inbound ICMP echo from this instance. For devices that do not answer ping, a port check (for example SSH on 22) shows the same thing.
Find devices with a network scan
Choose New, then Network Scan. Enter the range to scan, for example your subnet 172.31.80.0/24, then choose Save and Scan.
UpSnap runs an nmap ping scan of the range and lists every device that answers, with its name, IP address, MAC address and vendor. Choose Add to add one device, or Add all devices to add them all.
The scan range is stored in UpSnap's settings, and only administrators can change it. In a VPC, the scan sees the network interfaces of the instance's own subnet, with their MAC addresses. Through the router, it also sees hosts in other subnets that answer ping or TCP. Scan only networks you own or are authorised to scan.
Whatever range you enter, the nmap that UpSnap runs skips the instance metadata address:
cat /usr/local/lib/upsnap/bin/nmap#!/bin/sh
# sac: UpSnap runs nmap (device scan, IP tracking) by looking it up on PATH; this wrapper is first on the PATH of
# upsnap.service. It never lets a scan probe the instance metadata service (AWS 169.254.169.254, Azure wire server
# 168.63.129.16): nmap skips excluded targets entirely. The unit's IPAddressDeny additionally drops any IP packet to them. exec /usr/bin/nmap --exclude 169.254.169.254,168.63.129.16 "$@"Waking and shutting down machines
Open a device and find its Wake and Shutdown sections. Both can run on a cron schedule (Enable wake cron, Enable shutdown cron), and Require Confirmation asks before a button press acts.
What works in a VPC. Without a custom wake command, UpSnap wakes a device by sending a Wake-on-LAN magic packet to the broadcast address of the device's network. An AWS VPC does not deliver broadcasts, so that packet reaches no machine from an EC2 instance. Everything else works: status by ping and ports, scans, and shutdown or wake commands.
A command is a shell command (/bin/sh -c) that UpSnap runs on this instance as the upsnap user, in its sandbox and without metadata access. {{ DEVICE_IP }} and {{ DEVICE_MAC }} are replaced with the device's addresses. The image includes ssh and curl for this. It does not include sshpass or Samba's net, which UpSnap's examples mention.
Waking machines on your own network. First connect the VPC to that network, with an AWS Site-to-Site VPN or a VPN you run yourself. Then use one of these options:
- A relay on the LAN (the usual choice). Keep a small always-on machine on the LAN, for example a Raspberry Pi, with a Wake-on-LAN tool such as
wakeonlanoretherwake. Give UpSnap a custom wake command that asks the relay to send the magic packet on the LAN, for examplessh -i /var/lib/upsnap/.ssh/id_ed25519 wol@<relay-ip> wakeonlan {{ DEVICE_MAC }}. Status still comes from ping or a port across the VPN as usual. - A Layer 2 bridge. If the instance has a network interface on the LAN itself, UpSnap's own magic packet reaches that LAN. An example is a VPN in bridged, Layer 2 mode, such as OpenVPN with a
tapdevice bridged into the LAN. Set the device's netmask to the LAN's.
SSH commands, whether for a relay or for a shutdown such as ssh -i /var/lib/upsnap/.ssh/id_ed25519 admin@{{ DEVICE_IP }} sudo poweroff, need a key. Create a key for the upsnap user and add its public key to the target account:
sudo install -d -m 700 -o upsnap -g upsnap /var/lib/upsnap/.ssh
sudo -u upsnap ssh-keygen -t ed25519 -N '' -f /var/lib/upsnap/.ssh/id_ed25519
sudo cat /var/lib/upsnap/.ssh/id_ed25519.pubAccept each target's host key once with sudo -u upsnap ssh -i /var/lib/upsnap/.ssh/id_ed25519 <user>@<host> true, so commands do not stop at the prompt.
Settings, users and the PocketBase admin
Open Settings to control how UpSnap behaves:
- How often UpSnap pings the devices, as a cron expression. The default is every 3 seconds.
- The IP address tracking interval. UpSnap rescans the subnets of devices with Track IP address switched on and follows a device whose IP address changes.
- Lazy ping, which pings only while someone has the dashboard open.
- The site title and the icon.
Open Users to add people. For each user, set which devices they can see, power on and off, edit and delete, and whether they can create devices.
A user who may edit a device can also set its wake, shutdown and ping commands, which run on this instance. Give edit rights only to people you trust as much as an administrator.
The administrator from Step 4 is a PocketBase superuser. The same email address and password also open the PocketBase admin UI at UPSNAP_ADMIN_UI (/_/), which shows the raw collections, the request logs and PocketBase's own backups. The admin UI is served only through nginx's HTTPS front.
The API. UpSnap's actions are on /api/upsnap/ (wake, sleep, reboot, shutdown, scan and the group variants). Its data is on PocketBase's API (/api/collections/...). Sign in to get a token.
The power and scan actions also need the header Sec-Fetch-Site: same-origin. A browser sends it on UpSnap's own pages, and the cross-site guard requires it. The example below prints the number of devices, then shows the guard refusing a scan request without that header:
H=$(sudo sed -n 's#^UPSNAP_URL=https://\([^/]*\)/$#\1#p' /var/lib/sac/data/upsnap-credentials.txt)
TOKEN=$(sudo python3 -c 'import json; d={k.rsplit("_",1)[1]: v for k, v in (l.rstrip("\n").split("=", 1) for l in open("/var/lib/sac/data/upsnap-credentials.txt") if l.startswith("UPSNAP_ADMIN_"))}; print(json.dumps({"identity": d["EMAIL"], "password": d["PASSWORD"]}))' \
| curl -sk --resolve "$H:443:127.0.0.1" -H 'Content-Type: application/json' --data-binary @- "https://$H/api/collections/_superusers/auth-with-password" \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["token"])')
curl -sk --resolve "$H:443:127.0.0.1" -H @- "https://$H/api/collections/devices/records" <<<"Authorization: $TOKEN" | python3 -c 'import json,sys; print(json.load(sys.stdin)["totalItems"], "devices")'
curl -sk -o /dev/null -w 'scan without Sec-Fetch-Site: %{http_code}\n' --resolve "$H:443:127.0.0.1" -H @- "https://$H/api/upsnap/scan" <<<"Authorization: $TOKEN"0 devices scan without Sec-Fetch-Site: 403The password goes to curl on standard input, and the token goes as a header from standard input, so neither appears in the process list.
Data and backups
UpSnap keeps all of its data in /var/lib/upsnap/pb_data, which holds PocketBase's data.db and auxiliary.db SQLite files. To back it up, stop UpSnap briefly:
sudo systemctl stop upsnap
sudo tar -C /var/lib/upsnap -czf /root/upsnap-backup.tgz pb_data
sudo systemctl start upsnapTo restore on a new instance, stop UpSnap and replace /var/lib/upsnap/pb_data with the archive's copy, owned by upsnap with mode 700. Start UpSnap again, then sign in with the administrator of the instance you backed up.
The PocketBase admin UI (/_/, Settings, Backups) can also make and download backups while UpSnap runs.
Use your own domain and certificate
- In your DNS, point
<your-domain>(an A record) at the instance's public IP address. An Elastic IP keeps that address stable. - Tell the instance to use the new name. This sets the name nginx accepts, the request guards and UpSnap's application URL, and it generates a new self-signed certificate for the name:
sudo upsnap-set-hostname <your-domain>- For a certificate your browser trusts, put the certificate chain for
<your-domain>in/etc/ssl/upsnap/upsnap.crtand its private key in/etc/ssl/upsnap/upsnap.key(root only, mode 600). Then runsudo systemctl reload nginx. Alternatively, put the instance behind an Application Load Balancer with an AWS Certificate Manager certificate that forwards to port 443 on the instance.
Run the security checks
Confirm that nginx and UpSnap are blocked from the instance metadata service:
for u in nginx upsnap; do printf '%s ' "$u"; systemctl show -p IPAddressDeny --value "$u" | tr ' ' '\n' | sort | tr '\n' ' '; echo; donenginx 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 upsnap 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128The block applies to UpSnap's whole service, so the nmap scans and commands it starts are blocked too. Next, confirm that UpSnap runs as upsnap with only CAP_NET_RAW (bit 13, 0x2000) and cannot gain other privileges:
P=$(systemctl show -p MainPID --value upsnap) ps -o user= -p "$P" grep -E '^(CapEff|CapBnd|CapAmb|NoNewPrivs)' /proc/"$P"/statusupsnap CapEff: 0000000000002000 CapBnd: 0000000000002000 CapAmb: 0000000000002000 NoNewPrivs: 1Finally, check the request guards. Anonymous callers get no devices. nginx refuses a power action or scan that another web site's page sends, and it refuses an API change from a foreign Origin. A request for a host name the instance does not serve gets no answer at all.
H=$(sudo sed -n 's#^UPSNAP_URL=https://\([^/]*\)/$#\1#p' /var/lib/sac/data/upsnap-credentials.txt)
curl -sk -o /dev/null -w 'anonymous device list: %{http_code} ' --resolve "$H:443:127.0.0.1" "https://$H/api/collections/devices/records";
curl -sk --resolve "$H:443:127.0.0.1" "https://$H/api/collections/devices/records" | python3 -c 'import json,sys; print(json.load(sys.stdin)["totalItems"], "devices")'
curl -sk -o /dev/null -w 'cross-site wake: %{http_code}\n' --resolve "$H:443:127.0.0.1" -H 'Sec-Fetch-Site: cross-site' "https://$H/api/upsnap/wake/x"
curl -sk -o /dev/null -w 'cross-origin POST: %{http_code}\n' --resolve "$H:443:127.0.0.1" -X POST -H 'Origin: https://evil.example' -H 'Content-Type: application/json' --data '{}' "https://$H/api/collections/devices/records"
curl -sk -o /dev/null -w 'unknown host name: %{http_code}\n' --resolve evil.example:443:127.0.0.1 https://evil.example/ || trueanonymous device list: 200 0 devices cross-site wake: 403 cross-origin POST: 403 unknown host name: 000The credentials, the TLS key and UpSnap's data are readable by root only. The upsnap service user can also read the data:
sudo stat -c '%a %U:%G %n' /var/lib/sac/data/upsnap-credentials.txt /etc/ssl/upsnap/upsnap.key /var/lib/upsnap /var/lib/upsnap/pb_data600 root:root /var/lib/sac/data/upsnap-credentials.txt 600 root:root /etc/ssl/upsnap/upsnap.key 700 upsnap:upsnap /var/lib/upsnap 700 upsnap:upsnap /var/lib/upsnap/pb_dataOther notes:
- Sign-in limits. nginx allows about 10 sign-in attempts a minute per address and answers more with 429. PocketBase's own rate limiter is on as well.
- Who can reach it. Anyone who can sign in can see the devices they are allowed to see and power them on and off. Open ports 80 and 443 in the security group only to the networks your administrators and users work from.
- The build.
/usr/share/doc/sac-upsnap/BUILD-INFO.txtrecords the release, its checksums and the Go toolchain.go-version-m.txtnext to it lists every library in the program. - Logs. nginx logs are in
/var/log/nginx, and UpSnap logs to the journal (journalctl -u upsnap). PocketBase's request log is in the admin UI under Logs.
Keep it up to date
Ubuntu security updates install automatically. To apply all updates now:
sudo apt-get update && sudo apt-get upgrade -yNew UpSnap releases arrive as new versions of this listing, built and checked the same way. Read the UpSnap release notes before you move. Then back up /var/lib/upsnap/pb_data (Step 9), launch the new version and restore the backup on it.
Support and licensing
UpSnap is open source under the MIT licence (seriousm4x and contributors). The licence text is in /usr/share/doc/sac-upsnap/, and the source code is at github.com/seriousm4x/UpSnap. PocketBase and the Go libraries UpSnap is built with are open source under permissive licences (MIT, BSD and Apache 2.0). nmap is the Ubuntu package, under the Nmap licence (a GPL 2 variant).
There is no per-user licence fee. The AMI price covers SecureAnyCloud's build, hardening, first-boot setup and support.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24-hour response SLA
The other versions on this listing are on the network monitoring guide.
Deploy on AWS
Launch UpSnap 5.7.3 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com