WatchYourLAN 2.1.4 on AWS User Guide
Overview
This guide covers launching and using the WatchYourLAN 2.1.4 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.
WatchYourLAN is a lightweight network IP scanner with a web interface. Every two minutes it runs arp-scan on the network the instance is attached to and records every address that answers: its name, IP address, MAC address, hardware vendor and when it was last seen. You mark the hosts you know, and WatchYourLAN flags any host that is not marked known, so a new instance, endpoint or device in the subnet stands out. It keeps an online/offline history for every host, can probe a host's TCP ports, can send a notification when an unknown host appears (through Shoutrrr: email, Slack, Discord, Telegram, Gotify and many more) and can export to Prometheus or InfluxDB.
Upstream WatchYourLAN has no login of its own: anyone who can reach its port can read your network map, start scans, probe ports and change its settings. The cloudimg image makes it safe to run on EC2:
- A password on every page. nginx puts the whole application behind an HTTP Basic Auth prompt whose password is generated on your instance's first boot. The image ships with an empty password file, so if anything went wrong at first boot nobody gets in. Wrong passwords are rate limited.
- HTTPS from the first boot. nginx serves WatchYourLAN on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
- WatchYourLAN listens on localhost only. It is fixed to
127.0.0.1:8840by its service unit, so nginx is its only client. Saving another Host or Port on the settings page does not open it to the network. - Other web sites cannot act with your login. WatchYourLAN changes things with plain links (start a scan, probe a port, wake a host, add or delete a host). nginx refuses those requests when another web site's page sends them in your browser, and refuses any settings change whose browser
Originis not this instance. - The scanner is not root. WatchYourLAN and the
arp-scanit runs work as the unprivilegedwatchyourlanuser with exactly one Linux capability,CAP_NET_RAW(raw sockets for ARP), and cannot gain more.arp-scanitself carries no setuid bit and no file capabilities. - No access to the instance metadata service. nginx and WatchYourLAN (and every scan it starts) are blocked at the kernel level from the EC2 instance metadata service (IPv4 and IPv6), and WatchYourLAN's port checker reports the metadata address as closed.
- No third-party downloads at run time. The web themes and icons are served from the instance, so the pages load nothing from a CDN.
- Built from source, with current fixes. WatchYourLAN 2.1.4 is built from its official release source (checksum pinned) with Go 1.27.3. Two of the Go libraries it is built with received security fixes after 2.1.4 was released (
golang.org/x/netandgithub.com/jackc/pgx/v5); the image uses the fixed releases, with no known reachable vulnerabilities at build time. There is no compiler on the image. - Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.
What is on the image: WatchYourLAN 2.1.4 (/usr/local/bin/watchyourlan, settings and scan database in /var/lib/watchyourlan), arp-scan 1.10.0, 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 the VPC subnet you want to watch.
- A security group that allows TCP 22 (SSH), TCP 443 (WatchYourLAN) and TCP 80 (redirects to HTTPS) from the networks your administrators work from. WatchYourLAN needs no other inbound port. Its ARP scan does not depend on security groups.
Step 1: Launch the instance
In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick WatchYourLAN 2.1.4 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large (WatchYourLAN itself needs very little, so a smaller instance also works), your key pair, the subnet you want to watch and a security group as above. WatchYourLAN scans the subnet of the instance's primary network interface.
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=watchyourlan}]'
Step 2: Connect to your instance
| Version | SSH user |
|---|---|
| WatchYourLAN 2.1.4 on Ubuntu 24.04 | ubuntu |
ssh -i <your-key.pem> ubuntu@<public-ip>
Step 3: Check the services
First boot sets the host name, generates the certificate and the gate password and writes WatchYourLAN's settings; then WatchYourLAN and nginx start:
systemctl is-active watchyourlan-firstboot watchyourlan nginx
sudo test -f /var/lib/cloudimg/watchyourlan-firstboot.done && echo FIRSTBOOT_DONE
All three units are active and the first boot marker is present:
active
active
active
FIRSTBOOT_DONE
Only SSH and nginx listen on the network. WatchYourLAN listens on localhost only:
sudo ss -lntpH | awk '{print $4, $6}' | sed -E 's/users:\(\("([^"]+)".*/\1/' | grep -v '127.0.0.5' | sort -u
0.0.0.0:22 sshd
0.0.0.0:443 nginx
0.0.0.0:80 nginx
127.0.0.1:8840 watchyourlan
[::]:22 sshd
[::]:443 nginx
[::]:80 nginx
Step 4: Get your URL and password
sudo cat /var/lib/cloudimg/watchyourlan-credentials.txt
The file is readable by root only and holds the URL and the user name and password for this instance:
# WatchYourLAN 2.1.4 - generated on first boot by watchyourlan-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret.
WATCHYOURLAN_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
WATCHYOURLAN_USER=admin
WATCHYOURLAN_PASSWORD=<WATCHYOURLAN_PASSWORD>
#
# Open WATCHYOURLAN_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to
# https) and pass the HTTP Basic Auth prompt with WATCHYOURLAN_USER / WATCHYOURLAN_PASSWORD. WatchYourLAN has no accounts
# of its own: this gate is its login. It scans ens5 (this instance's subnet) every 2 minutes.
# Self-test: sudo watchyourlan-selftest Change the served name: sudo watchyourlan-set-hostname <your-domain>
# User guide: https://www.cloudimg.co.uk/guides/watchyourlan-2-1-4-on-ubuntu-24-04-aws/
The URL uses the instance's public DNS name from EC2 instance metadata. Opening https://<public-ip>/ sends you on to that name.
The image includes a self test. Through nginx it passes the gate, checks the pages, the scan, the scanner's privileges, the request guards and the metadata block:
sudo watchyourlan-selftest
SELFTEST-OK https 301 + healthz + gate 401 (anonymous and wrong password on 10 routes) / 200 + UI, local theme and icons, CSP + /api/version 2.1.4 + config loopback:8840 + watchyourlan uid watchyourlan, CapEff/Bnd/Amb = CAP_NET_RAW only, NoNewPrivs, listening 127.0.0.1:8840 only + scan lists gateway 172.31.80.1 (21 hosts) + 403 cross-site rescan + 403 cross-origin POST + 444 unknown host + metadata 000 inside watchyourlan and nginx, /api/port to metadata false (control 200 / true)
Step 5: Your network in the browser
Open the WATCHYOURLAN_URL in your browser. The certificate is self signed, so your browser asks you to confirm it the first time (or install your own certificate, Step 9). The browser then asks for a user name and password: enter WATCHYOURLAN_USER and WATCHYOURLAN_PASSWORD.
The home page lists every host the scans have found, with its name (reverse DNS), interface, IP address, MAC address, hardware vendor, when it was last seen, whether you have marked it known, and whether it answered the latest scan (green) or not (grey). Filter by interface, known or online, search, and sort by any column:

