Om een beetje grip op de situatie te houden wil ik een wat beter overzicht van alle ip-adressen en DNS records creëren. Nog mooier zou het zijn om dit te automatiseren of synchroniseren met bijvoorbeeld Netbox, vCenter en Docker. Helaas heeft pfSense alleen geen API, of toch wel…?
Over tijd kan een homelab behoorlijk groeien. Hoewel het meeste totaal onbelangrijk is voor het gezin, heb je thuis zo een prio 1 te pakken als de favoriete (kinder)serie niet uit de TV komt. Mede om die reden probeer ik de belangrijkste dingen zo robust mogelijk te maken. Op die manier kan ik wanneer ik wil een docker host rebooten of iets om zeep helpen, zonder dat er iemand ongelukkig wordt.

Gelukkig is er wel een project op Github die hierin voorziet! Het project heet pfSense-pkg-RESTAPI en kan je handmatig installeren op je pfSense. Het werkt zowel op pfSense Plus als de Community Edition. Er is zeer uitgebreide documentatie beschikbaar incl. interactieve Swagger documentatie waarmee je direct kan testen.
Ik ga hier uiteraard niet vertellen hoe jij dit moet aanpakken, maar hopelijk kan jij ook iets zinvols met de API.
Hieronder in ieder geval een script die het mogelijk maakt om snel een export te maken van alle DHCP reserveringen bijvoorbeeld.
Onderstaande script (met hulp van de vlugge vingers van AI) haal de interface descriptions en de DHCP reserveringen op:
#!/usr/bin/env bash
# -----------------------------
# CONFIGURATION
# -----------------------------
PFSENSE_HOST="<ip>:<port>"
API_KEY="<api-key-with-correct-rights>"
# Optional: If using self-signed cert
CURL_OPTIONS="-k"
# -----------------------------
# Get Interfaces
# -----------------------------
interfaces_response=$(curl $CURL_OPTIONS -s -X "GET" \
"https://$PFSENSE_HOST/api/v2/interfaces" \
-H "accept: application/json" \
-H "x-api-key: $API_KEY")
# Validate JSON
if ! echo "$interfaces_response" | jq empty >/dev/null 2>&1; then
echo "Error: Interfaces response is not valid JSON"
exit 1
fi
interfaces_code=$(echo "$interfaces_response" | jq -r '.code')
if [[ "$interfaces_code" != "200" ]]; then
echo "Error: Interfaces API returned code $interfaces_code"
echo "$interfaces_response" | jq .
exit 1
fi
# Build id → description map (JSON object)
iface_map=$(echo "$interfaces_response" | jq '
.data | map({ (.id): .descr }) | add
')
# -----------------------------
# Get DHCP Static Mappings
# -----------------------------
dhcp_response=$(curl $CURL_OPTIONS -s -X "GET" \
"https://$PFSENSE_HOST/api/v2/services/dhcp_server/static_mappings" \
-H "accept: application/json" \
-H "x-api-key: $API_KEY")
if ! echo "$dhcp_response" | jq empty >/dev/null 2>&1; then
echo "Error: DHCP response is not valid JSON"
exit 1
fi
dhcp_code=$(echo "$dhcp_response" | jq -r '.code')
if [[ "$dhcp_code" != "200" ]]; then
echo "Error: DHCP API returned code $dhcp_code"
echo "$dhcp_response" | jq .
exit 1
fi
# -----------------------------
# Output Table
# -----------------------------
echo "Interface | MAC | IP | Hostname | Description"
echo "----------------------------------------------------------------------------"
echo "$dhcp_response" | jq -r \
--argjson iface_map "$iface_map" \ '
.data[] |
(
.parent_id as $pid |
($iface_map[$pid] // $pid)
) as $iface_descr |
"\($iface_descr) | \(.mac // "-") | \(.ipaddr // "-") | \(.hostname) | \(.descr // "-")"
'Voorwaarden: installeer de API, zet deze open voor de juiste interfaces/subnets en maak een API key voor een user die rechten alleen heeft op wat je wilt automatiseren (dit kunnen ook alleen-lezen rechten zijn).