Zum Inhalt springen

MikroTik RouterOS

This page covers administrative access to a MikroTik router over RADIUS. It is the device-side counterpart to RADIUS.

PlatformSoftwareWhat was verified
MikroTik CHR (x86_64)RouterOS 7.5 (stable)RADIUS administrative login over SSH with MS-CHAPv2, for both local and Active Directory accounts; user-group assignment via Mikrotik-Group; login accounting; 802.1X and MAC authentication with VLAN assignment; CoA Disconnect

This is the first thing to know, because it decides whether anything works at all.

RouterOS does not send the password as PAP. Every Access-Request it produces for an administrative login carries MS-CHAP-Challenge and MS-CHAP2-Response:

sending Access-Request with id 30 to 10.0.0.20:1812
Service-Type = 1
User-Name = "ad_user1"
MS-CHAP-Challenge = 0x62c0175b3701c8cfbe5fb74390bf59df
MS-CHAP2-Response = 0x0000d8fca3d1cec9412f03e395aed10a…
Calling-Station-Id = "10.6.0.110"
NAS-Identifier = "MT-DEMO"
NAS-IP-Address = 10.0.0.11

and a successful reply carries MS-CHAP2-Success:

received Access-Accept with id 30 from 10.0.0.20:1812
MS-CHAP2-Success = 0x00533d38393136423546344342423845…
Service-Type = 1
Session-Timeout = 3600
Idle-Timeout = 600

Two things follow.

Taranac 1.2.2 or newer is required. MS-CHAPv2 support was added in that release. On an earlier version RouterOS logins are rejected regardless of how correct the rest of the configuration is, and the rejection looks like a bad password.

Your identity source has to be able to answer MS-CHAPv2. Unlike PAP, MS-CHAPv2 is a challenge–response exchange that cannot be satisfied by a plain directory bind. For directory-backed accounts the branch is chosen by the user’s own directory, and that directory has to be one that can serve MS-CHAPv2: either the Active Directory the node has joined — of which there is at most one — or, since 1.2.8, a directory that publishes a readable NT hash, such as FreeIPA’s ipaNTHash. The two are not alternatives: a node may hold a domain join and any number of hash-readable directories at the same time. See MS-CHAPv2 for directory accounts.

Every successful login is preceded by a rejected one

Section titled “Every successful login is preceded by a rejected one”

RouterOS probes the SSH none authentication method before it prompts the human, and it does so by sending a complete MS-CHAPv2 Access-Request whose response proves the empty password. That request is neither optional nor a misconfiguration: exactly one arrives before every interactive login, including the ones that succeed.

Taranac rejects it — it has to — and records it under its own reason, empty_password_probe, shown in the authentication log as Empty password (device probe). Since 1.2.2 that reason is excluded from everything that counts failures:

  • it does not feed the brute-force guard, which otherwise halved the configured threshold for exactly the devices that need MS-CHAPv2;
  • it is left out of the authentication-failure rate and out of the dashboard’s top failed authentications widget, which on a MikroTik-heavy installation was topped by the customer’s own administrators, one entry per successful login.

The row itself stays in the log on purpose — a packet that really arrived is not hidden. So a healthy RouterOS login is two rows for the same username: a rejected probe, then an accepted login. Only the second one is a login.

MS-CHAPv2 decides what is possible here, and the answer is narrow: push is the only workable second factor on this platform. This is not a gap waiting to be closed — two of the three MFA modes cannot work over MS-CHAPv2 even in principle.

One-time passwords appended to the password do not work, and cannot be made to. MS-CHAPv2 never carries the password. It carries a response derived from the NT hash of exactly the string the user typed. Append an OTP and the router hashes password+OTP, which will never match the stored password — and the server cannot separate the two halves back out, because it never receives either one in the clear.

Challenge mode does not work either, for a separate and more mundane reason: RouterOS runs no second round for an administrative login, so an Access-Challenge has nowhere to go.

