Back to blog

MikroTik / RouterOS  ·  Tutorial  ·  September 2026

Hotspot & Captive Portal
for Hotels

The branded "accept the terms and connect" page every guest expects — and every hotel owner asks us for. This is the MikroTik hotspot done properly: a login page you can put a logo on, voucher codes at reception, optional RADIUS, a walled garden so the login itself always loads, per-guest bandwidth, and the HTTPS-redirect reality nobody warns you about.

RouterOS Hotspot Captive Portal Hospitality Vouchers User Manager RADIUS

Guest joins Wi-Fi Hotspot gateway intercepts HTTP → login page Internet any web request after login Until the guest authenticates, every request is redirected to the portal. The walled garden is the short list of things allowed through it.

A captive portal is a small, well-worn trick: the router runs a tiny web server, and until a device authenticates, every HTTP request it makes is redirected to the login page. Accept the terms (or enter a voucher), the router flips that device's MAC to "authorised," and traffic flows normally. Phones recognise the pattern and pop the page automatically — that's the "Sign in to Wi-Fi" sheet every guest has seen.

On MikroTik this is the hotspot feature, and it's genuinely good — a five-minute wizard gets you a working portal, and the login page is just editable HTML you can brand. This post takes it from that wizard to something you'd actually hand a hotel: a terms-acceptance page, voucher codes printed at reception via User Manager, an optional RADIUS backend, the walled garden that keeps the portal itself reachable, and per-guest speed limits. It's the guest-facing front door to the segmented network from the hotel lab.

Prerequisites

01

Stand Up the Hotspot

The setup command wires the whole thing — an IP pool, DHCP, a NAT rule, the portal server, and a default profile — onto one interface. Run it on the guest interface, never the WAN.

RouterOS — the guided setup, then verify
# Point it at the guest interface (a VLAN interface or a guest bridge).
# The wizard asks a handful of questions — accept the sensible defaults.
[admin@GW] > /ip hotspot setup
hotspot interface: vlan20-guest
local address of network: 10.10.20.1/24   (auto)
masquerade network: yes
address pool: 10.10.20.10-10.10.20.254
select certificate: none
ip address of smtp server: 0.0.0.0
dns servers: 10.10.20.1
dns name: wifi.hotel.local
name of local user: (skip — we use vouchers)

# What it created, in one place:
[admin@GW] > /ip hotspot print
 0  name="hotspot1" interface=vlan20-guest address-pool=hs-pool-guest
    profile=hsprof1 idle-timeout=5m keepalive-timeout=none
⚠ Gotcha — The DNS Name Is Not Optional, and Keep It .local-ish

The dns name (here wifi.hotel.local) is the hostname the portal answers on — guests are redirected to http://wifi.hotel.local/login. Pick something that clearly isn't a real public domain, and never use your actual website's name (the portal would shadow it for every connected guest). It also must resolve only inside the hotspot — the wizard's built-in DNS handles that. If you later add HTTPS to the portal, this name must match the certificate (see the HTTPS gotcha in section 06).

02

The Login Page — Terms Acceptance

The simplest hotel portal isn't a username box — it's a logo, a "I accept the terms" checkbox, and a Connect button. That's a two-line change to the login profile plus a branded HTML file.

RouterOS — a login profile that only needs consent
# "trial" login lets a guest on for a set time with no credentials —
# perfect for accept-and-connect. Give everyone the same shared voucher-free access.
[admin@GW] > /ip hotspot user profile set [find name=default] \
    shared-users=1 rate-limit=10M/40M session-timeout=1d idle-timeout=15m
[admin@GW] > /ip hotspot profile set [find name=hsprof1] \
    login-by=cookie,http-chap trial-uptime-limit=1d trial-uptime-reset=1d
# cookie login remembers a returning guest's device for the day so they
# don't re-accept on every reconnect (the MAC-cookie in section 06).

The portal's HTML lives on the router's flash, in the hotspot/ directory — login.html, alogin.html (the "you're connected" page), logout.html, and a few includes. Pull them off with WinBox's Files browser or SFTP, edit them, and drop them back. For an accept-and-connect page you keep MikroTik's login form but replace the username/password inputs with a single checkbox and a hidden trial submit:

login.html — the essential terms-acceptance form (excerpt)
<img src="logo.png" alt="Hotel">
<h1>Welcome — free guest Wi-Fi</h1>

<form name="login" action="$(link-login-only)" method="post">
  <input type="hidden" name="dst" value="$(link-orig)">
  <input type="hidden" name="popup" value="true">

  <label><input type="checkbox" required>
    I accept the <a href="/terms.html">terms of use</a></label>

  <!-- "trial" hands out the free timed session; no username needed -->
  <input type="submit" name="" value="Connect">
