Operations¶
Service control¶
The RPM ships a systemd unit named pdns-pf-ipmapper.service, running as
the pdns-ipmapper user. Everyday commands:
# Status and recent logs
systemctl status pdns-pf-ipmapper
# Follow the log stream
journalctl -u pdns-pf-ipmapper -f
# Restart after a config change
systemctl reload-or-restart pdns-pf-ipmapper
The service does not watch its config file for changes; restart it after
editing ipmapper.yaml.
On startup the service loads all sessions from Redis before accepting
connections. During this load the ipmapper_ready_status metric reads 0;
it flips to 1 once the load finishes. The duration is reported in
ipmapper_redis_load_duration_seconds.
Config location¶
The default config path is /etc/pdns-pf/ipmapper.yaml. A commented
template with every option is shipped alongside it as
/etc/pdns-pf/ipmapper.example.yaml. See Configuration
for the full reference.
Command-line flags¶
| Flag | Default | Purpose |
|---|---|---|
-c, --config |
/etc/pdns-pf/ipmapper.yaml |
Path to the YAML config file. |
--debug |
false |
Enable debug logging. |
--no-redis |
false |
Disable Redis persistence entirely (state is lost on restart). |
--no-redisload |
false |
Skip loading state from Redis on startup; the service starts with an empty session table. |
--force-gc-interval |
0 (disabled) |
Force a full Go GC at this interval. Do not set below a few seconds — a forced GC sweep at high session counts causes visible CPU spikes. |
Observability¶
All live-inspection surfaces are served by the HTTP server bound to
http.address (see Configuration → http).
- Status page. HTML summary at
/showing active sessions, memory usage, Redis connection pool stats, and the readiness indicator. - Readiness probe.
/healthzreturns HTTP200once the instance is active and has loaded its state, and HTTP503while it is starting, waiting for the HA lock, or loading from Redis. The response body is a JSONgo-healthzstatus payload. On503responses, readiness messages appear underfailures["ipmapper-ready"]; for example, passive instances reportwaiting for redis lock. Use it as the backend health check for a load balancer or cluster controller (e.g. an HA proxy between the RADIUS Listener and the IP Mapper) so traffic only reaches the active instance. If the load balancer validates the response body, check a JSON field such asok: trueorstatus: "OK"instead of a bareOKbody. See Architecture → Monitoring availability with/healthz. - Prometheus metrics. Scraped at
/metrics. See Metrics for the full reference. - pprof. Go
net/http/pprofhandlers under/debug/pprof/for CPU, heap, goroutine, and block profiles.
The journal also receives a stats line every 30 seconds when Redis sync is enabled, including session count, Redis send/receive throughput, and heap size.
When the session API is enabled it is served
from this same listener under /api/v1/sessions. Protect that listener with
TLS — and ideally an auth_token or mTLS — before exposing the port beyond a
trusted network. Watch ipmapper_http_calls_unauthorized_total for rejected
requests and ipmapper_http_duration_seconds for latency
(see Metrics → Is the HTTP API healthy?).
Performance characteristics¶
Memory¶
The main cost is the in-memory session table. Set
options.initial_allocation to your expected
peak session count to avoid runtime map growth.
Preliminary sizing results for 10 million sessions under a single load with no fragmentation:
| Mode | Redis RAM usage | IP Mapper RAM usage | Session updates per second |
|---|---|---|---|
| Redis Script | 18 GB | n/a | 20 k |
| IP Mapper with OpaqueID maps | 7 GB | ~10 GB | 150 k |
| IP Mapper direct user mappings | 5 GB | ~10 GB | 180 k |
Treat these as lower-bound lab results. For production sizing, assume roughly double the RAM to account for fragmentation and operational headroom.
These figures exclude filter settings and device mappings. The IP Mapper internal state map accounts for about 2 GB of the Redis usage above and could be moved to a separate Redis instance.
The service sets Go's GOGC to 50 by default. This keeps peak heap
allocation at roughly 1.5× the live set rather than the Go default of 2×,
at the cost of more frequent GC sweeps. Override by setting GOGC in the
service environment file before starting the unit.
Redis sync pipeline¶
The internal pipeline is sized by the performance knobs
in the redis section. The defaults sustain several hundred thousand session
updates per second. Watch ipmapper_nats_duration_seconds and
ipmapper_resp_duration_seconds for signs that the pipeline is backing up.
Companion tool: pdns-pf-ipmapper-fill¶
The RPM ships pdns-pf-ipmapper-fill, a load-generation tool for benchmarking
or pre-seeding sessions via the RESP interface using the legacy Lua script
protocol.
| Flag | Default | Purpose |
|---|---|---|
-r |
127.0.0.1:6379 |
RESP listener address. |
-n |
1000 |
Number of sessions to create. |
-s |
../../redis-scripts/pdns-pf-redis-script.lua |
Path to the redis script used to format session updates. |
-L |
0 (unlimited) |
Rate limit in sessions per second. |
The tool generates synthetic IPv6 sessions using incrementing addresses in
the 2001:db8:beef::/48 range and sends them using the setSession legacy
Lua script interface.