← Operator library Access & AAA

FreeRADIUS with MikroTik: A Production Setup Guide for ISPs

Build a dependable PPPoE authentication and accounting path between MikroTik RouterOS and FreeRADIUS, then prove it works before moving subscribers.

What this note covers

Build a dependable PPPoE authentication and accounting path between MikroTik RouterOS and FreeRADIUS, then prove it works before moving subscribers.

What you are building

In a MikroTik PPPoE network, the router terminates each subscriber session while FreeRADIUS decides whether the credentials are valid and which service policy should be returned. The router then reports session activity back through RADIUS accounting. This separation lets an ISP manage access centrally without turning the RADIUS server into the traffic path.

Authentication

FreeRADIUS accepts or rejects the username and password presented through the MikroTik NAS.

Authorization

The Access-Accept can return an address pool, fixed address, rate limit, timeout, or other enforceable policy.

Accounting

Start, interim, and Stop packets create the session timeline used for online status, usage, and investigation.

Operations

NAS identity, time synchronization, logs, and health checks make every access decision traceable.

This guide uses a single MikroTik PPPoE concentrator and a FreeRADIUS server on a private management network. It is suitable for a controlled first deployment and creates the foundation for a billing-backed SQL policy later.

Important boundary: never expose UDP ports 1812 and 1813 broadly to the internet. Put the router and RADIUS server on a private routed network, management VLAN, WireGuard/IPsec tunnel, or another tightly filtered path. A RADIUS shared secret is not a substitute for an encrypted management network.

Plan the AAA path before installing anything

Use stable management addresses. A router may receive changing WAN addresses or connect through a VPN, but FreeRADIUS must still see it as one predictable network access server. The example topology below keeps subscriber traffic separate from AAA traffic.

PPPoE subscribers
       │
       ▼
MikroTik NAS              FreeRADIUS
10.44.0.2  ───────────►   10.44.0.10
             UDP/1812     authentication
             UDP/1813     accounting
Item Example Production requirement
RADIUS server 10.44.0.10 Static address, reliable storage, monitored service
MikroTik source address 10.44.0.2 Stable and reachable in both directions
Authentication UDP/1812 Allowed only from registered NAS addresses
Accounting UDP/1813 Allowed only from registered NAS addresses
Shared secret Unique per router Long, random, stored in a secret manager
Time NTP on both devices Consistent timezone and synchronized clocks

Record the expected source address before configuring firewalls. A common failure occurs when the router reaches the server from a different interface address than the one declared in clients.conf. Packet capture will show requests arriving, but FreeRADIUS will identify them as an unknown client and discard them.

Install FreeRADIUS on Debian or Ubuntu

Package paths vary by operating system and FreeRADIUS major version. On current Debian-family packages, configuration normally lives below /etc/freeradius/3.0/. Confirm the installed path on your server rather than creating a second unused configuration tree.

sudo apt update
sudo apt install freeradius freeradius-utils
sudo systemctl enable --now freeradius
sudo systemctl status freeradius --no-pager
sudo ss -lunp | grep -E ':(1812|1813)b'

Before editing, preserve a restricted backup:

sudo cp -a /etc/freeradius/3.0 /etc/freeradius/3.0.before-mikrotik
sudo chmod -R go-rwx /etc/freeradius/3.0.before-mikrotik

If your distribution installs a different version directory, substitute that path in every command below. Do not copy secrets into public repositories or support tickets.

Register the MikroTik as a RADIUS client

In RADIUS terminology, the client is the NAS sending requests—not the PPPoE subscriber. Add one block for the MikroTik in /etc/freeradius/3.0/clients.conf:

client edge-pppoe-01 {
    ipaddr = 10.44.0.2
    secret = replace-with-a-long-random-secret
    shortname = edge-pppoe-01
    nas_type = other
}

Use a different secret for every router. This limits the impact of one leaked configuration and makes rotation manageable. After saving the file, validate the full configuration before restarting:

sudo freeradius -XC
sudo systemctl restart freeradius
sudo systemctl is-active freeradius
Why configuration validation matters: restarting first turns a small syntax error into an authentication outage. freeradius -XC parses the active configuration without starting a second production listener.

Create one isolated test subscriber

Start with the files module so the network path can be proven without adding SQL and billing logic at the same time. Open /etc/freeradius/3.0/mods-config/files/authorize and add a temporary account:

radius-lab Cleartext-Password := "use-a-strong-temporary-password"
    Service-Type = Framed-User,
    Framed-Protocol = PPP,
    Mikrotik-Rate-Limit = "20M/20M"

The symmetric rate makes the first result easy to verify. Later, let the billing or subscriber system generate the exact MikroTik rate attribute from a single package record. Avoid keeping a second set of package speeds directly on every router.

Validate and reload once more:

sudo freeradius -XC
sudo systemctl restart freeradius

A local radtest confirms that FreeRADIUS can parse the user and produce an Access-Accept, but it does not test the MikroTik path. Many default packages define localhost with the testing secret testing123; verify that local client entry before running:

radtest radius-lab 'use-a-strong-temporary-password' 127.0.0.1 0 testing123

Expect Access-Accept and the intended reply attributes. If local testing fails, fix the RADIUS policy before touching RouterOS.

Restrict the server firewall

The server should accept authentication and accounting only from the router management address. With UFW, the example rules are:

sudo ufw allow from 10.44.0.2 to any port 1812 proto udp
sudo ufw allow from 10.44.0.2 to any port 1813 proto udp
sudo ufw status numbered

If the server uses nftables, a cloud network security group, or an upstream firewall, enforce the same source restriction there. Confirm routing and return routing; opening a port cannot repair an asymmetric path.

Configure the MikroTik RADIUS client

Run the following from a safe RouterOS session. Keep an independent management path available while changing access authentication.

/radius
add address=10.44.0.10 service=ppp secret="replace-with-the-same-long-random-secret" 
    authentication-port=1812 accounting-port=1813 timeout=1s src-address=10.44.0.2

/ppp aaa
set use-radius=yes accounting=yes interim-update=5m

The src-address must be present on the router and routable to the RADIUS server. If your topology does not permit a fixed source, omit it and register the address FreeRADIUS actually observes. A one-second timeout is a starting point for a stable private path; measure latency and packet loss before tuning retries or timeout values.

Inspect the RouterOS entry:

/radius print detail
/radius monitor 0

Local PPP secrets can affect testing because RouterOS may resolve a matching local account without asking RADIUS. Use a username that exists only in FreeRADIUS, or deliberately remove the duplicate local test secret after confirming you retain safe administrative access.

Prove authentication from an actual PPPoE client

  1. Start server-side debug. Stop the service briefly in a maintenance window and run sudo freeradius -X in the foreground.
  2. Connect the isolated test CPE. Use only the radius-lab credentials and avoid moving production subscribers yet.
  3. Follow the request. Confirm the packet is attributed to edge-pppoe-01, the intended authorize rule matches, and FreeRADIUS sends Access-Accept.
  4. Inspect the live session. Check the PPP active entry and verify the resulting queue or rate policy on RouterOS.
  5. Test rejection. Enter a wrong password and confirm an Access-Reject—not a timeout or unintended local login.
  6. Restore normal service. Exit debug mode and run sudo systemctl start freeradius.
/ppp active print detail where name="radius-lab"
/queue simple print detail where name~"radius-lab"
/radius monitor 0

Debug output can contain usernames, attributes, network addresses, and authentication material. Keep it out of public paste sites and remove sensitive values before attaching a small relevant extract to a ticket.

Accounting is a separate acceptance test

An accepted login proves only authentication and authorization. An ISP also needs a reliable record of when the session started, how it changed, and why it stopped. With PPP accounting enabled, validate these transitions independently:

Packet When it should appear What to verify
Accounting-Start After the PPP session is established Username, NAS, session ID, assigned address
Interim-Update At the configured interval Same session ID, advancing time and counters
Accounting-Stop After normal disconnect Matching session, final counters, termination cause
Accounting-On/Off When supported during NAS service state changes Stale-session reconciliation behaviour

Five-minute interim updates are a reasonable initial compromise for many networks: short enough to keep online state useful, but not so frequent that every router floods the database. Capacity-test your own subscriber count. Ten thousand online sessions at five-minute intervals produce roughly 33 interim packets per second before starts, stops, retries, and other NAS traffic.

If SQL accounting is enabled, confirm the same Acct-Session-Id is updated rather than inserted as a new online session each time. Test a clean logout, a powered-off CPE, a router reboot, and a temporary loss of the RADIUS path. Your billing platform needs a documented stale-session rule for cases where a Stop packet can never arrive.

Move policy into SQL only after the path works

A production ISP normally stores subscribers and reply attributes in SQL or lets its billing system maintain those records. Introduce that layer after file-based authentication, router communication, and accounting have all passed. Otherwise a single failed login may involve routing, firewall, shared secret, SQL schema, query logic, password format, and package generation at once.

Define ownership before connecting the billing platform:

  • The subscriber record owns access status and credential state.
  • The package catalogue owns the intended rate and service constraints.
  • The address-management design owns pools, framed addresses, and prefixes.
  • The NAS inventory owns router source addresses and unique shared secrets.
  • RADIUS accounting owns the raw session evidence; dashboards consume it rather than inventing online state independently.

Use a database account with only the permissions FreeRADIUS requires, restrict it to the AAA hosts, use TLS where the database crosses a host boundary, and back up both schema and configuration before migration.

Troubleshoot by symptom, not by guesswork

Symptom Likely area First evidence to collect
Router counter shows timeouts Routing, firewall, wrong source, service not listening /radius monitor, server socket list, packet capture
FreeRADIUS reports unknown client Observed NAS source differs from clients.conf Source IP in freeradius -X
Invalid Message-Authenticator or bad authenticator Shared secrets do not match or an intermediary changed the packet Compare secret deployment and client block
Access-Reject with a known password Password type, authorize order, duplicate username, account state Module-by-module debug result
Access-Accept but no expected speed Reply attribute absent, malformed, or overridden Access-Accept attributes and live RouterOS queue
User connects but appears offline Accounting path or session correlation Start/interim packets on UDP/1813
Duplicate online sessions Interim rows inserted, session ID mismatch, missing Stop handling Accounting records grouped by session ID
RADIUS works locally but not from MikroTik NAS path rather than user policy Capture on server management interface

On the server, a narrow capture confirms whether requests arrive without exposing more traffic than necessary:

sudo tcpdump -ni any 'host 10.44.0.2 and (udp port 1812 or udp port 1813)'

A packet reaching the server does not prove FreeRADIUS accepted it, and an Access-Accept leaving the server does not prove it returned to the router. Combine packet evidence with RADIUS debug and RouterOS counters.

Harden the production deployment

  • Patch FreeRADIUS and RouterOS through a tested maintenance process.
  • Use a unique, high-entropy shared secret for each NAS and rotate it deliberately.
  • Keep AAA traffic on encrypted or private management paths.
  • Reject unknown NAS addresses and alert on repeated unknown-client events.
  • Synchronize server and router clocks with monitored NTP sources.
  • Monitor authentication latency, rejects, timeouts, accounting freshness, and database write errors separately.
  • Maintain a second RADIUS node only when policy data and operational behaviour are genuinely synchronized.
  • Back up configuration, database schema, and secrets using different access controls.
  • Test restore and failover; a second IP in RouterOS is not proof of redundancy.

Dynamic Authorization or Disconnect Messages can later let a billing system terminate or change an active session without waiting for reconnection. Treat that as a separate project: RouterOS incoming RADIUS, UDP/3799 filtering, source validation, supported attributes, and replay-resistant operational controls all need acceptance testing.

Production cutover checklist

  1. Baseline. Record current PPPoE login rate, online count, CPU load, and failure rate.
  2. Pilot. Move a small internal or staff cohort whose sessions can be inspected directly.
  3. Observe. Compare router online sessions with accounting records through at least one full reconnect cycle.
  4. Expand gradually. Move subscribers in bounded batches while watching latency, rejects, timeouts, and SQL health.
  5. Exercise failure. Stop one RADIUS service, interrupt the management path, and document actual subscriber impact.
  6. Remove temporary access. Delete the file-based lab user and any temporary firewall or logging exceptions.
  7. Sign off. Store the topology, rollback procedure, secret owner, monitoring thresholds, and escalation contacts.
4proofs required before cutover: correct acceptance, correct rejection, complete accounting, and understood failure behaviour.

A stable FreeRADIUS deployment is not defined by one successful PPPoE login. It is defined by repeatable policy, trustworthy accounting, controlled failure, and evidence that an operator can follow from subscriber to NAS to RADIUS decision.

Primary references: IETF RFC 2865 and RFC 2866; the current FreeRADIUS documentation; and MikroTik’s current RouterOS RADIUS and PPP AAA manuals. Package locations, security defaults, and supported attributes can change by release, so validate commands against the versions deployed in your network.

Continue with ISPbills

Put this guide into practice