</form>

<!-- MikroTik replaces $(...) macros server-side before serving the page -->
💡 Keep Assets Local — the Login Page Loads Before the Internet Does

The guest isn't online yet when they see this page, so every asset it references must be on the router: the logo, CSS, fonts, any image. Link a Google Font or a CDN logo and it renders broken, because the guest can't reach the internet until after they submit. Put logo.png and a small style.css in the same hotspot/ folder and reference them relatively. This is the single most common reason a "custom portal" looks broken on the guest's phone.

03

Voucher Codes with User Manager

When "free for everyone" isn't the model — paid Wi-Fi, per-room codes, a code printed on the checkout receipt — you need vouchers. User Manager is MikroTik's built-in RADIUS server that generates and tracks them.

RouterOS 7 — enable User Manager, point the hotspot at it
# RouterOS 7 ships User Manager v5 as a package — enable it once.
[admin@GW] > /user-manager set enabled=yes

# Register the router itself as a RADIUS client of its own User Manager
[admin@GW] > /user-manager router add name=local address=127.0.0.1 shared-secret=hotspot-secret

# Tell the hotspot to authenticate against RADIUS instead of local users
[admin@GW] > /ip hotspot profile set [find name=hsprof1] use-radius=yes
[admin@GW] > /radius add service=hotspot address=127.0.0.1 secret=hotspot-secret

# A profile that shapes every voucher user, then a batch of 50 codes
[admin@GW] > /user-manager profile add name=guest-1day validity=1d
[admin@GW] > /user-manager user create-and-activate-profile=guest-1day \
    count=50 name-length=6 shared-users=1

# Print the batch to hand to reception:
[admin@GW] > /user-manager user print where profile=guest-1day
 #  NAME    PASSWORD   PROFILE
 0  a7f3k9  a7f3k9     guest-1day
 1  m2x8qp  m2x8qp     guest-1day
 …
⚠ Gotcha — "Validity" Starts on First Login, Not on Creation

A common panic: "I made 50 one-day codes last month, are they all expired?" No — with User Manager v5, a voucher's validity countdown begins the moment it's first used, not when it's generated. So a stack of unused codes at reception stays good indefinitely; only handed-out ones burn down. Confirm the intended behaviour with a test code before a busy weekend — the difference between "validity" and "session-timeout" trips up everyone the first time, and getting it wrong means either codes that die on the shelf or codes that never expire.

04

The Walled Garden

Some traffic must pass before login: the portal's own assets, a payment provider if you sell access, captive-portal detection URLs so phones auto-pop the page. That allow-list is the walled garden.

RouterOS — let the essentials through the portal
# Payment gateway (if guests pay by card for access)
[admin@GW] > /ip hotspot walled-garden add dst-host=*.stripe.com action=allow

# Captive-portal detection endpoints — so iOS/Android reliably auto-open
# the login sheet instead of silently deciding "no internet"
[admin@GW] > /ip hotspot walled-garden add dst-host=captive.apple.com action=allow
[admin@GW] > /ip hotspot walled-garden add dst-host=connectivitycheck.gstatic.com action=allow
[admin@GW] > /ip hotspot walled-garden add dst-host=www.msftconnecttest.com action=allow

# For raw IPs / non-HTTP, use the IP walled garden instead
[admin@GW] > /ip hotspot walled-garden ip add dst-address=1.1.1.1 action=accept
💡 Don't Over-Open the Garden

Every walled-garden entry is free, unauthenticated internet for anyone in Wi-Fi range — so keep it to detection URLs and (if used) the payment host. We've audited "free Wi-Fi" hotspots whose walled garden had grown to include social media and streaming "so guests could preview" — which is just open Wi-Fi with extra steps, and on a metered or capped line, a bill. The garden is a short list; if it's long, something's wrong with the model.

05

Per-Guest Bandwidth & Fairness

The hotspot has its own rate-limit that composes with — and should defer to — the PCQ fairness from the QoS post. Set a per-session cap here; let PCQ share the pool.

RouterOS — a sane per-guest cap
# rate-limit on the user profile: rx/tx from the GUEST's perspective.
# 10M down / 5M up per device is plenty for a hotel guest.
[admin@GW] > /ip hotspot user profile set [find name=default] rate-limit=5M/10M

# Advanced rate-limit syntax also supports burst — generous for a few
# seconds (snappy page loads) then settles to the sustained cap:
#   rate-limit=5M/10M 8M/16M 6M/12M 8 8 8   (rx/tx  burst  threshold  time)

