Synchroniser automatiquement 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.
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) :
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.
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.