Skip to main content

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-user places files at ~/.config/routermonitor).
  • Decide on which DHCP clients list lookup method you wish to use (see more details below):
    • Mode = MIM_API is 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_APIV2 is second best - Fast. No last_seen or expiry info available for static mapped clients.
    • Mode = Page_Scrape is is completely functional, but slower than the APIs since pfSense logins can be slow. Matches Unofficial_APIV2 results
  • Edit/configure routermonitor.cfg, creds_SMTP, and creds_routermonitor as needed.
  • Run routermonitor once manually to build the clients database. It will take a few moments for rate-limited MACOUI lookups.
  • Do routermonitor --add-note runs 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 just routermonitor) provides a list of all known clients over time. --sort-by hostname may be useful. The report may be sorted by mac, hostname, ip, device, first_seen, last_seen, expiry, notes, or macoui. The default SortBy may be set in the config file.
  • routermonitor --list-dhcp-server provides a list of the currently known DHCP clients on the server. --sort-by is supported with fields mac, hostname, ip, device, last_seen, and expiry.
  • routermonitor amaz provides a list of all clients in the database that have the string 'amaz' in any field (two in the above example output) while routermonitor .2. lists all clients on my Guest WiFi (192.168.2.*, three in the above example output). Filtering is supported with --list-dhcp-server also.
  • routermonitor --update finds 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. See LogLevel in 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
  • See the routermonitor.cfg starter file for configuring access to the MIM API.

Notes and considerations

  1. 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".
  2. 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.
  3. With the MIM API the hostname field 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.
  4. 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. routermonitor accumulates 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.
  5. 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_id field, which specifies which pfSense+ instance the API request targets. routermonitor supports specifying a series of Devices in 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 the creds_routermonitor config file API_key param.

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 lease in the expiry column.
  • last_seen and expiry are 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_path param. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

routermonitor-4.0.tar.gz (29.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

routermonitor-4.0-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

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

Hashes for routermonitor-4.0.tar.gz
Algorithm Hash digest
SHA256 1fecb7f4deb5064859dc0620d4fdf262acbb901fe86f08c62175ef274bec2722
MD5 fb316d14663ecc6c411bfa564efe375b
BLAKE2b-256 3f52a1f357b055b74c966a88ff8d04d54023f004498454d22fba383670e68e3d

See more details on using hashes here.

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

Hashes for routermonitor-4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b5f25cc5e501aa58fc7c43bf10104e52388973e0bff399ddb0211310d297aba2
MD5 afd159aeb73d8e91f4eb179664b404b5
BLAKE2b-256 b02f4cb0896456e3c309f03541ae98144fb5533d1591e1bf072b2acba51ca891

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page