Skip to content

About

Self-hosted IPAM: subnets, IPs and VLANs, ICMP discovery, live SNMP switch faceplates, racks and cables, topology up to the Internet, wall outlets, alerts, audit log and REST API.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

93 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

NexoraIPAM

Modern IP address management for teams who want to see their network, not a spreadsheet.

Tests Latest release PHP 8.5 Laravel 13 Livewire 4 Source-available license

Website Β· Features Β· Quick start Β· Compose Β· Development Β· Configuration Β· API Β· License

NexoraIPAM dashboard

NexoraIPAM keeps track of your subnets, IP addresses, VLANs and network devices in one place. It discovers hosts with ICMP, reads switches and routers over SNMP, raises alerts on conflicts and full subnets, and records every change in an audit log. The interface is available in English and French, with light and dark themes.

Features

πŸ—ΊοΈ Inventory

  • IPv4 and IPv6 subnets organised by location: agency, office and floor.
  • Interactive address map showing free, assigned and reserved addresses, the gateway and the DHCP pool.
  • Subnet planning: split a range into smaller blocks and delegate them.
  • Next free IP in one click, skipping the gateway, the DHCP pool and delegated blocks.
  • Network settings per subnet: gateway, DNS servers, DNS domain and DHCP range.
  • VLANs, tags and custom fields (text, number, link, date, list) on subnets, addresses and VLANs.

πŸ”Œ Switches and routers over SNMP

  • SNMP v2c and v3, with credentials encrypted at rest.
  • A live front panel of each switch, with RJ45, SFP and QSFP ports drawn as such. When a vendor's port names give no clue, administrators can set the connector of a port by hand; polls keep that choice. For every port: link state, speed, native, untagged and tagged VLANs, throughput, learned MAC addresses and LLDP neighbour.
  • VLAN colours: every VLAN gets a stable colour, or one you choose, shown on ports and lists. Click a VLAN to highlight its ports.
  • Racks and topology: place devices and passive items in racks unit by unit. Links between switches are drawn automatically from LLDP, or from the MAC addresses each switch learns from the other.
  • Rooms and cables: the racks of a location stand side by side in the order you choose, and the cables between them run through a tray drawn above the row. Hover a cable or an item to highlight both ends; click a link tag to jump to the other end. Document by hand what detection cannot see (patch cords, fibres between racks, devices without SNMP), with a medium and a tag: a detected link between the same ports confirms it. The medium of any link (Ethernet, fibre, DAC) can be set from the topology table or the rack link list, including links between devices that are not racked.
  • Way out to the Internet: give each device a role (edge router or firewall, core, distribution, access) and mark the ports that lead to a carrier as WAN, with the link name, public IP and circuit reference. The topology is then drawn in layers: the Internet cloud on top, connected to the WAN ports, then edge, core, distribution and access. A device without a role sits below its closest neighbour towards the edge; devices with no known link are set apart.
  • Large networks: each device is drawn under its uplink, as a tree, and the access switches of one parent wrap onto several rows past six. Zoom with the buttons, Ctrl + wheel or a pinch, drag to move around, and use the minimap to jump across a large network. Find a device by name or address, filter by location, and click a device to light it and its direct neighbours; click it again to open it.
  • Wall outlets: create a whole series at once (A1 to A24, or A01 with zero padding) per location, then patch each outlet to a switch port, from the outlet list or from the port panel of the device. The list shows the port state and VLAN, filters patched and free outlets, and unpatches or deletes a selection; the global search finds an outlet by name.
  • Patch plan: every switch of a location drawn as a grid, odd ports on top and even ports below, each port coloured by its native VLAN with the name of the wall outlet patched to it, like the spreadsheet it replaces. Click a port to patch or free it, click a VLAN to highlight its ports on every switch, and print the sheet for the rack.
  • The router ARP table fills in MAC addresses and adds unknown hosts to the inventory.
  • Uses standard MIBs (IF-MIB, BRIDGE-MIB, Q-BRIDGE-MIB, LLDP-MIB, IP-MIB), so it works across vendors.

Switch front panel with port details

πŸ“‘ Discovery, history and alerts

  • ICMP discovery with reverse DNS and ARP/NDP MAC collection, on demand or on a schedule.
  • Address history: every MAC address and host name seen on an IP, plus the switch port it is plugged into.
  • Host names without DNS: when reverse DNS has nothing, names come from DHCP leases (Kea API or ISC dhcpd.leases), NetBIOS, mDNS, LLDP and SNMP. A less reliable source never overwrites a better one.
  • Interactive dashboard: every figure opens the matching filtered list. It also shows hosts first seen this week with their MAC vendor and switch port, device health, the busiest ports, recent MAC changes and the latest changes.
  • Scan history: every ICMP discovery, SNMP poll and DHCP import with its trigger (manual, with its author, or scheduled), status, duration and result, kept for 90 days.
  • Alerts for subnets over a usage threshold, unknown hosts, available addresses that respond, MAC changes, hosts that go silent and unreachable devices. Alerts can be acknowledged and sent by e-mail.

