UniFi client block
The unifi-response connector blocks the wireless client that currently
holds the target address on a UniFi Network controller (block-sta) and
unblocks it on release (unblock-sta). It is the second target of the same
executor as the firewall quarantine: the executor sees
one node named unifi, adds and removes memberships and reads them back, and
the Response page shows the same statuses. It is Pro (licence feature
response).
It is meant for a tenant that has no firewall pair — a wireless-only site behind a controller. One tenant can declare one response target, so it is this or the firewall, not both.
What it does on an approval
Section titled “What it does on an approval”- Checks the address against the policy: inside
allowed_targets, outside every protected scope (plus the controller host and the appliance’s own addresses, added implicitly). - Resolves the client’s MAC from the controller’s live active-client list
— never from a cache, because the address may belong to another client by
now, and blocking the wrong MAC is worse than refusing. No active client
holding the address, or a wired client, is refused
(
address_outside_scope): blocking a switch port through the client manager is a different blast radius — the port, not the device. - Posts
block-stafor that MAC, reads the blocked flag back from the known clients, and only then reports the membership as present. - Records the MAC, the address and the action id in the ownership ledger
in the appliance’s state store (
response_target_members, keyed by instance and MAC).
On release it posts unblock-sta only for a MAC in its ledger and reads
back that the client is no longer blocked. A block an operator placed by hand
on the controller is never lifted by Nyxtrace, and a restart neither turns own
blocks into foreign ones nor lifts a block it did not make. list_members
reports a foreign blocked client as foreign and an owned block the controller
no longer shows as absent, so the executor sees a block somebody lifted.
The command body is a fixed verb and a normalised MAC — nothing else of the request reaches the controller.
Set it up
Section titled “Set it up”1. An account that may block clients
Section titled “1. An account that may block clients”Settings → Admins → Add Admin, Local Access Only, restricted to the site. This account needs the right to block and unblock clients, which the read-only account of the source connector does not have — so it is a second account, not the dashboard admin and not a UI Cloud account. Give it the least role the controller offers that can block a client, and nothing above.
2. The certificate pin and the credentials
Section titled “2. The certificate pin and the credentials”The same pin as the source connector (tls_fingerprint_sha256, read with the
openssl s_client line on
the UniFi page),
and two secret files under /etc/ndr/secrets, following the
secret rules:
umask 077printf '%s' 'nyxtrace-response' > /etc/ndr/secrets/unifi-response-usernameprintf '%s' '<password>' > /etc/ndr/secrets/unifi-response-passwordchgrp nyxtrace /etc/ndr/secrets/unifi-response-*chmod 0640 /etc/ndr/secrets/unifi-response-*3. Declare the instance
Section titled “3. Declare the instance”connectors: - id: unifi-response instance: unifi-block tenant: example enabled: true config: url: https://controller.example.invalid:11443 site: default tls_fingerprint_sha256: "…" policy_revision: 1 allowed_targets: "198.51.100.0/24" protected_scopes: "198.51.100.0/28" ttl: 900s secrets: username: file:/etc/ndr/secrets/unifi-response-username password: file:/etc/ndr/secrets/unifi-response-passwordurl, site and tls_fingerprint_sha256 are the source connector’s. The
policy fields are the same set
as on the firewall target — policy_revision, allowed_targets and
protected_scopes required, ttl (default 900s), kill_switch,
auto_enabled, the thresholds, the limits and the calibration fields. There
is no kill_states and no alias: the controller drops the client’s
association itself. The automatic mode
applies to this target exactly as to the firewall pair — an identity proof of
dhcp_lease_and_mac or better is what the controller’s own client table
provides, through the unifi source connector.
4. Validate and test
Section titled “4. Validate and test”sudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true NDR_CONNECTORS_PATH=/etc/ndr/connectors.yaml \ ndr connectors validatesudo -u nyxtrace env NDR_CONNECTORS_ENABLED=true NDR_CONNECTORS_PATH=/etc/ndr/connectors.yaml \ ndr connectors test unifi-block --livetest --live logs in and lists the active clients; it blocks nothing. Restart
ndr-api and look for operation=response_worker … nodes=1 … started=true.
Without the licence feature the worker starts in mode=release_only.
5. The canary
Section titled “5. The canary”The same order as on the firewall: once with kill_switch: true to walk a
proposal through approve without touching the controller, then one
operator-owned wireless test client for ten minutes, Release, and a check on
the controller that the client is unblocked. Skip the “expiry with Nyxtrace
stopped” step — there is nothing on the controller that would expire it, which
is exactly the point of the caution above.
Release and expiry
Section titled “Release and expiry”Release on the Response page or POST /api/v1/response-actions/{id}/release
unblocks the MAC from the ledger and confirms by reading the blocked flag back;
the action becomes rolled_back when the controller no longer shows the client
as blocked, rolling_back with the reason otherwise, and the worker retries.
At the deadline the appliance releases on its own and ends the action as
expired. Release is never licence-gated.
If the appliance is down at the deadline the block stays until it is back or a person lifts it on the controller (Clients → the client → Unblock). If you lift it by hand, press Release afterwards so the ledger agrees.
Health and limits
Section titled “Health and limits”The instance is listed as connector:unifi-block on the
System page. Twenty requests a minute with a burst of
six, one command per request, health once an hour. Attempts on
GET /api/v1/response-actions/{id} carry the node label unifi, the
operation and the readback; the MAC is the membership id on the server side
and never leaves it.
Known limits
Section titled “Known limits”- Wireless clients only. A wired client is refused, on purpose.
- No fail-open. The controller has no expiry; the appliance’s release is the only automatic way back.
- The address must be held by an active client at the moment of approval; a client that has already roamed off is refused rather than guessed.
- Not exercised against a real controller by the project: tested against recorded controller exchanges only.
- Everything on the overview still applies: this is not endpoint access and not an IPS.