# Then let PCQ (from the QoS post) share the total guest pool fairly on
# top of the per-device cap — the two layers stack:
[admin@GW] > /queue simple add name=guest-pool target=10.10.20.0/24 \
    max-limit=300M/300M queue=pcq-up/pcq-down
⚠ Gotcha — Hotspot Rate-Limit vs FastTrack, Again

The same trap as the firewall post: if a FastTrack rule matches guest traffic, the hotspot's shaping (and your PCQ queues) never see the packets, and every "limit" silently does nothing. On a box running a guest hotspot, scope FastTrack to exclude the guest subnet, or don't FastTrack at all. Symptom: you set 10M per guest, one guest pulls 400M, and the queue counters read zero. The packets are being fast-pathed around the shaper.

06

The HTTPS Reality & Other Field Gotchas Read Before Go-Live

Captive portals were designed for a plaintext-HTTP web. The modern all-HTTPS web breaks the classic "redirect any page" trick — here's what actually happens on a guest's phone, and how to make it smooth.

A hotspot works by intercepting an HTTP request and answering with a redirect. But browsers now default to HTTPS, and the router cannot transparently intercept an HTTPS request — doing so would be a certificate error, which is exactly what HTTPS exists to prevent. So if a guest's first action is opening https://…, they get a connection failure, not your portal.

What saves you is captive-portal detection: every modern phone, on joining Wi-Fi, quietly fetches a known plaintext URL (Apple's captive.apple.com, Android's connectivitycheck.gstatic.com). If it gets your redirect instead of the expected response, it pops the login sheet automatically. So the fix isn't fighting HTTPS — it's making sure those detection URLs are handled and not accidentally allowed through the walled garden (allow them to the portal, don't let them bypass it).

Symptom in the fieldCause & fix
"No internet" but no login pageDetection URL blocked or mis-handled — ensure the walled garden allows the detection hosts to the portal, not around it.
Login page loads broken / no logoPortal assets referenced from a CDN — put logo/CSS on the router (section 02).
Guest re-accepts on every reconnectEnable login-by=cookie so the device MAC is remembered for the session (section 02).
Portal throws a cert warningYou enabled HTTPS login without a cert whose CN matches the dns name. Either use plain HTTP for the portal (fine on an isolated guest VLAN) or install a matching cert.
Some devices never see the portalThey opened an HTTPS page first and cached it. Toggle Wi-Fi off/on, or open http://neverssl.com — the reception-desk trick.
💡 What We Actually Deploy on Cretan Hotels

For most small properties: an accept-and-connect portal on plain HTTP (the guest VLAN is already isolated, so there's no credential to steal), cookie login so returning guests skip the page, a two-line walled garden, and a per-guest cap under PCQ. Vouchers only where the owner wants paid or per-room access. We keep the portal's HTML in the config backup so a reflash restores the branding too — the logo on that page is often the only thing the owner personally checks after we hand over.

07

MikroTik ↔ Cisco — Guest Access

Cisco's equivalent lives on the wireless controller, not the router — worth knowing if a site is mixed.

MikroTik / RouterOSCisco
/ip hotspot (built into the router)WLC guest anchor + web-auth policy (on the controller)
Editable login.html on flashCustom web-auth bundle uploaded to the WLC
User Manager vouchersISE guest sponsor portal / local web-auth accounts
Walled gardenPre-auth ACL on the guest WLAN
use-radius=yes → User ManagerRADIUS to ISE / a NAC
rate-limit on the user profileQoS profile / rate limit per WLAN

Takeaways

  1. A captive portal is a redirect-until-authorised trick — the router intercepts HTTP and flips a device to "authorised" on consent. /ip hotspot setup builds the whole stack on one guest interface.
  2. Run it on the isolated guest VLAN, never the WAN, and pick a fake portal hostname that isn't your real domain.
  3. Accept-and-connect is a login profile plus branded HTML. Keep every asset on the router — the guest has no internet until after they submit.
  4. Vouchers = User Manager (built-in RADIUS). Validity counts from first use, so unused codes at reception stay good.
  5. The walled garden is a short allow-list — captive-portal detection URLs and a payment host, nothing more. A long garden is a misconfigured model (or a bill).
  6. Per-guest rate-limit stacks with PCQ — and both die if FastTrack matches guest traffic. Scope FastTrack out of the guest subnet.
  7. HTTPS broke transparent interception; captive-portal detection is what makes the page auto-pop. Handle the detection URLs and the "no internet" complaint disappears.

Want branded guest Wi-Fi with a login page that just works?

NOCTIS builds captive portals for hotels and villas across Crete — your logo, terms acceptance or vouchers, isolated from your real network, fair in high season, and tested on the phones your guests actually carry.

Book a Discovery Call →