πŸ” Global search

Press Ctrl + K (or /) anywhere to open the search:

  • An IP address also lists every subnet that contains it.
  • A MAC address, in any format, shows the switch port where it was learned.

Global search

πŸ”— REST API

Automate the inventory with a versioned JSON API and personal tokens: reserve the next free IP from a deployment, sync subnets from Terraform, query a MAC address from a script. See REST API.

πŸ›‘οΈ Security and accountability

  • Roles: administrator, operator and viewer.
  • Sign-in: local accounts with TOTP two-factor authentication, LDAP group membership, or OpenID Connect with PKCE.
  • Profile: local accounts change their name, password and two-factor settings, and their e-mail address after confirming a link sent to the new one (the former address is told of the change). Everyone sees their recent sign-ins.
  • Audit log: every creation, change and deletion with its author, IP address and before/after values. Secrets are masked. Sign-ins, settings changes, discoveries, SNMP polls and alerts are recorded too.

Address map with gateway and DHCP pool

Quick start with Docker

The image is published on GHCR as ghcr.io/pokertour/nexoraipam:vX.X.X. It runs FrankenPHP on PHP 8.5 and listens on port 8080.

  1. Generate an application key. It is 32 random bytes, base64-encoded with the base64: prefix:

    echo "base64:$(openssl rand -base64 32)"
  2. Create a .env file with this key and the public URL of the application:

    APP_KEY=base64:...
    APP_URL=https://ipam.example.com

    Or generate the file in one go:

    printf 'APP_KEY=base64:%s\nAPP_URL=%s\n' "$(openssl rand -base64 32)" https://ipam.example.com > .env
  3. Start the container:

    docker volume create nexora-data
    docker run -d --name nexora --env-file .env \
      -v nexora-data:/var/lib/nexora -p 8080:8080 \
      ghcr.io/pokertour/nexoraipam:vX.X.X
  4. Read the temporary administrator password in the logs, then sign in as admin@example.com. You will be asked to change the password on first sign-in.

    docker logs nexora

With Docker Compose

The repository ships a compose.yaml that runs NexoraIPAM with a MariaDB 12.3 LTS database. Put it in its own directory and create the .env file next to it, with the application key, the public URL and a database password:

printf 'APP_KEY=base64:%s\nAPP_URL=%s\nDB_PASSWORD=%s\n' \
  "$(openssl rand -base64 32)" https://ipam.example.com "$(openssl rand -hex 24)" > .env
docker compose up -d
docker compose logs nexora   # temporary administrator password

NexoraIPAM waits for MariaDB to be healthy, then applies the migrations. The data lives in the nexora-mariadb-data volume. The application container keeps no data of its own: sessions, cache and the job queue are stored in the database.

Variable in .env Default Purpose
DB_PASSWORD required Password of the MariaDB user, also used to create it on first start.
DB_DATABASE nexora Database name.
DB_USERNAME nexora Database user.
NEXORA_VERSION latest Image tag to run, for example v0.0.3.
NEXORA_PORT 8080 Port published on the host.

Keep the Compose directory outside a clone of the repository, where .env is the Laravel development file. MariaDB only creates the database and its user on the first start: changing DB_PASSWORD afterwards does not change it in MariaDB.

To upgrade, change NEXORA_VERSION or run docker compose pull, then docker compose up -d. To try local changes, build the image with docker build -t ghcr.io/pokertour/nexoraipam:dev ., then start it from your Compose directory with NEXORA_VERSION=dev docker compose up -d.

On every start, the container applies database migrations and makes sure the initial account exists. Supervisor then runs three processes: FrankenPHP, the queue worker that performs discoveries and SNMP polls, and the scheduler. Keep the same APP_KEY and volume across upgrades: the key decrypts the stored settings and credentials.

Behind a reverse proxy

Set APP_URL to the public HTTPS address: links, scripts and styles are then always served in HTTPS. The container trusts the X-Forwarded-For, -Proto, -Host and -Port headers from proxies on private networks (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, loopback and fc00::/7), which covers a proxy in the same Docker network or on the LAN. Set TRUSTED_PROXIES in .env to a comma-separated list of addresses or ranges to narrow it, or to * to trust any proxy. Never use * if the container port is also reachable directly, as clients could then forge their IP address in the audit log.

