Controller Integration
Wiring a physical WiFi controller, AP, or NAS into Kiwire is two separate integrations that both have to be done: an HTTP redirect that sends the guest's browser to the Kiwire captive portal, and a RADIUS connection that the controller uses to actually authenticate and account for the session. This page walks through both, using the Controller Login Config module (Systems › Login Config) as the glue between the two.
Every controller vendor names its redirect parameters differently. Kiwire never assumes a parameter name — the Login Config's Param Mapping tells Kiwire which query key on the incoming request corresponds to each field (MAC, IP, destination URL, etc). Get this mapping wrong and the portal cannot identify who is logging in.
The Two Integration Points
| Integration | Direction | Purpose |
|---|---|---|
| Captive portal redirect (HTTP) | Controller → guest's browser → Kiwire | Shows the login page. The controller's walled-garden / splash-page setting must point at Kiwire's /login/{device_type} endpoint. |
| RADIUS (auth + accounting) | Controller ↔ Kiwire RADIUS server | Actually authorizes network access and reports session usage. Configured on the Device Controller record, independent of the redirect. |
Both must be configured on the physical hardware — a correct redirect with no RADIUS pointing will show the login page but never grant network access, and RADIUS with no redirect means the guest never sees a login page at all.
Step 1 — Register the Device Controller
Before wiring up the redirect, register the AP/controller as a Device Controller in Kiwire (Device Management › Device Controllers). You'll need its management IP address and a RADIUS shared secret — both must match exactly what you configure on the physical hardware's RADIUS client settings. See the Device Controllers page for the full field reference and RADIUS notes.
Step 2 — Create a Login Config Entry
Each controller type (not each physical device — one entry covers every AP of that vendor/firmware across all your sites) needs a Login Config entry at Systems › Login Config. This is what turns an arbitrary vendor redirect into something Kiwire understands.
| Field | Description |
|---|---|
slug | The URL segment used in the redirect — becomes {device_type} in /login/{device_type}. Lowercase, hyphenated (e.g. mikrotik, ruckus_ap, cisco_wlc). |
vendor | Cosmetic label shown in the grid — pick from the configured vendor list or leave blank. |
status | active — the redirect endpoint accepts requests for this slug; inactive — requests to this slug 404. |
| Param Mapping | One request-query-key per standard field (see below). This is the actual integration work — everything else is bookkeeping. |
| Custom Params (JSON) | Any extra vendor-specific keys you want captured that don't fit the standard fields — see Custom Parameters below. |
Standard Parameters
These are the fields Kiwire's captive portal understands natively. For each one, the Param Mapping tells Kiwire which query string key the controller actually sends it as — you get this from the AP vendor's splash-page documentation, or by capturing a real hit (see Discovering Parameters below).
| Field | What Kiwire uses it for |
|---|---|
mac | The guest device's MAC address — the primary identity key for the session, MAC-bound access, and auto-login. |
ip | The guest device's client IP address on the AP's LAN/VLAN. |
destination | The URL the guest was originally trying to reach — used for post-login redirect ("continue to the site you wanted"). |
controller_ip | The controller/NAS's own IP address, as reported in the redirect (distinct from the socket IP RADIUS sees it from). |
login_url | The vendor's own "submit login here" callback URL, if the redirect scheme requires posting back to the controller after authentication (e.g. Mikrotik's link-login-only). Kiwire strips any query string appended to this value. |
controller_id | The NAS identifier (often called gw_id, ap_mac, or nasid) — must match the unique_id/NAS-ID on the registered Device Controller so Kiwire can resolve which tenant and zone this hit belongs to. |
vlan | VLAN ID the guest is on, if the controller reports it. |
ssid | SSID the guest associated to. |
zone | Explicit zone override, if the controller can pass one (most vendors can't — zone is usually resolved from the device/NAS instead). |
error | An error code the controller passes back (e.g. a previous authentication failure), surfaced to the login page. |
Only map the fields your controller actually sends. An unmapped field simply resolves to empty — you don't need every row filled in for the portal to work, but mac, ip, controller_id, and login_url are the ones that matter most for a working handshake.
Step 3 — Point the Controller's Redirect at Kiwire
On the physical AP/controller, find the setting usually called External Captive Portal, Splash Page URL, Walled Garden Redirect, or UAM Server (naming varies by vendor) and set it to:
https://{domain}/login/{device_type}
{domain}— the public hostname of your Kiwire installation (the same domain that serves the admin panel), e.g.captive.yourcompany.com.{device_type}— theslugyou set in Step 2, e.g.mikrotikorruckus_ap.
Most controllers append their own query string to this base URL automatically — you don't build the query string by hand. A real hit from a Mikrotik hotspot, for example, might arrive as:
https://captive.yourcompany.com/login/mikrotik?mac=00:11:22:33:44:55&ip=192.168.88.10&link-login=https%3A%2F%2F192.168.88.1%2Flogin&link-orig=http%3A%2F%2Fexample.com
With a Param Mapping of mac → mac, ip → ip, login_url → link-login, destination → link-orig, Kiwire correctly picks up all four fields from that request.
public/assets/img/docs/controller-integration/param-mapping.png
Custom Parameters
If a controller sends additional vendor-specific fields you want recorded (but that don't map to any standard field above), add them in the Login Config's Custom Params box as JSON, e.g.:
{
"ap_name": "ap_name",
"site_id": "wlan_site"
}
The key is the label you want to store it under; the value is the request query key the controller actually sends.
Pointing RADIUS at Kiwire
Separately from the redirect, the controller must send RADIUS Access-Request and accounting packets to Kiwire's RADIUS server for the session to actually be authorized:
- Set the controller's RADIUS authentication server and accounting server to Kiwire's RADIUS host, ports 1812 (auth) and 1813 (accounting).
- Set the shared secret to exactly match the
secretfield on the Device Controller record created in Step 1 — case-sensitive, must match on both sides. - Ensure the controller's management IP (the one sending RADIUS packets) matches the
ip_addresson the Device Controller record — this is Kiwire'sNAS-IP-Addressmatch.
Full field reference, vendor-specific RADIUS attribute notes, and the Test Connection tool are covered on the Device Controllers page.
The redirect and RADIUS integrations are independent — Kiwire has no way to tell you the redirect is misconfigured from the RADIUS side, or vice versa. If guests reach the login page but never get online (or get online but see a blank/broken login page), check whichever half you haven't verified yet.
Discovering Parameters From a Real Controller
If the vendor's documentation doesn't clearly state its redirect parameter names — or you want to confirm what a specific firmware version actually sends — use Monitoring › Controller Test:
- Open Monitoring › Controller Test and click Start to open a capture window.
- Point a test device at the controller so it triggers the captive-portal redirect (or manually hit the redirect URL from a browser on the same network).
- The page shows the raw incoming request — every query parameter the controller actually sent, plus a pass/fail checklist for
mac,ip,controller_id(NAS ID), andlogin_urlagainst whatever Login Config is currently mapped for that slug. - Use the raw parameter names shown to fill in (or correct) the Param Mapping in Step 2.
This is also the fastest way to confirm a Login Config change actually took effect, without needing physical access to the AP.
Special Cases
WiFiDog Protocol (Ruijie Reyee)
Ruijie gateways running in WiFiDog mode don't hit /login/{device_type} directly — the gateway owns the literal path segment /login/ as part of its own protocol, so it's handled by a dedicated shim at /wifidog/ruijie/login, which renames the WiFiDog parameters and forwards internally to the standard ruijie-reyee Login Config. If you're integrating a Ruijie AP in WiFiDog/MCFi mode, point it at the /wifidog/ruijie base path (per Ruijie's own configuration UI) rather than constructing a /login/ URL by hand — no separate Login Config entry is needed for this mode.
Vendors That Require a "Login URL" Callback
Some controllers (Mikrotik hotspot, ChilliSpot/CoovaChilli-style UAM) expect the portal to eventually redirect the guest's browser back to a controller-hosted URL to actually flip the connection to authorized — this is the login_url field. Make sure it's mapped for any vendor that works this way; without it, the login page will accept credentials but the guest will never actually get network access.
Integration Checklist
- Device Controller registered with correct
ip_addressand RADIUSsecret - Login Config created with a unique
slugand statusactive - Param Mapping filled in for at least
mac,ip,controller_id, and (if applicable)login_url/destination - Controller's splash-page / external captive portal setting points to
https://{domain}/login/{slug} - Controller's RADIUS auth (1812) and accounting (1813) servers point to Kiwire, with matching shared secret
- Verified end-to-end with Monitoring › Controller Test and the Device Controller's Test Connection action
Login Config entries are shared across all tenants — the same slug serves any tenant, with the specific NAS/tenant resolved from the controller_id (NAS ID) at request time. You don't create a separate Login Config per tenant for the same controller vendor.