Push works normally. The password is verified by MS-CHAPv2 as usual, and the second factor happens out of band — the server holds the exchange open while the user approves on their phone. Verified on this platform with the Telegram and Email push providers.

The behaviour is fail-closed, and Taranac distinguishes two rejection reasons so you can tell the cases apart:

Reject reasonMeaning
mfa_provider_unsupportedThe user’s MFA provider cannot work over MS-CHAPv2 — typically a TOTP/OTP factor. Move that user to a push provider.
mfa_not_configuredPolicy requires MFA and the user has no factor enrolled at all.

Both surface as a plain Access-Reject to the router, which shows the user nothing but a failed login — so the distinction lives in Taranac’s authentication log, and that is where to look when someone says “my password works everywhere else”.

Everything above applies to any platform that authenticates over MS-CHAPv2, not just MikroTik. And note the interaction with the RADIUS timeout below: push is the one mode that works here, and it is also the one that needs the timeout raised.

/radius
add address=10.0.0.20 secret="<RADIUS_SECRET>" service=login timeout=3s comment="Taranac device-admin"

service=login is what scopes this server entry to administrative login. RouterOS uses the same /radius list for every RADIUS-consuming subsystem, so a router that also does 802.1X carries a second entry with service=dot1x pointed at the NAC ports:

add address=10.0.0.20 secret="<RADIUS_SECRET>" service=dot1x authentication-port=1814 accounting-port=1815 timeout=3s comment="Taranac NAC"

Both entries point at the same server and therefore carry the same secret: it is the radius_secret on this router’s device entry in Taranac, and it must match byte for byte. See Network devices for the device → device group → global chain.

Leaving the ports off the first entry uses the RADIUS defaults, 1812/1813, which is what a standard Taranac deployment listens on for device administration. The NAC service listens on 1814/1815 and must be named explicitly. Getting these the wrong way round produces a server that answers with the wrong policy engine rather than an error.

/user aaa
set use-radius=yes accounting=yes default-group=read

use-radius=yes is the master switch. accounting=yes is what produces the Accounting-Request pairs that create login records in Taranac — a router without it authenticates perfectly and reports nothing.

interim-update controls periodic updates during a session; the tested router leaves it at 0s, which sends start and stop only.

The attribute Taranac must return is Mikrotik-Group (vendor 14988, VSA type 3), carrying the name of a RouterOS user group. The built-ins are full, write and read; custom groups work too, and the name has to match exactly.

/user group print detail
0 name="read" policy=local,telnet,ssh,reboot,read,test,winbox,password,web,sniff,…
1 name="write" policy=local,telnet,ssh,reboot,read,write,test,winbox,…
2 name="full" policy=local,telnet,ssh,ftp,reboot,read,write,policy,test,winbox,…

For this to work, the Taranac policy rule serving this device must return a profile built on the MikroTik RouterOS RADIUS template. A profile built on some other vendor’s template will authenticate the user perfectly and send an attribute the router does not understand — see below, because this failure is invisible unless you know its signature.

/ip service print

RADIUS login applies to the management services RouterOS exposes — ssh, winbox, www, api and others. Disable what you do not use; each enabled service is another path where an authorization mistake has consequences. SSH was the method verified here.

Turn on RADIUS logging first — RouterOS logs nothing about RADIUS by default:

/system logging
add topics=radius
add topics=radius,debug

The radius,debug topic prints every attribute of every packet, which is what makes this platform pleasant to diagnose. Turn it off again when you are done; it is noisy.

/radius monitor 0 gives the counter summary for the first server entry:

/radius monitor 0
pending: 0
requests: 32
accepts: 12
rejects: 20
resends: 0
timeouts: 0
bad-replies: 0
last-request-rtt: 10ms

timeouts and bad-replies at zero mean the server is reachable and the shared secret is right. resends climbing points at latency or loss. rejects are policy decisions, not transport problems.

