Networking AWS

NetAlertX 26.10.0 on AWS User Guide

| Product: NetAlertX 26.10.0 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the NetAlertX 26.10.0 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg network monitoring listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

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.

What the cloudimg image adds:

  • 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.1 only; 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 web sites are refused.
  • An unprivileged scanner. NetAlertX runs as its own netalertx user with exactly two Linux capabilities, CAP_NET_RAW and CAP_NET_ADMIN (what ARP scanning needs), no sudo, 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.
  • The escaping fixes of NetAlertX 26.8 to 26.10. Device names and vendors come from your network, so cloudimg ships 26.10.0, which escapes them in notification e-mails and strips HTML from plugin data, and checks this on every build.
  • Fail closed. nginx, PHP and NetAlertX start only after first boot has finished, and they refuse to start if a credential is missing or still a placeholder.
  • 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 licence requires. /app is a git checkout of the upstream v26.10.0 tag, so git -C /app diff shows every change cloudimg made.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is 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.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

The NetAlertX device list showing the network interfaces found in the instance's VPC subnet, each with its name, IP address, MAC address and status

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 authorised to scan.

Step 1: 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 your Region, then Launch through EC2. Choose m5.large, your key pair, the subnet to monitor and a security group as above.

With the AWS CLI (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=netalertx}]'

First boot takes a few seconds after the instance is running. The first scan runs within five minutes.

Step 2: Connect to your instance

Version SSH user
NetAlertX 26.10.0 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: 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/cloudimg/netalertx-firstboot.done && echo FIRSTBOOT_DONE

All four units are active and the first boot marker is present:

active
active
active
active
FIRSTBOOT_DONE

Only 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' | sort
0.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"))

Step 4: Get your URL, password and API token

sudo cat /root/netalertx-credentials.txt

The file is readable by root only:

# NetAlertX 26.10.0 on Ubuntu 24.04 (cloudimg) - 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://www.cloudimg.co.uk/guides/netalertx-26-10-0-on-ubuntu-24-04-aws/

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/healthz
401
ok

Step 5: Sign in

Open https://<public-ip>/ in a browser and accept the certificate warning (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.

The NetAlertX login page, shown after the browser's basic authentication prompt

After you log in you land on Devices. The tiles at the top count all devices, those connected now, favourites, 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.

Step 6: 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, and 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.conf
SCAN_SUBNETS=['172.31.80.0/20 --interface=ens5']
ARPSCAN_RUN='schedule'
ARPSCAN_ARGS='arp-scan --ignoredups --retry=6'

How many devices 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|24

Click 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 favourite and choose which alerts it raises.

A device's details page with its MAC and IP address, the plugins that found and named it, and its notification settings

Monitoring > Presence shows when each device was online over the week:

The presence view with a calendar row per device

A VPC subnet only contains the network interfaces you and AWS place there, so new devices are worth a look: a new instance, an endpoint, a load balancer node that came up, or something you did not expect.

Step 7: 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/graphql
403

The REST routes (for example GET /server/devices, 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.

Step 8: 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 them by e-mail or to a chat service, open Settings > Publishers, enter the details of your service (for example the SMTP server, user and password) and set the publisher's When to run to on_notification, then Save. These publishers are off on this image because they send data to an outside service; the instance needs outbound access to it (security group, network ACL, NAT).

The NetAlertX settings page with the device scanners and the core settings

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.

Step 9: 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, with your name in place of <your-domain>:

sudo netalertx-set-hostname <your-domain>

This writes the name to /etc/cloudimg/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.

Step 10: Scan scope

The image scans the subnet the instance is in. To scan another subnet 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), or 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 netalertx

ARP 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 authorised to scan.

Step 11: 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. It prints one line:

sudo /usr/local/sbin/netalertx-selftest.sh | cut -c1-120
selftest OK: listening tcp lo:20212 lo:53 pub:22 pub:443 pub:80 | netalertx 127.0.0.1:20212 only, user netalertx, caps

NetAlertX 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 netalertx
netaler+ python3
CapEff: 0000000000003000
CapAmb: 0000000000003000
cap_net_admin cap_net_raw

Every 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)"; done
netalertx: 169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
nginx: 169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
php8.3-fpm: 169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32
netalertx-firstboot: 169.254.169.254/32 fd00:ec2::254/128 168.63.129.16/32

Step 12: Versions, source and licence

sudo git -C /app log -1 --format='%H %D'
cat /app/.VERSION
ls /usr/share/doc/netalertx/
19aa886432b5dc3ecf1077fe34b77bbd2f75c68e grafted, HEAD, tag: v26.10.0
v26.10.0
CLOUDIMG-CHANGES.txt
LICENSE.txt
SOURCE-OFFER.txt
pip-audit.json
python-requirements.lock.txt

sudo git -C /app diff shows the changes cloudimg made to the upstream source: the API binds to 127.0.0.1, the set-password plugin no longer defaults to a published password, and /app/api is a directory instead of a link to /tmp. pip-audit.json is the dependency audit taken when the image was built, and python-requirements.lock.txt lists the exact Python packages.

Step 13: 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, 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 nginx

Then update or remove the netalertx_admin_password line in /root/netalertx-credentials.txt. To issue a new API token, use Settings > Core > API token > Generate, save, and update netalertx_api_token.

Step 14: Data and backups

Everything NetAlertX knows is in the SQLite database /app/db/app.db and the settings in /app/config/app.conf. To back them up, make a consistent copy with SQLite while NetAlertX runs and 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).

Step 15: 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 licence, the source offer and cloudimg's change notice are in /usr/share/doc/netalertx/, and /app is the complete source. NetAlertX is a trademark of its owners; cloudimg is not affiliated with or endorsed by the NetAlertX project. For help with the cloudimg image, contact support@cloudimg.co.uk. See also the network monitoring listing guide.