Choose Edit to name hosts and switch Known on for the ones you recognise; the unknown ones are what WatchYourLAN alerts on. Click an IP address to open the host's page: its details, a rename box, the Known switch, a Port Scan that checks a range of TCP ports from the instance, Wake-on-LAN, Delete host and its online history for a day:

History shows each host's recent scans as a row of green (online) and grey (offline) marks, so hosts that come and go are easy to spot:

Step 6: What WatchYourLAN scans
On AWS, arp-scan sends an ARP request to every 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.ec2.internal or ip-a-b-c-d.<region>.compute.internal), and the hardware vendor of a VPC interface shows as (Unknown: locally administered). The subnet's router (the first address, here 172.31.80.1) is always there.
The scan settings are on the Config page:

They are stored in /var/lib/watchyourlan/config_v2.yaml:
sudo grep -E '^(host|port|ifaces|timeout|trim_hist|use_db|arp_args):' /var/lib/watchyourlan/config_v2.yaml
host: 127.0.0.1
port: "8840"
arp_args: ""
ifaces: ens5
timeout: 120
trim_hist: 48
use_db: sqlite
(Once you save settings in the browser, WatchYourLAN rewrites the file with its keys in alphabetical order.)
- Interfaces is the network interface to scan (first boot sets the primary interface,
ens5on current instance types). Add a second network interface in another subnet and list both, separated by a space, to watch that subnet too. - Timeout is the time between scans in seconds; Trim History is how many hours of online/offline history to keep.
- Args for arp-scan and Arp Strings pass your own
arp-scanoptions or target lists, for example a narrower range.
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 7: Notifications, Prometheus and the API
The Config page's Shoutrrr URL sends a message when a new unknown host appears. It takes any Shoutrrr service URL, for example smtp://user:password@smtp.example.com:587/?from=watchyourlan@example.com&to=you@example.com or a Slack, Discord, Telegram or Gotify URL; Test notification sends a test. The instance needs outbound access to that service.

The Host and Port boxes have no effect on this image: the service unit fixes WatchYourLAN to 127.0.0.1:8840, behind nginx, whatever is saved there. With Prometheus config enabled, /metrics serves the host list for Prometheus (behind the same password).
WatchYourLAN also has a small JSON API (documented at /swagger/index.html on your instance), behind the same password. For example, the number of hosts found so far and the version:
H=$(sudo sed -n 's#^WATCHYOURLAN_URL=https://\([^/]*\)/$#\1#p' /var/lib/cloudimg/watchyourlan-credentials.txt)
U=$(sudo sed -n 's/^WATCHYOURLAN_USER=//p' /var/lib/cloudimg/watchyourlan-credentials.txt)
PW=$(sudo sed -n 's/^WATCHYOURLAN_PASSWORD=//p' /var/lib/cloudimg/watchyourlan-credentials.txt)
curl -sk --resolve "$H:443:127.0.0.1" -K - "https://$H/api/all" <<<"user = \"$U:$PW\"" | python3 -c 'import json,sys; print(len(json.load(sys.stdin) or []), "hosts")'
curl -sk --resolve "$H:443:127.0.0.1" -K - "https://$H/api/version" <<<"user = \"$U:$PW\""; echo
21 hosts
"2.1.4"
(curl -K - reads the password from standard input, so it does not appear in the process list.)
Step 8: Data and backups
Everything WatchYourLAN keeps is in /var/lib/watchyourlan: config_v2.yaml (settings) and scan.db (the hosts and their history, SQLite). To back it up, stop WatchYourLAN for a moment:
sudo systemctl stop watchyourlan
sudo tar -C /var/lib -czf /root/watchyourlan-backup.tgz watchyourlan
sudo systemctl start watchyourlan
To restore on a new instance, stop WatchYourLAN, extract the archive over /var/lib/watchyourlan (owner watchyourlan, mode 700) and start it again.
Step 9: 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 it. This sets the name nginx accepts and the request guards, and generates a new self signed certificate for it:
sudo watchyourlan-set-hostname <your-domain>
- For a certificate your browser trusts, put the certificate chain for
<your-domain>in/etc/ssl/watchyourlan/watchyourlan.crtand its private key in/etc/ssl/watchyourlan/watchyourlan.key(root only, mode 600), and 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.
Step 10: Security checks
nginx and WatchYourLAN are blocked from the instance metadata service:
for u in nginx watchyourlan; do printf '%s ' "$u"; systemctl show -p IPAddressDeny --value "$u" | tr ' ' '\n' | sort | tr '\n' ' '; echo; done
nginx 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
watchyourlan 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
WatchYourLAN runs as watchyourlan with only CAP_NET_RAW (bit 13, 0x2000) and cannot gain other privileges:
P=$(systemctl show -p MainPID --value watchyourlan)
ps -o user= -p "$P"
grep -E '^(CapEff|CapBnd|CapAmb|NoNewPrivs)' /proc/"$P"/status
watchyourlan
CapEff: 0000000000002000
CapBnd: 0000000000002000
CapAmb: 0000000000002000
NoNewPrivs: 1
The gate answers before WatchYourLAN does, nginx refuses a scan or settings change that another web site's page sends, and a request for a host name the instance does not serve gets no answer at all:
H=$(sudo sed -n 's#^WATCHYOURLAN_URL=https://\([^/]*\)/$#\1#p' /var/lib/cloudimg/watchyourlan-credentials.txt)
curl -sk -o /dev/null -w 'no password: %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/"
curl -sk -o /dev/null -w 'cross-site rescan: %{http_code}\n' --resolve "$H:443:127.0.0.1" -H 'Sec-Fetch-Site: cross-site' "https://$H/api/rescan"
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' --data 'theme=x' "https://$H/api/config/"
curl -sk -o /dev/null -w 'unknown host name: %{http_code}\n' --resolve evil.example:443:127.0.0.1 https://evil.example/ || true
no password: 401
cross-site rescan: 403
cross-origin POST: 403
unknown host name: 000
The credentials, the gate's password hash, the TLS key and WatchYourLAN's data are readable by root (and the data by the watchyourlan service user) only:
sudo stat -c '%a %U:%G %n' /var/lib/cloudimg/watchyourlan-credentials.txt /etc/nginx/watchyourlan.htpasswd /etc/ssl/watchyourlan/watchyourlan.key /var/lib/watchyourlan /var/lib/watchyourlan/config_v2.yaml
600 root:root /var/lib/cloudimg/watchyourlan-credentials.txt
640 root:www-data /etc/nginx/watchyourlan.htpasswd
600 root:root /etc/ssl/watchyourlan/watchyourlan.key
700 watchyourlan:watchyourlan /var/lib/watchyourlan
600 watchyourlan:watchyourlan /var/lib/watchyourlan/config_v2.yaml
Other notes:
- The password is a 24 character random string, stored as a SHA-512 crypt hash in
/etc/nginx/watchyourlan.htpasswd. To change it, write a new hash there (printf '%s\n' '<new-password>' | openssl passwd -6 -stdingives the hash; the line isadmin:<hash>), update the credentials file and runsudo systemctl reload nginx. - Who can reach it. Anyone with the password can see your subnet's hosts and start scans and port checks from the instance. Open ports 80 and 443 in the security group only to the networks your administrators use.
- The build.
/usr/share/doc/cloudimg-watchyourlan/BUILD-INFO.txtrecords the release, the Go toolchain and the two dependency updates;go.mod,go.sumandgo-version-m.txtnext to it list every library in the program. - Logs. nginx logs are in
/var/log/nginx; WatchYourLAN logs to the journal (journalctl -u watchyourlan), including each unknown host it finds.
Step 11: Keep it up to date
Ubuntu security updates install automatically. To apply all updates now:
sudo apt-get update && sudo apt-get upgrade -y
New WatchYourLAN releases arrive as new versions of this listing, built and checked the same way. To move to one, back up /var/lib/watchyourlan (Step 8), launch the new version and restore it. Read the WatchYourLAN release notes before you move.
Support and licensing
WatchYourLAN is open source under the MIT licence (aceberg and contributors); the licence text is in /usr/share/doc/cloudimg-watchyourlan/, and the source code is at github.com/aceberg/WatchYourLAN. arp-scan is open source under the GPL 3.0 or later licence, and the Go libraries WatchYourLAN is built with are open source under permissive licences (MIT, BSD and Apache 2.0). There is no per user licence fee. The AMI price covers cloudimg's build, hardening, first boot setup and support.
- Email: support@cloudimg.co.uk
- Website: https://www.cloudimg.co.uk
- Support: 24/7, with a 24 hour response SLA
The other versions on this listing are on the network monitoring guide.