/user active print detail shows who is connected and, crucially, how they authenticated:

/user active print detail
Flags: R - radius; M - by-romon
0 when=aug/02/2026 08:49:55 name="admin" via=console group=full
1 R when=aug/06/2026 08:32:21 name="ad_user1" address=10.6.0.110 via=ssh group=read

The R flag is the one to read: that session was authenticated by RADIUS. A session without it came from the local user database. The group= column shows which RouterOS group was actually applied — compare it against what your policy intended.

This pair of lines is the whole verification in one view. R proves Taranac authenticated the session; group=read proves the group assignment arrived and was applied, because a session that fell through to default-group would show that group instead.

received Access-Accept with id 40 from 10.0.0.20:1812
MS-CHAP2-Success = 0x00533d35303334364244304435433937…
Service-Type = 1
Session-Timeout = 3600
Idle-Timeout = 600
MT-Group = "read"

MT-Group present, named, and carrying a group that exists on the router. That is the line to look for.

If Taranac returns an authorization profile built on another vendor’s template, RouterOS accepts the login and logs the attribute it cannot use:

received Access-Accept with id 30 from 10.0.0.20:1812
Service-Type = 1
Session-Timeout = 3600
Idle-Timeout = 600
Unknown-Attribute(vendor=Cisco, type=1) = 0x7368656c6c3a707269762d6c766c3d3135

That hex decodes to shell:priv-lvl=15 — a Cisco AV-pair, sent to a MikroTik. RouterOS does not understand it, ignores it, and falls back to default-group.

Login accounting works and needs no configuration beyond accounting=yes. A session produces a start and a stop:

sending Accounting-Request with id 19 to 10.0.0.20:1813
User-Name = "ad_user1"
Acct-Status-Type = 1 ← start
Acct-Session-Id = "84000004"
NAS-Identifier = "MT-DEMO"
NAS-IP-Address = 10.0.0.11
sending Accounting-Request with id 20 to 10.0.0.20:1813
Acct-Status-Type = 2 ← stop
Acct-Session-Time = 8
Acct-Terminate-Cause = 1

NAS-IP-Address is what Taranac matches against the registered device. RouterOS derives it from the interface used to reach the server, so a router with several routed interfaces should have its device entry checked against what actually appears here rather than against the address you think of as its management IP. See Network devices.

RouterOS can also act as an authenticator for endpoints, using the second /radius entry:

/interface dot1x server
add interface=ether4 auth-types=dot1x,mac-auth mac-auth-mode=mac-as-username-and-password accounting=yes

auth-types=dot1x,mac-auth enables 802.1X with MAC authentication as the fallback — RouterOS’s equivalent of MAB. mac-auth-mode=mac-as-username-and-password sends the endpoint’s MAC address as both username and password, which is the convention Taranac’s MAB matching expects.

VLAN assignment works through the standard tunnel attributes:

received Access-Accept with id 49 from 10.0.0.20:1814
Tunnel-Type = 13
Tunnel-Medium-Type = 6
Tunnel-Private-Group-ID = "40"

Since 1.2.8 a NAC session records the VLAN Taranac assigned and the VLAN the device reported as two separate values, so accounting no longer overwrites the assignment and a disagreement between the two is visible instead of being averaged away. The port needs no decoding on this platform: RouterOS puts a readable interface name in NAS-Port-Id (ether2), which is what the NAS Port column shows as it arrives.

/radius incoming
set accept=yes port=3799

This opens the listener for change-of-authorization requests. Without it Taranac’s disconnects go nowhere and every session stays up until it ends on its own — with no error on either side.

