NetAlertX 26.10.0
Overview
NetAlertX (formerly Pi.Alert) is an open-source network presence scanner. It scans the network it is attached to on a schedule, keeps an inventory of every device it has seen (MAC address, IP address, name, vendor), records when each device is online, and raises alerts when a new device appears or a known one goes missing. On AWS, it shows you every network interface in your instance's VPC subnet: instances, load balancer nodes, NAT gateways, VPC endpoints and anything else that holds an address there.
This guide covers the NetAlertX 26.10.0 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud network monitoring listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
What you get:
- No default password, two logins. The web UI is behind HTTP basic authentication in nginx and, after that, NetAlertX's own login page, both with one password generated on your instance's first boot. NetAlertX stores only the SHA-256 hash it checks. The password itself is only in
/root/netalertx-credentials.txt(root only). Upstream's published default password is removed and refused. - A per-instance API token. The NetAlertX API (GraphQL and REST) answers only to the token generated on your instance. The API itself listens on
127.0.0.1only, so nginx is the only way in. - HTTPS from the first boot. The certificate is generated on your instance for its own addresses, port 80 redirects to HTTPS, and requests for a host name the instance does not serve are dropped. Cross-site posts and WebSocket upgrades from other websites are refused.
- An unprivileged scanner. NetAlertX runs as its own
netalertxuser with exactly two Linux capabilities,CAP_NET_RAWandCAP_NET_ADMIN(what ARP scanning needs), nosudo, and a read-only view of the system apart from its own data directories. - Scans your subnet only. On first boot, the scan scope is set to the instance's own VPC subnet. Plugins that contact outside services (email, webhooks, MQTT, ntfy, Pushover, Telegram and similar notification publishers, the public IP lookup and the vendor database download) are off until you switch them on.
- Escaping fixes. The image includes the escaping fixes of NetAlertX 26.8 to 26.10, and one more. Device names and vendors come from your network, so SecureAnyCloud ships 26.10.0, which escapes them in notification e-mails and strips HTML from plugin data. SecureAnyCloud also makes the device list show every column as plain text, and every build checks both in a browser.
- Fail closed. nginx, PHP and NetAlertX start only after first boot has finished, and they refuse to start if a credential is missing or has not been replaced with a generated value.
- No metadata access. NetAlertX, nginx, PHP-FPM and the first-boot service are blocked from the instance metadata service, and the AMI requires IMDSv2.
- The source, as the license requires. /app is the upstream v26.10.0 source that runs on the instance, and /usr/share/doc/netalertx/sac-changes.diff shows every change SecureAnyCloud made to it.
- Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on. PHP 8.3 is Ubuntu's own build,
8.3.6-0ubuntu0.24.04.13or later, which fixes the PHP2Shell remote code execution flaws (CVE-2026-109618 and CVE-2026-109619, USN-8948-1). Every build checks each installed PHP package and stops on an older one. - Host hardening. SSH accepts key logins only, root cannot log in over SSH, and root has no password. The firmware update timer (
fwupd-refresh) is switched off, because EC2 instances have no firmware it can update. - On the image: NetAlertX 26.10.0 (Python scanner and API, PHP web UI, SQLite database) in
/app, its Python packages in/opt/netalertx-python, arp-scan, nmap, fping and the other scanner tools, nginx 1.24, PHP 8.3 and OpenSSL 3.0 (from Ubuntu 24.04), cloud-init and the AWS Systems Manager agent. - Defaults: default user
ubuntu, architecture x86_64, recommended instance type m5.large.
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair, and the VPC subnet you want to monitor. NetAlertX sees the subnet its network interface is in.
- A security group that allows TCP 22 (SSH) from your admin network and TCP 443 (the web UI and API) only from the people and systems that use it. Port 80 only redirects to HTTPS, so you can leave it closed. Never open 20212: the NetAlertX API listens on the loopback address only.
- Permission to scan the network. Only scan networks you own or are authorized to scan.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick NetAlertX 26.10.0 on Ubuntu 24.04 as the software version and select your Region, then choose Launch through EC2. Choose m5.large, your key pair, the subnet to monitor and a security group as described above.
Or launch with the AWS CLI, replacing 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=netalertx}]'First boot takes a few seconds after the instance is running. The first scan runs within five minutes.
Connect to your instance
Connect over SSH. The SSH user for NetAlertX 26.10.0 on Ubuntu 24.04 is ubuntu:
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services
First boot sets the password, the API token, the scan scope and the certificate. Then PHP-FPM, NetAlertX and nginx start:
systemctl is-active netalertx nginx php8.3-fpm netalertx-firstboot
sudo test -f /var/lib/sac/data/netalertx-firstboot.done && echo FIRSTBOOT_DONEAll four units are active and the first boot marker is present:
active active active active FIRSTBOOT_DONEOnly SSH and nginx listen on network ports. The NetAlertX API is on the loopback address:
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0.5' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g' | sort0.0.0.0:22 users:(("sshd"),("systemd")) 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx")) 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx")) 127.0.0.1:20212 users:(("python3")) [::]:22 users:(("sshd"),("systemd")) [::]:443 users:(("nginx"),("nginx"),("nginx")) [::]:80 users:(("nginx"),("nginx"),("nginx"))Get your URL, password and API token
sudo cat /root/netalertx-credentials.txtThe file is readable by root only:
# NetAlertX 26.10.0 on Ubuntu 24.04 (sac) - generated on this instance's first boot. # These values are unique to this instance; none was baked into the image. Keep this file secret. netalertx_url=https://<public-ip>/ netalertx_admin_user=admin netalertx_admin_password=<admin-password> netalertx_api_token=<api-token> netalertx_scan_scope=172.31.80.0/20 (ens5) # Web UI: https://<host>/ - the browser asks for the user and password above (HTTP basic auth), then NetAlertX's
# own login page asks for the same password.
# API: https://<host>/server/graphql (and the REST routes) with Authorization: Bearer <netalertx_api_token>
# The certificate is self signed (minted on this instance): accept the browser warning once or install your own.
# Serve a DNS name instead:
sudo netalertx-set-hostname <your-dns-name>
# Scanning: this instance scans its own subnet only (SCAN_SUBNETS). Only scan networks you own or may scan.
# Self-test:
sudo /usr/local/sbin/netalertx-selftest.sh
# User guide: https://secureanycloud.com/stacks/netalertx-26-10-0/The URL uses the instance's public IP address from the EC2 instance metadata. The certificate also names the public DNS name and the private IP address, so https://<public-dns-name>/ and https://<private-ip>/ work too.
If you stop and start the instance without an Elastic IP, the boot service picks up the new address and issues a new certificate for it. To use your own DNS name, see Step 9.
A request without the password gets nginx's 401, and the health check answers without one:
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/devices.php
curl -sk https://127.0.0.1/healthz401 okSign in
Open https://<public-ip>/ in a browser and accept the certificate warning, because the certificate was made on your instance. The browser asks for a user name and password: enter admin and the netalertx_admin_password. NetAlertX then shows its own login page. Enter the same password.
Login sessions are kept in memory (/run/php-sessions), never on disk, so everyone signs in again after the instance restarts.
After you log in, you land on Devices. The tiles at the top count all devices, those connected now, favorites, new devices, devices that went down and archived ones. The chart shows how many were online over time, and the table lists every device with its name, last IP address, MAC address, status and the plugin that found it.
What NetAlertX scans
On AWS, NetAlertX finds devices with arp-scan. Every five minutes, it sends an ARP request to each address of the instance's subnet. The VPC answers for every network interface that holds one of those addresses, with that interface's own MAC address, whatever its security group allows.
Names come from reverse DNS (in a VPC, ip-a-b-c-d.<region>.compute.internal or ec2.internal). The scope is set on first boot:
sudo grep -E '^(SCAN_SUBNETS|ARPSCAN_RUN|ARPSCAN_ARGS)=' /app/config/app.confSCAN_SUBNETS=['172.31.80.0/20 --interface=ens5'] ARPSCAN_RUN='schedule' ARPSCAN_ARGS='arp-scan --ignoredups --retry=6'Count the devices that the scans have found so far:
sudo sqlite3 -readonly /app/db/app.db "SELECT COUNT(*) AS devices, COUNT(DISTINCT devMac) AS macs FROM Devices;"24|24Select a device to open its details: its addresses, how it was found, its sessions and its presence history. You can name it, give it an owner, type, group or location, mark it as a favorite and choose which alerts it raises.
Monitoring > Presence shows when each device was online over the week:
A VPC subnet only contains the network interfaces that you and AWS place there, so new devices are worth a look. A new device may be a new instance, an endpoint, a load balancer node that came up, or something you did not expect.
Use the API
The NetAlertX API serves GraphQL and REST under https://<host>/server/. It needs the API token from the credentials file in an Authorization: Bearer header. On the instance, the token is read from the file and handed to curl through a pipe, so it never appears on a command line:
TOKEN_HEADER="$(sudo sed -n 's/^netalertx_api_token=\(.*\)$/header = "Authorization: Bearer \1"/p' /root/netalertx-credentials.txt)" printf '%s\n' "${TOKEN_HEADER}" | curl -sk -K - -X POST -H 'Content-Type: application/json' \
--data '{"query":"{ devices { count } }"}' https://127.0.0.1/server/graphql echo unset TOKEN_HEADER{"data":{"devices":{"count":24}}}Without the token, the API refuses the request:
curl -sk -o /dev/null -w '%{http_code}\n' -X POST -H 'Content-Type: application/json' \
--data '{"query":"{ devices { count } }"}' https://127.0.0.1/server/graphql403The REST routes (for example, GET /server/devices and GET /server/events/recent) and the API reference are described in the NetAlertX API documentation. The API's own /docs and /openapi.json pages are not served on this image.
Notifications
NetAlertX writes every alert to its in-app notifications (the bell at the top of the page and Monitoring > Sent reports). To also send alerts by e-mail or to a chat service, open Settings > Publishers and enter the details of your service (for example, the SMTP server, user and password). Set the publisher's When to run to on_notification, then select Save.
These publishers are off on this image because they send data to an outside service. The instance needs outbound access to that service (security group, network ACL, NAT).
The same applies to the Internet IP plugin (it asks an outside service for your public address) and Vendor update (it downloads the IEEE vendor database). Switch them on in Settings only if you want them. NetAlertX also checks GitHub once an hour for a newer release, to show an update notice.
Your own DNS name and certificate
To serve NetAlertX under your own name (for example, https://netalertx.example.com/), point the DNS name at the instance. Then run the following command, with your name in place of <your-domain>:
sudo netalertx-set-hostname <your-domain>This writes the name to /etc/sac/netalertx-hostname, issues a new self-signed certificate for it (keeping the instance's addresses as alternative names), updates the link used in notifications and reloads nginx.
To use a certificate from a public authority instead, replace /etc/nginx/tls/netalertx.crt and /etc/nginx/tls/netalertx.key with yours (the key 0600 root) and run sudo systemctl reload nginx.
Scan scope
The image scans the subnet the instance is in. To scan another subnet that the instance can reach at layer 2 (an extra network interface in it), or to narrow the range, set SCAN_SUBNETS in Settings > Arp-Scan (Network scan). You can also set it in /app/config/app.conf while NetAlertX is stopped, for example:
sudo systemctl stop netalertx printf '%s' "['10.0.1.0/24 --interface=ens6']" | sudo /usr/local/sbin/netalertx-setconf /app/config/app.conf SCAN_SUBNETS --raw sudo systemctl start netalertxARP does not cross a router, so subnets reached through a route (another subnet, a peered VPC, a VPN) need a network interface in that subnet. Only scan networks you own or are authorized to scan.
Security checks
The image ships a self-test that checks the listening ports, both logins, the API token, cross-site requests and the metadata block. Run it. It prints one line:
sudo /usr/local/sbin/netalertx-selftest.sh | cut -c1-120selftest OK: listening tcp lo:20212 lo:53 pub:22 pub:443 pub:80 | netalertx 127.0.0.1:20212 only, user netalertx, capsNetAlertX runs as its own user with only the two network capabilities:
PID="$(systemctl show -p MainPID --value netalertx)" ps -o user=,comm= -p "${PID}" grep -E '^Cap(Eff|Amb)' "/proc/${PID}/status" systemctl show -p AmbientCapabilities --value netalertxnetaler+ python3 CapEff: 0000000000003000 CapAmb: 0000000000003000 cap_net_admin cap_net_rawEvery service is blocked from the instance metadata service. From your SSH shell, it still works:
for s in netalertx nginx php8.3-fpm netalertx-firstboot; do echo "$s: $(systemctl show -p IPAddressDeny --value $s.service)"; donenetalertx: 169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128 nginx: 169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128 php8.3-fpm: 169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128 netalertx-firstboot: 169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128Versions, source and license
cat /app/.VERSION grep -E '^ +(Tag|Commit):' /usr/share/doc/netalertx/SOURCE-OFFER.txt ls /usr/share/doc/netalertx/v26.10.0 Tag: v26.10.0 Commit: 19aa886432b5dc3ecf1077fe34b77bbd2f75c68e SAC-CHANGES.txt LICENSE.txt SOURCE-OFFER.txt sac-changes.diff pip-audit.json python-requirements.lock.txtThe PHP that serves the web UI is Ubuntu's PHP 8.3 package with the PHP2Shell fixes:
php -v | head -1 | cut -d' ' -f1-2 dpkg-query -W -f '${Package} ${Version}\n' php8.3-fpm php8.3-cli php8.3-commonPHP 8.3.6 php8.3-cli 8.3.6-0ubuntu0.24.04.13 php8.3-common 8.3.6-0ubuntu0.24.04.13 php8.3-fpm 8.3.6-0ubuntu0.24.04.13/usr/share/doc/netalertx/sac-changes.diff holds every change SecureAnyCloud made to the upstream source, as a patch against that commit. The changes are:
- The API binds to 127.0.0.1.
- The set-password plugin no longer defaults to a published password.
- /app/api is a directory instead of a link to /tmp.
- The device list shows every column as plain text (upstream escapes only the name and FQDN columns).
pip-audit.json is the dependency audit taken when the image was built, and python-requirements.lock.txt lists the exact Python packages.
Changing the password
The password is used twice: by nginx (a SHA-512 crypt hash in /etc/nginx/netalertx.htpasswd) and by NetAlertX's login (a SHA-256 hash in app.conf). To change both, run the following command and type the new password when prompted:
read -rsp 'New NetAlertX password: ' NEWPW; echo printf '%s\n' "$NEWPW" | openssl passwd -6 -stdin | sed 's/^/admin:/' | sudo tee /etc/nginx/netalertx.htpasswd >/dev/null
sudo systemctl stop netalertx printf '%s' "$NEWPW" | sha256sum | awk '{printf "%s", $1}' | sudo /usr/local/sbin/netalertx-setconf /app/config/app.conf SETPWD_password unset NEWPW
sudo systemctl start netalertx && sudo systemctl reload nginxThen update or remove the netalertx_admin_password line in /root/netalertx-credentials.txt. To issue a new API token, select Settings > Core > API token > Generate, save, and update netalertx_api_token.
Data and backups
Everything NetAlertX knows is in the SQLite database /app/db/app.db, and its settings are in /app/config/app.conf. To back them up, make a consistent copy with SQLite while NetAlertX runs, then copy it off the instance:
sudo sqlite3 /app/db/app.db ".backup '<backup-dir>/netalertx-app.db'"
sudo cp /app/config/app.conf <backup-dir>/Maintenance > Backup/Restore in the web UI exports and imports the device list as CSV. NetAlertX deletes events older than 90 days by default (Settings > Core).
Security recommendations
- Allow TCP 443 only from your own networks, or reach the UI through an SSH tunnel or AWS Systems Manager port forwarding and keep 443 closed.
- Keep the credentials file safe, and change the password if it may have been seen.
- The scanner sees every interface in its subnet. Put the instance in the subnet you mean to monitor, and treat its inventory as sensitive information about your network.
- Turn on only the notification publishers and outside services you need.
Support and licensing
NetAlertX is free software under the GNU General Public License version 3. The license, the source offer and SecureAnyCloud's change notice are in /usr/share/doc/netalertx/, and /app is the complete source. NetAlertX is a trademark of its owners. SecureAnyCloud is not affiliated with or endorsed by the NetAlertX project.
For help with the SecureAnyCloud image, contact sales@secureanycloud.com. See also the network monitoring listing guide.
Deploy on AWS
Launch NetAlertX 26.10.0 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