Captive portal
The captive portal intercepts unknown devices and sends them to a branded web page where the user registers, authenticates, or accepts a policy. Once the visitor completes a flow, Taranac places the device’s endpoint into a target group and issues a Change-of-Authorization (CoA) so your NAC policy re-evaluates it and grants the correct VLAN or ACL — all without the user touching their network settings.
A single portal can offer several flows (Guest, BYOD, Self-Registration, AUP) on one landing page, and you can run as many portals as you like — one per site, building, or audience — and place them anywhere across your network. Each runs either embedded in the Taranac stack or standalone in a branch DMZ, where it is fully self-sufficient: it serves its own DHCP and DNS, wraps stray traffic onto itself (DNS intercept answers every name with the portal’s IP), and proxies registration back to the central Taranac.
How redirect works
Section titled “How redirect works”Taranac cannot tell a guest laptop from a contractor’s phone before it registers — there is nothing to match on. So the policy treats all unknown devices the same way: it sends them to a holding VLAN (the Registration VLAN) and points them at the captive portal. The differentiation happens at the portal: the user picks a flow, registers, and only then does the device land in a specific endpoint group that your policy can match.
Unknown device → MAB → Policy "Unknown → Captive Portal" → Registration VLAN → portal landing page: [ Guest ] [ BYOD ] [ Accept Policy ] → user completes a flow → endpoint joined to target group → CoA re-auth → policy matches the group → correct VLAN / ACLTwo redirect mechanisms exist, and a portal can use either or both (redirect_mode):
| Mode | How the device reaches the portal | When to use |
|---|---|---|
url_redirect | The authorization profile returns a Cisco-style url-redirect (+ redirect ACL) pointing at the portal | Switches/WLCs that support URL redirection (Cisco, and similar) |
vlan_intercept | The device is dropped in the Registration VLAN; the portal’s DNS answers every name with its own IP, so any web request lands on the portal | Vendor-agnostic; works on any switch that can assign a VLAN |
both | Tries URL redirect; falls back to VLAN intercept | Default — safest across mixed hardware |
Key concepts
Section titled “Key concepts”- Portal — one configuration with a unique slug that defines its URL path (
/portal/{slug}), branding, security, and a set of flows. One portal can be marked default: it catches VLAN-intercept traffic that has no slug of its own. - Flow — a registration scenario inside a portal:
guest,byod,self_registration, oraup. Each flow type may appear at most once per portal and has its own settings and target endpoint group. - Target endpoint group — the group the device’s endpoint is joined to when the flow completes. Your NAC policy matches on this group to grant access.
- Guest session — the record of a completed (or pending) registration: who registered, the device MAC, verification/sponsor state, and when access expires. Drives expiry and revocation.
- Holding (Registration) VLAN — the quarantine VLAN unknown devices sit in until they finish a flow. In standalone mode the portal can serve DHCP and DNS for this VLAN itself.
Configuring a portal
Section titled “Configuring a portal”Open NAC → Endpoints → Captive Portals. The page lists every portal with its slug, deployment mode, enabled-flow count, active sessions, and (for standalone) instance health. Use New portal to create one.
The Captive Portals page: the nginx Configuration panel (embedded portals) sits above the portal table.
The portal editor is a drawer with tabs:
General
Section titled “General”| Field | Notes |
|---|---|
| Name | Display name. |
| Slug | URL segment /portal/{slug}. Auto-generated from the name on create; editable. |
| Enabled | Turns serving of the portal on or off. |
| Default | Embedded portals only. The fallback portal for VLAN intercept without a slug — only one portal may be default. |
| Deployment mode | Embedded or Standalone (DMZ). |
| Redirect mode | both / url_redirect / vlan_intercept (see table above). |
| Backend API URL | Standalone only — URL of the main Taranac API the container calls back to. |
| Portal URL | Public URL used for URL-redirect targets and email verification links. |
| Default flow | landing shows all enabled flows; or open directly into guest / byod / aup / self_registration. With a single enabled flow, the landing page is skipped automatically. |
| Source networks | Embedded only — CIDR subnets, one per line, used to route VLAN-intercept traffic to this portal’s slug. |
| Redirect after URL | Where to send the user after success, instead of showing the success page. |
Add one card per flow. Each card has a display name, an icon, a sort order, an enable toggle, and an optional target endpoint group (picked from your endpoint groups). The rest of the card is the flow-specific settings — see Flows in detail.
Appearance
Section titled “Appearance”Logo (uploaded as a data URI), brand name, primary and background colours, welcome text, and success text. A live Preview tab renders the landing page from your current settings without any API call.
Security
Section titled “Security”Applied portal-wide, not per flow:
| Field | Default | Notes |
|---|---|---|
| Captcha | on | ALTCHA challenge — self-hosted proof-of-work, no third-party service and no user interaction. Applies to guest, self-registration and BYOD flows. |
| Honeypot | on | A hidden decoy field; submissions that fill it are rejected silently. |
| Rate limit per IP | 5/hour | Maximum registration attempts from one IP per hour. |
| Allowed email domains | — | Whitelist, one domain per line. Empty = allow any. |
| Blocked email domains | — | Blacklist, one domain per line. |
Deployment
Section titled “Deployment”Shown only when editing a standalone portal. See Standalone portals.
Flows in detail
Section titled “Flows in detail”Temporary access for visitors. The guest fills a form (name, email, and optionally phone, company, reason) and gets access either immediately or after sponsor approval.
| Setting | Values | Notes |
|---|---|---|
| Access mode | self_service / sponsor_required | Self-service grants access on completion; sponsor-required holds the session until an employee approves. |
| Verification method | none / email / sms / email_or_sms | Sends a one-time code; the guest must enter it before access is granted. |
| Code TTL | 10 min | How long the verification code stays valid. |
| Registration fields | per field: required / optional / hidden | Name, Email, Phone, Company, Reason for visit. |
| Session duration | 24 h | 0 = no expiration. |
| Max devices per guest | 1 | |
| Terms | optional | Show a terms text that must be accepted. |
| Sponsor mode | guest_choice / fixed | When sponsor-required: the guest types a sponsor’s email, or you pin a fixed sponsor user. |
With sponsor approval, the guest’s session sits in pending; the sponsor receives an email (and sees the request under Sponsor → Pending) and clicks approve or reject. On approval the device is placed in the target group and a CoA re-auth is fired. If a verification step is configured, the sponsor is notified only after the guest verifies.
A known corporate user registers a personal device. The user enters their corporate credentials (and accepts terms); Taranac authenticates them, binds the device’s MAC to their account, and grants access.
| Setting | Values | Notes |
|---|---|---|
| Auth method | both / local / ldap | Which identity source is accepted. The source is checked before the password, so a wrong-source login is rejected without revealing whether the credentials were valid. |
| Require MFA | off | Portal-level MFA, independent of any group MFA policy. Users without an MFA provider are prompted to set one up. |
| Access mode | permanent / time_limited | Permanent binds the device indefinitely (no guest session created). Time-limited creates a session that expires. |
| Session duration | 24 h | Used for time_limited; 0 = no expiry. |
| Max devices per user | 3 | |
| Terms | required by default |
The user must already exist in Taranac — the portal registers devices, it does not create accounts. An expired or must-change password is rejected with a “change your password in the main portal” message. A device whose endpoint is blocked is refused through every flow.
Self-registration
Section titled “Self-registration”Visitors create a persistent user account. Verification is mandatory (no none option). If the verified email matches an auto-approve domain the account is activated immediately; otherwise it is created as pending_approval and an admin must activate it.
| Setting | Values | Notes |
|---|---|---|
| Verification method | email / sms / email_or_sms | Always required. |
| Code TTL | 10 min | |
| Registration fields | required / optional / hidden | Same five fields as Guest. |
| Session duration | 24 h | 0 = no expiry. |
| Terms | optional |
AUP (Acceptable Use Policy)
Section titled “AUP (Acceptable Use Policy)”The lightest flow: show a policy, optionally require an “I agree” checkbox, grant access. No credentials, no registration form.
| Setting | Default | Notes |
|---|---|---|
| Require checkbox | on | User must tick “I agree” to proceed. |
| Session duration (minutes) | 480 (8 h) | 0 = no expiration. |
| Terms text | template | Rich-text policy; ships with a ready-made Permitted Use / Prohibited Activities / Monitoring template. |
On accept, Taranac stamps the endpoint’s AUP acceptance, joins it to the target group, and fires a CoA. If an active AUP session already exists for the device’s MAC, the existing one is reused rather than creating a duplicate.
When to use which flow
Section titled “When to use which flow”| You want to… | Use |
|---|---|
| Let visitors self-serve temporary access with optional email/SMS verification | Guest (self-service) |
| Require an employee to vouch for each visitor | Guest (sponsor-required) |
| Let staff enrol their own phones/laptops against their existing account | BYOD |
| Let people create lasting accounts, gated by email domain | Self-registration |
| Just make everyone accept a usage policy before getting on the network | AUP |
How a registration becomes access
Section titled “How a registration becomes access”For every flow the mechanics are the same once the user finishes:
- Find the MAC. The backend looks up the active NAC session by the client’s IP (taken from
X-Forwarded-For/X-Real-IP) to learn the device MAC. The endpoint was already created during MAB. - Place the endpoint in the flow’s target endpoint group (creating the endpoint if needed; a blocked endpoint is refused here).
- Trigger CoA. Taranac sends a CoA re-authentication for that MAC so the switch/WLC re-runs authorization. Your policy now matches the new group membership and applies the right VLAN/ACL.
When a session expires or is revoked, the reverse happens: the endpoint is removed from the flow’s target group and a CoA disconnect is issued, dropping the device back to the holding VLAN.
Managing guest sessions
Section titled “Managing guest sessions”NAC → Endpoints → Guest Sessions lists every registration with status, flow type, identity (name/MAC/IP, adapted to the flow), MAC, IP, created and expiry times. The page auto-refreshes. From a row you can:
- Extend — push the expiry out by a number of hours.
- Revoke — end access immediately (issues a CoA disconnect).
- Open the detail drawer for full guest, verification, sponsor and endpoint information.
Background jobs keep sessions tidy: expired and timed-out (sponsor- or verification-waiting) sessions are reaped every few minutes, and old expired/revoked records are deleted after the retention window (nac.guest_session_retention_days, default 90 days).
Standalone portals
Section titled “Standalone portals”For a branch with no reliable path back into the core, deploy the portal as a separate Docker container in the site DMZ. It serves the portal UI, optionally provides DHCP and DNS for the Registration VLAN, and proxies the guest API back to the main Taranac backend authenticated by an API token (X-Portal-Token).
The Deployment tab (edit mode, standalone only) gives you:
- Server certificate — pick a TLS certificate from NAC PKI to back the portal’s nginx. Choose the issuing CA, then a certificate; CSR-issued certs with no private key are disabled. Without one, the container generates an untrusted self-signed cert at startup.
- Network (DHCP / DNS) — independent toggles. DHCP serves addresses on the chosen interface; the lease is fixed at 30 seconds so a device quickly re-requests an address once it moves out of the Registration VLAN. DNS intercept answers every query with the portal’s IP so any web request triggers the portal.
- API token — generate the bearer token the container uses to call home. It is shown once; copy it immediately.
- Standalone bundle — download
captive-portal-{slug}.tar.gzcontainingdocker-compose.yml, the generated nginx config, and a deploy README. - Portal instances — the heartbeat registry: each running container reports name, IP, health (online / degraded / offline) and last-seen. Health rolls up to the portal badge in the list.
For embedded portals, the nginx Configuration panel on the Portals page manages the generated nginx config: Preview the deployed vs pending config, then Apply (or Force Apply) to write it and hot-reload nginx. The panel flags “changes pending” whenever a portal edit hasn’t been applied yet.
Reference: portal status flow
Section titled “Reference: portal status flow”register (with verification) → pending_verificationregister (no verification) → pending (sponsor required) → active (self-service)verify code OK → pending (then awaits sponsor) | activesponsor approve / reject → active | rejectedAUP accept → active (immediate)expiry / timeout (worker) → expiredadmin or sponsor revoke → revokedRelated
Section titled “Related”- NAC policy — match on the target group the portal assigns
- Endpoints and endpoint groups — where registered devices land
- NAC PKI — TLS certificates for standalone portals
- Network devices — CoA depends on the device’s shared secret
- Deployment bundle & architecture: github.com/TaranacLabs/taranac