port= is where the two sides have to agree, and it is worth being explicit about it. Taranac resolves the destination port for every CoA through device → device group → nac.coa_port (default 3799). The per-vendor coa_port in the NAC vendor dictionary is not part of that chain — it is surfaced by the capability API and never consulted when the packet is sent, so editing it there changes nothing. If the router listens on one port and Taranac sends to another, the CoA fails as a silent timeout: no NAK, nothing in the router’s log, and an operator staring at a disconnect that reports failure with no reason. Taranac names every non-default CoA port it finds in its own log at startup for exactly this reason.

Confirmed working on the tested router:

received Disconnect-Request with id 63 from 10.0.0.20:52608
Acct-Session-Id = "0f000086"
User-Name = "00:50:79:66:68:06"
sending Disconnect-ACK with id 63 to 10.0.0.20:52608

Note what happens in between: the router tears the session down and sends its own Accounting-Stop with final counters before acknowledging the disconnect. That ordering is why a disconnected session closes cleanly in Taranac with real byte and packet totals.

The rest of the mikrotik entry in Taranac’s NAC vendor dictionary, for completeness:

WhatHow Taranac encodes it
VLANTunnel-Type / Tunnel-Medium-Type / Tunnel-Private-Group-ID
Named ACLFilter-Id
Session timeoutSession-Timeout + Termination-Action = RADIUS-Request
Re-authenticationA Disconnect. MikroTik declares no native CoA reauth, so the endpoint reconnects rather than re-authenticating in place
VLAN changeA real CoA-Request carrying the tunnel triplet
Port bounce · port disableUnsupported
Downloadable ACL · URL redirectNot declared. URL redirect is declared by Cisco IOS / IOS-XE alone

The Disconnect is the row verified on the tested router. Everything else in that table is what the dictionary declares from vendor documentation and has not been exercised here.

  • Local fallback. Whether local RouterOS accounts still work when Taranac is unreachable, and whether an explicit Access-Reject behaves differently from a timeout, has not been established. Keep a local account and verify it before relying on use-radius=yes.
  • Winbox, WebFig and API logins. Only SSH was verified.
  • Push providers other than Telegram and Email. Those two were verified; the remaining providers are expected to behave the same way, since the push path is shared, but have not been exercised over MS-CHAPv2.
SymptomLikely cause
Every RADIUS user gets full rightsdefault-group=full combined with a missing or unusable Mikrotik-Group. Check for Unknown-Attribute in the debug log.
Every RADIUS user gets full rights, and MT-Group = "full" is in the replyThe profile leaves Mikrotik-Group unset, so the template’s own default — full — is what gets sent.
Every successful login also logs a rejected empty_password_probeNormal, and not counted anywhere. RouterOS proves the empty password to probe SSH none before prompting.
Unknown-Attribute(vendor=Cisco…) in Access-AcceptThe Taranac profile is built on the wrong vendor template.
All logins rejected, secret and policy correctTaranac older than 1.2.2 — RouterOS sends MS-CHAPv2, which earlier releases cannot answer.
Directory users rejected, local users fineThat user’s directory cannot serve MS-CHAPv2 — it is neither the joined Active Directory nor a directory with a readable NT hash.
Push MFA always fails/radius timeout too low. The default is 300 ms; use 30s.
One user rejected, reason mfa_provider_unsupportedThat account uses a TOTP/OTP factor, which cannot work over MS-CHAPv2. Move it to a push provider.
One user rejected, reason mfa_not_configuredPolicy requires MFA and the account has no factor enrolled.
Logins work, nothing in Taranacaccounting=no in /user aaa.
Request never reaches policy evaluationNAS-IP-Address does not match the registered device address.
CoA has no effect/radius incoming not set to accept=yes, or its port= differs from the port Taranac resolved (device → device group → nac.coa_port). A port mismatch fails as a silent timeout.
802.1X VLAN assigned in Taranac, port stays on its pvidThe bridge is not VLAN-aware. vlan-filtering=yes plus an /interface bridge vlan table are what the assignment is applied to.
Nothing in the log at allRouterOS logs no RADIUS topics by default — add them.