location / {
    proxy_pass http://nexora:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

The worker probes networks from the container, so the container must be able to reach them. Any other command, for example docker run --rm <image> php artisan …, runs without starting the services.

Local development

Requirements: PHP 8.3+ with PDO SQLite, Composer, Node.js 20.19+ or 22.12+ and npm. Install the PHP LDAP extension only if you use directory sign-in.

composer install
cp .env.example .env
php artisan key:generate
touch database/database.sqlite
php artisan migrate
npm ci && npm run build
php artisan nexora:install   # prints the temporary administrator password
php artisan serve

Discoveries and SNMP polls run on the discovery queue. Start the worker and the scheduler next to the web server:

php artisan queue:work database --queue=discovery
php artisan schedule:work

The worker host needs a few system tools:

Feature Tools
ICMP discovery and reverse DNS ping (iputils) and getent
Host names over NetBIOS and mDNS nmblookup (samba-client / samba-common-bin) and dig (bind-tools / dnsutils)
MAC addresses from ARP/NDP iproute2
SNMP snmp on Debian/Ubuntu, net-snmp-tools on Alpine
MAC vendor lookup in Tools ieee-data, or the IEEE CSV files in /usr/share/ieee-data

In production, set APP_ENV=production and an HTTPS APP_URL, point the web server to public/, run php artisan schedule:run every minute, and keep the discovery worker running.

Configuration

Administrators configure everything from Settings in the application. Authentication and SMTP settings are stored encrypted.

Role Access
Administrator Inventory, devices, users, tags and fields, audit log and settings
Operator Read and edit the inventory, acknowledge alerts
Viewer Read the inventory, devices and alerts
  • Users: the list shows every account with a Local, LDAP or OpenID Connect badge and its last sign-in, and filters by source. Directory and SSO accounts appear after their first sign-in.
  • Local accounts: create them in Users and share the temporary password. Administrators can delete any account except their own and the installation account, which is recognised by its id and may change its e-mail address. The installation account keeps local access as a fallback when local sign-in is disabled.
  • LDAP: enter the LDAPS URL, base DN, allowed AD group DN and service account. Direct and nested members of the group sign in with their mail attribute and get a viewer account on first sign-in. Install the directory CA in the server trust store if needed.
  • OpenID Connect: register a confidential client using HTTPS discovery, the authorization code flow, PKCE S256 and RSA signatures. Declare the callback URL shown in Settings (/auth/openid/callback) at your provider. The e-mail address (only when verified) and the name come from the ID token or, when it carries none as with Zitadel by default, from the userinfo endpoint. The scopes default to openid profile email and can be changed, for example to add groups; openid is always requested. Authorized users get a viewer account on first sign-in.
  • Sign-in page: choose the method offered first, for example SSO above the local form, and set the text and icon of the LDAP and OpenID Connect buttons (Microsoft, key, shield, building…).
  • SMTP: set the sender, server and credentials, then use Send a test. Implicit TLS, STARTTLS and, for a local relay, no encryption are supported.
  • Alerts: set the IPv4 usage threshold, choose which conflicts to report and whether new alerts are sent by e-mail.
  • SNMP devices: add each device in Devices with its address, UDP port and v2c community or v3 credentials, then edit it from the list or from its page. Read-only access is enough. Set an interval to poll it automatically. Throughput appears from the second poll. If a model reports ports or VLANs incorrectly, php artisan nexora:snmp-dump <device> prints the SNMP tables NexoraIPAM reads, without the credentials.
  • Device API: some devices do not publish their VLANs over SNMP. MikroTik RouterOS, for example, leaves the Q-BRIDGE-MIB tables empty. For these, choose an API in the device form; it then provides the native, untagged and tagged VLANs of each port while SNMP keeps providing everything else. If the API fails, the poll still completes with the SNMP data and the device page shows the error.
    • MikroTik RouterOS: three drivers read the same bridge VLAN table. Each needs a dedicated read-only group and user, for example /user group add name=nexora-api policy=read,api,rest-api then /user add name=nexora group=nexora-api password=….

      • API-SSL, port 8729 (recommended, RouterOS 6.43 or later): enable the api-ssl service (/ip service set api-ssl disabled=no), ideally with a certificate (certificate=…). Without one, RouterOS only offers anonymous TLS: turn off certificate verification. The read and api policies are enough.
      • REST, HTTPS (RouterOS 7.1 or later): enable the www-ssl service with a certificate. It needs the rest-api policy too, and also exposes WebFig.
      • API, port 8728: enable the api service. Not encrypted: the password and configuration cross the network in clear text, so keep it to an isolated management network.

      Turn off certificate verification only for a self-signed certificate on a trusted network.

  • DHCP leases: enter the Kea control agent URL and credentials, or the path of an ISC dhcpd.leases file readable by the worker, and an import interval. Active leases name the addresses they cover and add unknown ones that fall in an inventoried subnet.
  • Automatic discovery: set an interval in minutes on a location. It applies to the subnets attached directly to that location.

SQLite is the default database. MariaDB is supported and tested in CI, and the Compose file uses it. Configure the connection through the standard Laravel DB_* variables.

REST API

The API lives under /api/v1 and returns JSON. Only administrators create tokens, in Administration β†’ API tokens, for the account the token will act as; a dedicated account per automation tool is recommended. A token is shown once, is either read-only or read-write (writes also require the operator or administrator role of its account), and can expire. The same page revokes tokens and shows their history: token creation and revocation, and every change made with each token, which the audit log also labels with the token name. Send the token as a bearer token:

curl -H "Authorization: Bearer $NEXORA_TOKEN" https://ipam.example.com/api/v1/me
Method and path Purpose
GET /me Current account and token abilities.
GET /search?q= Global search, as with Ctrl + K: subnets containing an IP, switch port of a MAC, and so on.
GET /subnets Subnets. Filters: search, location, tag, per_page.
POST /subnets, GET/PATCH/DELETE /subnets/{id} Manage a subnet: name, cidr, location_id, vlan_id, gateway, dns_servers, domain, dhcp_start, dhcp_end, tags, custom_fields.
GET /subnets/{id}/addresses Addresses of a subnet.
POST /subnets/{id}/next-free Reserve the next free address, with optional hostname, description, status, tags and custom_fields.
GET /addresses Addresses. Filters: subnet, status, address, mac, search.
POST /addresses, GET/PATCH/DELETE /addresses/{id} Manage an address: subnet_id, address, hostname, status, description, tags, custom_fields.
GET /vlans, POST /vlans, GET/PATCH/DELETE /vlans/{id} Manage VLANs: number, name, location_id, color, description.
GET /locations, GET /locations/{id} Locations, read-only.
GET /devices, GET /devices/{id} SNMP devices, read-only. A single device includes its ports, VLANs, throughput, MAC addresses and LLDP neighbours.

Reserve an address for a new virtual machine:

curl -X POST -H "Authorization: Bearer $NEXORA_TOKEN" -H "Content-Type: application/json" \
  -d '{"hostname": "vm-web-01", "tags": ["production"]}' \
  https://ipam.example.com/api/v1/subnets/12/next-free

The API applies the same rules as the interface: CIDR and addresses are normalised, the gateway and DHCP range must belong to the subnet, a subnet with addresses cannot be deleted, and every change is written to the audit log with the token owner as author.

Status Meaning
401 Missing or invalid token.
403 Token without the needed ability, role not allowed to write, or account disabled.
409 Conflict: no free address left, or a subnet that still holds addresses.
422 Validation error, with the details in errors.

Lists are paginated with data, links and meta. Error messages follow the Accept-Language header (English or French). Each token is limited to 120 requests per minute.

Releases

Pushes and pull requests run the test suite. To publish a version, open Actions β†’ Tests et publication β†’ Run workflow and enter vX.X.X. The workflow then:

  1. runs the tests;
  2. builds and checks the image;
  3. pushes the version and latest tags to GHCR;
  4. creates the GitHub release.

The About page checks for the latest release. For a private repository, set GITHUB_RELEASE_TOKEN to a token with read access.

Testing

vendor/bin/phpunit
npm run build

License

NexoraIPAM is source-available, not open source. It is released under the NexoraIPAM Source Available License v1.0. In short:

  • βœ… You may read the code and use NexoraIPAM for free, including inside a company, for your own internal needs.
  • βœ… You may modify it for your own internal use.
  • ❌ You may not redistribute it, publish forks, or offer it as a hosted service without written permission.
  • ❌ Paid services built on NexoraIPAM require prior authorization: installation, integration, hosting, support or training for third parties.

This summary is for convenience only: the license text is authoritative. Contributions are welcome under the terms described in CONTRIBUTING.md.

Made by pokertour

About

Self-hosted IPAM: subnets, IPs and VLANs, ICMP discovery, live SNMP switch faceplates, racks and cables, topology up to the Internet, wall outlets, alerts, audit log and REST API.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages