Skip to content

Operations

This page is the operator's reference for a running pdns-pf-simulator-server instance: how to control the service, how to watch it, which metrics to look at, and how to drive the REST API by hand when you need a verdict for one specific domain.

Service control

The RPM ships a systemd unit named pdns-pf-simulator-server.service, running as the pdns-simulator user. Everyday commands:

# Status and recent logs
systemctl status pdns-pf-simulator-server

# Follow the log stream
journalctl -u pdns-pf-simulator-server -f

# Restart after a config change
systemctl reload-or-restart pdns-pf-simulator-server

The service does not watch its config file for changes; restart it after editing /etc/pdns-pf/simulator-server.yaml. The same is true of the Lua entry-point file — workers load it once at startup, so any change to the filter engine needs a restart to take effect.

Config location

The shipped systemd unit points the service at /etc/pdns-pf/simulator-server.yaml. A heavily-commented template ships alongside it at /etc/pdns-pf/simulator-server.example.yaml.

See Configuration for the full reference.

Command-line flags

When running the service in the foreground for troubleshooting — for example under strace, or by hand out of the package's install path — these are all the flags it accepts:

Flag Default Purpose
--config, -c /etc/pdns-pf/simulator.yaml (binary default) Path to the YAML config file. The shipped systemd unit overrides this to /etc/pdns-pf/simulator-server.yaml, which is the path you should edit on a deployed box.
--debug false Force debug-level logging for this process. Overrides log.level. Verbose — use sparingly.
--test-and-exit false Fire one synthetic lookup_domain request for www.example.com and exit. Used by the package's smoke test. Exits non-zero if the request fails.
--version false Print the version string and exit.

Observability

The service exposes all of its live-inspection surfaces on the single webserver bound to http.address:

  • Status page. A small HTML page served at /. It echoes the last info payload returned by the Lua side and links to the metrics endpoint and the REST API.
  • Prometheus metrics. Scrape endpoint at /metrics. See the Metrics reference below.
  • pprof. Go net/http/pprof handlers under /debug/pprof/ for CPU, heap, goroutine and block profiles.
  • REST API. The four endpoints listed in REST API surface.

Logs go to standard error. Under the default systemd unit they are captured by the journal under the pdns-pf-simulator-server syslog identifier, so journalctl -u pdns-pf-simulator-server and journalctl -t pdns-pf-simulator-server both work.

REST API surface

All four endpoints return application/json. Three of them are subject to the api_keys check; /api/v1/info is not.

GET /api/v1/domain

Domain categorization lookup. Returns the OX Feed classification codes that apply to the given domain, without applying any subscriber context.

Query parameters:

Parameter Required Description
domain yes Domain name. IDNA-encoded by the server before lookup.
path no Optional path under the domain, used by feeds that classify by URL.
curl -s -H "X-API-Key: $KEY" \
    'https://simulator.internal:8671/api/v1/domain?domain=www.example.com'

GET|POST /api/v1/simulate

Full user simulation. Resolves the subscriber, applies their settings, and runs the filter pipeline end to end. Parameters can be sent as query string (GET) or application/x-www-form-urlencoded body (POST). At least one of ip, username, or deviceid is needed for the engine to resolve a subscriber.

This is also the endpoint used by proxy implementations that delegate live decisions to the simulator. In the current OpenResty proxy this happens when proxyremotebaseurl points at the simulator. In that mode proxy-side errors from this endpoint become proxy failures: HTTP requests return a backend error response, and TLS/SNI stream requests are closed.

Parameter Description
domain Domain name to check. IDNA-encoded by the server. Required.
path Optional path under the domain.
ip Client IP address. Used to look up the subscriber session.
username Subscriber username.
deviceid Hex-encoded device id.
profile Numeric device profile to use instead of the one derived from the subscriber.
settings JSON-encoded settings to override the subscriber's stored settings. Useful for "what would this user see if I changed setting X?" tests.
rules_ip IP to use for rules that key on a netblock. Only affects netblock-based list rules.
verbose Set to 1 to include detailed rule-evaluation logs in the response.
vhost Optional virtual host identifier passed through to the filter engine.
curl -s -H "X-API-Key: $KEY" \
    'https://simulator.internal:8671/api/v1/simulate?domain=www.example.com&ip=192.0.2.1&verbose=1'

GET /api/v1/codemappings

Dump of the OX Feed classification code → name table from the local LMDB. Returns 204 No Content when the OX Feed backend is not in use or its mappings are not yet loaded.

curl -s -H "X-API-Key: $KEY" \
    'https://simulator.internal:8671/api/v1/codemappings'

GET /api/v1/info

Returns the most recent info payload from the Lua side. Refreshed every maintenance tick (once per second). Useful as a liveness probe and to confirm which region the instance reports for.

Metrics reference

All metrics are exposed at /metrics on the http.address listener. The five simulator metrics share a pdns_pf_simulator_ prefix; the version metric uses the platform-wide pdns_platform_ prefix.

Metric Type Meaning
pdns_platform_version_info gauge Set to 1 with a version label carrying the running binary's version string. Useful for build provenance in dashboards.
pdns_pf_simulator_lua_workers gauge Number of Lua workers configured. Reflects lua.workers at startup and does not change at runtime.
pdns_pf_simulator_lua_worker_create_error_total counter vec Failures creating a Lua worker, labelled by the error message. Should always be zero — non-zero means a worker failed to load the Lua entry point, and the service exits.
pdns_pf_simulator_lua_call_total counter vec Lua calls made by the worker, labelled by call (lookup_domain, simulate_user, codemappings, maintenance, info).
pdns_pf_simulator_lua_call_error_total counter vec Lua calls that returned an error, labelled by call. The ratio against pdns_pf_simulator_lua_call_total is the error rate per request type.
pdns_pf_simulator_info gauge vec Set to 1 with a region label sourced from the Lua side's info response. Lets dashboards distinguish instances by region without scraping /api/v1/info.

A baseline operator dashboard typically tracks the request-rate and error-rate per call label, plus the version gauge.

Troubleshooting

  • Service exits at startup with a Lua error, and pdns_pf_simulator_lua_worker_create_error_total is non-zero on the last scrape: the lua.file path is wrong, the file is malformed, or a required Lua module from the pdns-pf-lua-dist package is missing. Confirm the path matches the one shipped by the pdns-pf-simulator RPM and that the dependency RPM is installed.
  • Requests hang or pile up, especially with a single worker: consider raising lua.workers, or look for a slow query (large verbose: 1 simulation) holding up the pool.
  • HTTP returns 401 for the simulate / domain / codemappings endpoints: the api_keys list is populated and the caller's key is missing or unknown.
  • NATS subjects are unreachable: the NATS goroutine only starts when nats.itsy.url or NATS_URL is set. Check the startup log for NATS enabled — its absence means the service is HTTP-only.