Synchroniser automatiquement les ports switch dans phpIPAM

Synchroniser les ports switch dans phpIPAM

phpIPAM documente bien les adresses IP, mais pas nativement sur quel port physique de quel switch se trouve chaque équipement — une information qui se périme vite si elle n'est tenue qu'à la main dans un tableur à part. En s'appuyant sur la supervision SNMP déjà en place, un petit script peut interroger les switchs et tenir cette cartographie à jour tout seul.

1. Le principe

Chaque switch manageable expose, via SNMP, une table d'adresses MAC par port (BRIDGE-MIB, OID dot1dTpFdbTable) : pour chaque adresse MAC vue sur le switch, l'OID indique sur quel port elle a été apprise. En croisant cette table avec les enregistrements IP déjà connus dans phpIPAM (qui, lui, connaît l'association IP ↔ MAC via ses scans réseau), un script peut déduire "cette IP est sur le port 14 du switch X" et pousser l'information dans un champ personnalisé phpIPAM.

Pré-requis côté phpIPAM : créer un champ personnalisé (Administration → Custom Fields → ipaddresses) nommé par exemple switch_port, qui accueillera la valeur "nom du switch / numéro de port" pour chaque IP.

2. Le script

Exemple simplifié en Python, à adapter à votre environnement (bibliothèque SNMP, format d'authentification phpIPAM) :

sync_ports.py
import requests
from pysnmp.hlapi import *

# --- Configuration ---
SWITCHES = [
    {"name": "switch-access-1", "ip": "192.0.2.10", "community": "ro-community"},
    {"name": "switch-access-2", "ip": "192.0.2.11", "community": "ro-community"},
]
PHPIPAM_URL = "https://ipam.exemple.local/api/app_id"
PHPIPAM_TOKEN = "jeton_api_phpipam"

def get_mac_port_table(switch):
    # Interroge dot1dTpFdbTable (adresse MAC -> port) via SNMP walk
    result = {}
    for (errInd, errStat, errIdx, varBinds) in nextCmd(
        SnmpEngine(), CommunityData(switch["community"]),
        UdpTransportTarget((switch["ip"], 161)), ContextData(),
        ObjectType(ObjectIdentity("1.3.6.1.2.1.17.4.3.1.2")),
        lexicographicMode=False):
        for varBind in varBinds:
            mac, port = parse_fdb_entry(varBind)  # conversion OID -> MAC + port
            result[mac] = port
    return result

def update_phpipam(ip_address, mac, switch_name, port):
    # Recherche l'entrée IP correspondante dans phpIPAM par adresse
    resp = requests.get(f"{PHPIPAM_URL}/addresses/search/{ip_address}/",
                         headers={"token": PHPIPAM_TOKEN})
    if resp.ok and resp.json().get("data"):
        addr_id = resp.json()["data"][0]["id"]
        requests.patch(f"{PHPIPAM_URL}/addresses/{addr_id}/",
                        headers={"token": PHPIPAM_TOKEN},
                        data={"custom_switch_port": f"{switch_name}/{port}"})

# --- Boucle principale : un switch à la fois, mise à jour incrémentale ---
for switch in SWITCHES:
    mac_table = get_mac_port_table(switch)
    for mac, port in mac_table.items():
        ip = lookup_ip_by_mac(mac)  # via l'API phpIPAM ou une table ARP locale
        if ip:
            update_phpipam(ip, mac, switch["name"], port)

3. Planifier l'exécution

Une exécution nocturne (cron) suffit largement pour ce type de données, qui ne change pas à la minute près. Le script écrase silencieusement les valeurs précédentes — pas besoin de logique de diff complexe, la table SNMP fait foi à chaque passage.

Limites à connaître : la table d'adresses MAC d'un switch expire les entrées inactives au bout de quelques minutes — un poste éteint au moment du scan n'apparaîtra pas. Les ports en agrégat LACP/trunk (plusieurs liens physiques logiquement fusionnés) peuvent aussi rendre l'association port/IP ambiguë selon le switch. Pour ces cas, une correction manuelle ponctuelle reste plus fiable qu'une automatisation complète.
L'objectif n'est pas une cartographie parfaite à la seconde près, mais de ne plus jamais avoir à deviner sur quel port débrancher quand un tableur externe n'a pas été mis à jour depuis six mois.

Conclusion

En réutilisant l'accès SNMP déjà en place pour la supervision réseau, ce script referme la boucle entre "quelle IP" et "quel port physique" sans double saisie manuelle. C'est un gain de temps net dès qu'il faut intervenir en urgence sur un port précis sans avoir à suivre chaque câble à la main. Si vous voulez être accompagné sur l'automatisation de votre documentation réseau, n'hésitez pas à me contacter.

R
Raph — Chronoassistance25 ans d'expérience en informatique, cybersécurité et infrastructure.