Watch for new DHCP clients on your LAN
Project description
routermonitor
routermonitor logs/monitors DHCP clients managed by your pfSense DHCPv4 server. I use pfSense as my home DHCP server and find that over time that I've accumulated several clients on my network that I cannot readily identify. routermonitor watches the DHCP leases and tracks changes in a sqlite3 database. Any new client found on the network results in a text message notification.
- Clients come and go over time, as family members come and visit, and as DHCP leases expire. The history of known clients is tracked by MAC address. Clients may be manually deleted from the database (i.e., That laptop went in the tub with kids! (long gone)). No changes are ever made on the dhcp server.
- Some hostnames are ambiguous, such as '*' and 'android-2ab8700dff69dbfd', and some devices issue random MAC addresses. Notes may be manually added for each tracked client.
- The Organization Unique ID for for each clients' MAC address is looked up and added to the database, often providing enough info to identify strange clients.
Definition of terms:
- client is used in this documentation to refer to a host/client on your network that has requested an IP address via DHCP.
- device refers to a pfSense(+) DHCP server on your network. pfSense devices are also referred to as the router or dhcp server in this documentation.
Supports
- Linux and Windows
- Python 3.9+
- pfSense+ 25.07.1 and above, and corresponding pfSense CE versions (2.8.0+?) (tested on 25.07.1 and 25.11)
- pfSense ISC and Kea servers
- pfSense+ MIM API, UnofficialV2 API, and Status > DHCP Leases page scrape modes
Notable changes since prior release (V3.1)
- Removed support for dd-wrt
- Updated page scrape mode to be compatible with more recent DHCP Leases page layout - Works with both ISC and Kea DHCP servers.
- Added support for the new Nexus multi-instance management (MIM) API
- Added support for the Unofficial V2 API (https://pfrest.org/)
- Added support for last_seen (most recently seen) tracking and reporting
Usage
$ routermonitor -h
usage: routermonitor [-h] [--update] [--list-db] [--list-dhcp-server] [--sort-by {hostname,ip,first_seen,last_seen,expiry,mac,macoui,notes}] [--create-db] [--note NOTE] [--delete] [--MAC MAC] [--config-file CONFIG_FILE] [--print-log]
[--service] [-v] [--setup-user] [--setup-site] [-V]
[SearchTerm]
Monitor for new clients on the network.
The network dhcp server is queried for currently known DHCP clients.
Any new clients are identified and a notification is sent.
4.0
positional arguments:
SearchTerm Print database records containing this text.
options:
-h, --help show this help message and exit
--update, -u Check the dhcp server for new connections and update the database.
--list-db, -l Print known clients on the network from the database (default mode).
--list-dhcp-server, -r
Print known clients on the network from the dhcp server.
--sort-by {hostname,ip,first_seen,last_seen,expiry,mac,macoui,notes}, -s {hostname,ip,first_seen,last_seen,expiry,mac,macoui,notes}
Sort --list-db and --list-dhcp-server output. Overrides config SortBy. Default <hostname> if neither specified.
--create-db Create a fresh database and populate it with the current dhcp server clients.
--note NOTE, -n NOTE Add a note to the db for the specified --MAC.
--delete Delete from the db the specified --MAC.
--MAC MAC, -m MAC MAC address for --add-note or --delete.
--config-file CONFIG_FILE, -c CONFIG_FILE
Path to the config file (Default <routermonitor.cfg)> in user/site config directory.
--print-log, -p Print the tail end of the log file (default last 40 lines).
--service Run updates in an endless loop for use as a systemd service.
-v, --verbose Print status and activity messages (-vv for debug logging)
--setup-user Install starter files in user space.
--setup-site Install starter files in system-wide space. Run with root prev.
-V, --version Return version number and exit.
Example output
$ routermonitor
WARNING: ========== routermonitor (4.0) ==========
WARNING: Config file </path/to/routermonitor.cfg>
hostname first_seen last_seen ip expiry device mac macoui notes (Sorted by <last_seen>)
Denon-AVR-X1600H 2020-05-22 18:23:30 2025-11-29 21:29:18 192.168.1.112 2020-05-24 10:42:07 pfsense.mylan 00:05:cd:8a:ab:8d Denon, Ltd. -
Galaxy-S10-jen 2020-05-22 18:23:33 2025-11-30 11:01:02 192.168.1.114 2020-05-22 18:33:29 pfsense.mylan 10:98:c3:80:cd:b2 Murata Manufacturing Co., Ltd. -
amazon-b6f1c2033 2020-05-23 06:45:05 2025-11-30 11:06:36 192.168.1.118 2020-05-24 12:57:19 pfsense.mylan 38:f7:3d:16:ef:40 Amazon Technologies Inc. Wife's Kindle Fire
espressif 2020-05-22 18:23:35 2025-11-30 11:23:37 192.168.2.121 2020-05-24 11:45:03 pfsense.mylan 44:67:55:02:01:7f Orbit Irrigation -
Flex5 2020-05-22 18:23:36 2025-11-30 11:25:41 192.168.1.123 2020-05-24 11:59:32 pfsense.mylan 50:5b:c2:e1:23:ef Liteon Technology Corporation -
* 2020-05-22 18:23:37 2025-11-30 11:31:48 192.168.1.144 2020-05-24 15:21:31 pfsense.mylan 64:52:99:90:45:aa The Chamberlain Group, Inc Liftmaster gateway 828LM in office
MyQ-F8C 2020-05-22 18:23:38 2025-11-30 11:32:15 192.168.1.143 2020-05-24 11:07:13 pfsense.mylan 64:52:99:91:67:51 The Chamberlain Group, Inc Garage door opener
ESP_48CEBF 2020-05-22 18:23:40 2025-11-30 11:33:19 192.168.2.146 2020-05-24 08:51:01 pfsense.mylan 80:7d:3a:48:89:bf Espressif Inc. Basement lights smartswitch
* 2020-05-22 18:23:41 2025-11-30 11:34:23 192.168.2.133 2020-05-24 15:00:59 pfsense.mylan 8c:85:80:1d:ab:69 Smart Innovation LLC Eufy doorbell
RPi1 2020-05-22 18:23:42 2025-11-30 11:36:13 192.168.1.31 static lease pfsense.mylan b8:27:eb:25:cd:f7 Raspberry Pi Foundation -
FireStick4k 2020-05-22 18:23:44 2025-11-30 11:37:04 192.168.1.40 static lease pfsense.mylan cc:9e:a2:56:ef:c9 Amazon Technologies Inc. -
...
<73> known clients.
Setup and Usage notes
- Install routermonitor from PyPI (
pip install routermonitor) - Install the initial configuration files (
routermonitor --setup-userplaces files at~/.config/routermonitor). - Decide on which DHCP clients list lookup method you wish to use (see more details below):
Mode = MIM_APIis the best choice if you are using a Netgate pfSense+ device or have a Plus license - Fast and best information. If using the MIM API you will need to manually install the Netgate pfsense-api (see below).Mode = Unofficial_APIV2is second best - Fast. Nolast_seenorexpiryinfo available for static mapped clients.Mode = Page_Scrapeis is completely functional, but slower than the APIs since pfSense logins can be slow. MatchesUnofficial_APIV2results
- Edit/configure
routermonitor.cfg,creds_SMTP, andcreds_routermonitoras needed. - Run
routermonitoronce manually to build the clients database. It will take a few moments for rate-limited MACOUI lookups. - Do
routermonitor --add-noteruns to annotate client info, as desired. Example:routermonitor --MAC 80:7d:3a:48:ce:bf --add-note "Basement lights smartswitch". routermonitor --list-db(equivalent to justroutermonitor) provides a list of all known clients over time.--sort-by hostnamemay be useful. The report may be sorted by mac, hostname, ip, device, first_seen, last_seen, expiry, notes, or macoui. The defaultSortBymay be set in the config file.routermonitor --list-dhcp-serverprovides a list of the currently known DHCP clients on the server.--sort-byis supported with fields mac, hostname, ip, device, last_seen, and expiry.routermonitor amazprovides a list of all clients in the database that have the string 'amaz' in any field (two in the above example output) whileroutermonitor .2.lists all clients on my Guest WiFi (192.168.2.*, three in the above example output). Filtering is supported with--list-dhcp-serveralso.routermonitor --updatefinds any new clients on the network, adds them to the database, and sends a text message notification (see routermonitor.cfg). Any changes in IP address or IP Expiry time are logged to log_routermonitor.txt at the INFO level. SeeLogLevelin routermonitor.cfg.- Optionally set up the routermonitor systemd service. A template .service file is provided in the config directory.
- When running in service mode (continuously looping) the config file may be edited and is reloaded when changed. This allows for changing settings without having to restart the service.
Using the Netgate Nexus MIM API (pfSense+ devices/appliances only) (Mode = MIM_API)
Setup
-
Clone the Python interface github distribution to your local filesystem
cd <my-temp-space> git clone https://github.com/Netgate/pfsense-api.git # creates ./pfsense-api pip install ./pfsense-api/py # Once installed the cloned directory <my-temp-space>/pfsense-api may be deleted. -
In the pfsense+ GUI set the device to HTTPS access mode
- The API will not work in HTTP mode
- System > Advance > Admin Access > Protocol = HTTPS (SSL/TLS)
- This uses a self-signed certificate, so your browser may want your approval to connect.
- For more secure access, see below for setting up a certificate authority. Do this step before enabling Netgate Nexus Controller so that port 8443 is properly set up with the internally signed 'Server Certificate'. If you set up the CA after enabling Netgate Nexus then simply disable and re-enable Netgate Nexus Controller again.
-
Enable Netgate Nexus
- System > Advanced > Netgate Nexus > Enable Netgate Nexus Controller
- This enables the official Nexus MIM API. Without paying for a license you can access only the
localhostdevice. - See https://docs.netgate.com/pfsense/en/latest/nexus/setup.html
- The user must have full admin privileges (be a member of the admins group), as of 25.07.1 RELEASE.
- This enables the official Nexus MIM API. Without paying for a license you can access only the
- System > Advanced > Netgate Nexus > Enable Netgate Nexus Controller
-
See the routermonitor.cfg starter file for configuring access to the MIM API.
Notes and considerations
- A key benefit of using the MIM_API mode is that real DHCP lease start and expiry times are available. In the other modes all statically mapped clients simply show as "static lease".
- Netgate Nexus and the MIM API were first released on pfSense+ version 25.07. For older pfSense+ versions and the CE version see the Unofficial V2 API.
- With the MIM API the
hostnamefield comes first from the pfSense+ DHCP static mappings, with fallback to the hostname provided by the client on a DHCP request. The hostname is lower case, as by-spec hostnames are case insensitive. Windows clients will have a '.' appended to the hostname. - Kea DHCP server only issues and logs IP assignments from clients that actively send a DHCP request (this may be true also for the ISC server). For static mapped clients, Kea issues the specified fixed address, with a 2 hour lease, meaning that a statically mapped clients must periodically request a new IP (and gets back the fixed assignment). The MIM API only reports actually requested/issued IP addresses. Clients with statically assigned addresses but not on the network wont show up in the list. Therefore, long-story-short, the MIM API may report a subset of the statically assigned IP addresses/clients.
routermonitoraccumulates the history of connected clients, so the transient nature of the lease list is not a problem. Note that the other update methods (Unofficial_APIV2 and Page_Scrape) show all static mappings. - Netgate Nexus on pfSense+ devices provides the multi-instance management (MIM) API, with specific support for accessing/controlling multiple pfSense+ devices on a network from a single "controller" (the master pfSense+ device). MIM API accesses have a
device_idfield, which specifies which pfSense+ instance the API request targets.routermonitorsupports specifying a series ofDevicesin the config file. The devices will be accessed in the order listed with all found clients merged into one DHCP clients list. The default Devices lists is['localhost']. If you have a multi-instance network you will need a paid subscription to use Nexus across devices, and then the MIM API can also be used across devices.
Using the Unofficial V2 API (Mode = Unofficial_APIV2)
Setup
-
Install the Unofficial V2 API on your pfSense device. This API works on both Netgate pfSense+ devices (24.11+) and on CE devices (2.8.0+). See https://pfrest.org/INSTALL_AND_CONFIG/. The install can be done via an SSH login, using the device console, or using the GUI Diagnostics > Command Prompt > Execute Shell Command. Example for pfSense+ 24.11 (do install the correct version):
pkg-static -C /dev/null add https://github.com/jaredhendrickson13/pfsense-api/releases/latest/download/pfSense-24.11-pkg-RESTAPI.pkg -
To enable the API, briefly, you will need to, at System > REST API > Settings, Enable the API, set Allowed Interfaces, and set up the Authentication Method to
Key. On the Keys tab, create a key and save the key value to thecreds_routermonitorconfig fileAPI_keyparam.
Notes and considerations
- This API returns the same information as on the Status > DHCP Leases page, including static mapped clients that are not currently on the network.
- This API runs a whole lot faster than the Page_Scrape mode.
- Static mapped clients will report
static leasein theexpirycolumn. last_seenandexpiryare only reported for non-static mapped clients.- The reported device field will always be the URL to the pfSense device since there is no multi-device support.
Using page scrape mode (Mode = Page_Scrape)
Setup
-
No setup necessary beyond entering your GUI admin login credentials in the routermonitor config file. Actually, always put credentials in a file hidden from other users and import that file in the routermonitor config.
-
For better security, you may wish to create a limited access user (System > User Manager) with just these privileges:
WebCfg - Dashboard (all) Allow access to all pages required for the dashboard. WebCfg - Status: DHCP leases Allow access to the 'Status: DHCP leases' page.
Notes and considerations
- This method attempts to read and parse the Status > DHCP Leases page. On first access the Login page is presented and routermonitor proceeds to log in and then access the Leases page. All of this take several seconds.
- See the Notes and considerations for the Unofficial V2 API, above.
Using a Certificate Authority
Each access mode supports verified SSL access by configuring a certificate authority within pfSense. In short, to set up certificates for use with routermonitor:
- Create a self-signed 'CA certificate' (System > Certificates > Authorities), then 'Export CA' to a file. This is the CA public key. Set the path to this file in the routermonitor config file
CA_pathparam. Note that the directory path to the CA file defaults to~/.config/routermonitor- an absolute path or a path relative to ~/.config/routermonitor may be specified. - Create a internally signed 'Server Certificate' (System > Certificates > Certificates) that refers to the new CA certificate (thus not a self-signed server certificate), with a Common Name (CN) or SAN entry set to the URL being used to access the device by routermonitor.
- Change the webGUI (webConfigurator) to use the new internally signed server certificate (System > Advanced > Admin Access > SSL/TLS Certificate). Once set, the new server certificate will show as in use by the 'webConfigurator'. Delete the original server cert. Your browser may need some nudging at this point.
- If applicable, change the MIM API to use the new internally signed server certificate (System > Advanced > Netgate Nexus > TLS Certificate). You may need to disable/re-enable Netgate Nexus to propagate the new certificate setup to port 8443.
Use of a CA is optional. CA_path defaults to False if not defined, which disables SSL verification.
Version history
-
4.0 251220 - Remove dd-wrt support, Added MIM_API and Unofficial_APIV2 support.
-
3.1 240106 - Fixed service mode exit when pfsense router is not accessible. Added retries to lookup_MAC().
- Adjusted for cjnfuncs V2.1 (module partitioning).
- Fixed service mode exit when pfsense router is not accessible.
- Added retries to lookup_MAC().
- Adjusted pfsense DHCP Leases table parsing (case changes in header) in 23.09-RELEASE.
- Adjusted pfsense DHCP Leases table parsing for ISC DHCP EOL header warning.
-
3.0.5 230226 - Fixed inclusion of deployment_files
-
3.0 230215 - Converted to package format, updated to cjnfuncs 2.0
-
2.0 221023 - Revamped, moved from mysql to sqlite3
-
...
-
0.1 200426 - New
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file routermonitor-4.0.tar.gz.
File metadata
- Download URL: routermonitor-4.0.tar.gz
- Upload date:
- Size: 29.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fecb7f4deb5064859dc0620d4fdf262acbb901fe86f08c62175ef274bec2722
|
|
| MD5 |
fb316d14663ecc6c411bfa564efe375b
|
|
| BLAKE2b-256 |
3f52a1f357b055b74c966a88ff8d04d54023f004498454d22fba383670e68e3d
|
File details
Details for the file routermonitor-4.0-py3-none-any.whl.
File metadata
- Download URL: routermonitor-4.0-py3-none-any.whl
- Upload date:
- Size: 23.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5f25cc5e501aa58fc7c43bf10104e52388973e0bff399ddb0211310d297aba2
|
|
| MD5 |
afd159aeb73d8e91f4eb179664b404b5
|
|
| BLAKE2b-256 |
b02f4cb0896456e3c309f03541ae98144fb5533d1591e1bf072b2acba51ca891
|