In un homelab, presi dall’entusiasmo, è facile aggiungere servizi, VLAN, macchine virtuali e container in modo quasi compulsivo. In poco tempo, la rete diventa un labirinto di indirizzi IP: quali sono già assegnati? Quali sono liberi? Quali è possibile utilizzare senza generare conflitti? Tenere traccia manualmente di tutto questo risulta caotico e soggetto a errori, soprattutto con l’aumentare della complessità.
È in questo contesto che un IPAM o IP Address Management diventa imprescindibile: uno strumento progettato proprio per centralizzare, organizzare e automatizzare la gestione degli indirizzi IP.
Ultimamente ho testato diverse soluzioni open source, come NetBox e phpIPAM, ma mi sono sembrate eccessivamente complesse da installare e gestire e con funzionalità superflue per le mie esigenze attuali. Tra le altre soluzioni, NIPAP, nonostante i suoi limiti, rimane per me insostituibile: semplice, funzionale e focalizzato su ciò che realmente serve. Fa una cosa, e la fa bene.
Tuttavia, non è un software perfetto: lo sviluppo, sebbene attivo, procede lentamente, non ci sono nuove funzionalità da tempo, da interfaccia grafica non prevede alcun automatismo e, in molti aspetti, risulta ancora grezzo e macchinoso. Nonostante questo, per il mio utilizzo e per la mia rete interna, i pregi superano i difetti: per me, rimane la scelta migliore.
Installazione di NIPAP
Come descritto nell’articolo dedicato, il primo passaggio consiste nella creazione di una macchina virtuale Debian all’interno di Proxmox VE, utilizzando preferibilmente un template preconfigurato oppure una delle immagini ufficiali in formato qcow2.
Una volta completato il provisioning della macchina virtuale, procedere con l’installazione di Docker seguendo la documentazione ufficiale.
La VM verrà inserita nella VLAN di Management (10.0.5.0/24) e configurata automaticamente tramite Cloud-Init con i seguenti parametri di rete:
- Indirizzo IP: 10.0.5.21/24
- Gateway: 10.0.5.254
- DNS: 10.0.5.254
Risulta superfluo specificare che indirizzi, subnet, VLAN, ecc. dipendono dal proprio laboratorio.
Dopo la creazione della macchina virtuale, è consigliabile includerla immediatamente nel piano di backup di Proxmox.
NIPAP dietro reverse proxy
Per consentire l’accesso al servizio in HTTPS, NIPAP viene pubblicato dietro un reverse proxy. Nella nostra infrastruttura, viene utilizzato Nginx Proxy Manager Plus, con un certificato self-signed.
Nella sezione Advanced del Proxy Host aggiungere le seguenti direttive, che consentono di aumentare le dimensioni dei buffer utilizzati dal proxy e prevenire eventuali problemi con risposte HTTP di grandi dimensioni:
proxy_busy_buffers_size 512k;
proxy_buffers 4 512k;
proxy_buffer_size 256k;
Per una maggior sicurezza, possiamo anche impostare delle Access List, limitando l’accesso a soli determinati indirizzi IP.
Bisogna creare la regola di firewall affinché NPM possa raggiungere NIPAP sulla porta 80.
Infine, creare un DNS override in OPNsense da Services > Unbound DNS > Overrides, in modo che ipam.home.lan punti all’indirizzo IP del reverse proxy (10.0.70.1 nel nostro homelab).
Creazione stack Docker compose
Una volta completata la creazione della macchina virtuale e terminate le configurazioni preliminari, accedere alla nuova VM tramite SSH e posizionarsi nella directory /opt, che verrà utilizzata per ospitare lo stack Docker.
Creare quindi la cartella /opt/nipap e, al suo interno, i file docker-compose.yml e .env.
docker-compose.yml
x-common-security: &common-security
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
services:
db:
image: nipap/postgres-ip4r:latest
container_name: nipap-db
restart: unless-stopped
<<: *common-security
cap_add:
- CHOWN
- FOWNER
- DAC_OVERRIDE
- SETUID
- SETGID
stop_grace_period: 30s
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./postgres:/var/lib/postgresql/data
nipapd:
image: nipap/nipapd:latest
container_name: nipapd
restart: unless-stopped
<<: *common-security
depends_on:
db:
condition: service_healthy
environment:
# PostgreSQL connection
DB_HOST: db
DB_PORT: 5432
DB_NAME: ${POSTGRES_DB}
DB_USERNAME: ${POSTGRES_USER}
DB_PASSWORD: ${POSTGRES_PASSWORD}
# NIPAP API account
# Used by nipap-www to authenticate against nipapd
AUTH_BACKEND: local
NIPAP_USERNAME: ${NIPAPD_USERNAME}
NIPAP_PASSWORD: ${NIPAPD_PASSWORD}
nipap-www:
image: nipap/nipap-www:latest
container_name: nipap-www
restart: unless-stopped
<<: *common-security
depends_on:
- nipapd
ports:
- "80:80"
environment:
# Connection to NIPAP backend
NIPAPD_HOST: nipapd
NIPAPD_PORT: 1337
# Credentials used to access nipapd API
NIPAPD_USERNAME: ${NIPAPD_USERNAME}
NIPAPD_PASSWORD: ${NIPAPD_PASSWORD}
# Web login credentials
WWW_USERNAME: ${WWW_USERNAME}
WWW_PASSWORD: ${WWW_PASSWORD}
.env:
POSTGRES_DB=nipap
POSTGRES_USER=nipap
POSTGRES_PASSWORD=
NIPAPD_USERNAME=admin
NIPAPD_PASSWORD=
WWW_USERNAME=admin
WWW_PASSWORD=
In estrema sintesi, il file compose definisce uno stack per l’esecuzione di NIPAP, composto da tre servizi principali: un database PostgreSQL, il demone nipapd e l’interfaccia web nipap-www.
Attraverso l’anchor &common-security, viene applicata a tutti i container una configurazione di sicurezza comune che rimuove tutte le Linux capabilities (cap_drop: ALL) e abilita l’opzione no-new-privileges, impedendo l’acquisizione di privilegi aggiuntivi durante l’esecuzione.
Il servizio db utilizza un’immagine PostgreSQL con supporto all’estensione IP4R, necessaria per la gestione degli indirizzi IP, esegue un controllo di integrità e aggiunge esclusivamente le capability minime richieste dal database per la gestione del filesystem e degli utenti.
Il servizio nipapd, che rappresenta il backend applicativo, viene avviato solo dopo che il database risulta operativo e riceve tramite variabili d’ambiente tutti i parametri necessari per la connessione al database.
Infine, il servizio nipap-www fornisce l’interfaccia web dell’applicazione, esponendo la porta HTTP 80 dell’host.
Una volta completata la configurazione dei file, avviare lo stack Docker dalla directory /opt/nipap eseguendo il comando docker compose up -d.
Al termine della procedura, verificare che tutti i container siano in esecuzione mediante il comando docker ps.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
22b1c0dcfa77 nipap/nipap-www:latest "/nipap-www/entrypoi…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, [::]:80->80/tcp nipap-www
c86a4a423876 nipap/nipapd:latest "/nipap/entrypoint.sh" 2 minutes ago Up 2 minutes 1337/tcp nipapd
c1a483ad7546 nipap/postgres-ip4r:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes (healthy) 5432/tcp nipap-db
Se l’installazione è stata completata correttamente, l’interfaccia web di NIPAP sarà raggiungibile all’indirizzo https://ipam.home.lan, utilizzando le credenziali definite dalle variabili WWW_USER e WWW_PASSWORD.
Configurazione dei prefix in NIPAP
NIPAP organizza le reti in modo gerarchico, utilizzando tre tipologie di prefissi:
Reservation: rappresenta uno spazio di indirizzi riservato che può contenere altre subnetAssignment: identifica una subnet effettivamente assegnata a una rete o a una VLANHost: rappresenta un singolo indirizzo IP assegnato a un dispositivo
Ad esempio, nel nostro homelab in cui tutte le VLAN appartengono alla rete 10.0.0.0/8, è possibile organizzare la struttura come segue:
Reservation
└── 10.0.0.0/8
├── Assignment 10.0.5.0/24 (Management)
├── Assignment 10.0.10.0/24 (LAN)
├── Assignment 10.0.20.0/24 (WLAN)
└── ...
È proprio durante la creazione di nuovi prefissi che emerge la legnosità a cui accennavamo: non è possibile indicare direttamente il prefisso o l’indirizzo IP desiderato. NIPAP assegna automaticamente il primo prefisso o il primo indirizzo disponibile compatibile con il CIDR richiesto.
Ad esempio, se esiste la reservation 10.0.0.0/8 e si richiede la creazione di un nuovo Assignment /24, il sistema potrebbe proporre automaticamente 10.0.0.0/24 oppure il primo blocco libero disponibile all’interno della Reservation.
Se invece si desidera creare, ad esempio, la VLAN Management sulla subnet 10.0.5.0/24, sarà necessario:
- creare inizialmente l’assignment e lasciare quello proposto automaticamente da NIPAP
- modificare successivamente l’assignment assegnato, sostituendolo con 10.0.5.0/24
Lo stesso comportamento si applica agli host: viene sempre proposto il primo indirizzo IP disponibile e, se necessario, questo deve essere modificato manualmente, dopo il salvataggio, come mostrato nelle immagini seguenti:
Un altro difetto é che non risulta possibile, da web, impostare il range del DHCP.
Questo approccio può sembrare macchinoso durante la configurazione iniziale, soprattutto se si sta importando una rete già esistente. Una volta completata la fase di popolamento, tuttavia, il workflow diventa molto più naturale: per ogni nuova VM, server o dispositivo è sufficiente creare un nuovo host in NIPAP e lasciare che il sistema suggerisca il primo indirizzo libero, oppure modificare il valore proposto qualora sia necessario utilizzare un indirizzo specifico.
Al termine della configurazione, la struttura dei prefissi dovrebbe risultare simile alla seguente: