MikroTik Integration
MikroTik RouterOS is the primary NAS target for ProxPanel. The RADIUS server understands the MikroTik vendor dictionary (VSA 14988), and a dedicated RouterOS API client in internal/mikrotik/ does everything the RADIUS protocol can’t — torch, IP pool reads, queue tweaks, dynamic PCQ creation, ping, traceroute.
This page is the operator’s cheat-sheet: paste the RouterOS commands, set the right PPP profile, and confirm with a checklist.
Configuration flow
Section titled “Configuration flow”Step 1: Add the NAS to ProxPanel (NAS / Routers → Add NAS) ↓Step 2: Add ProxPanel as a RADIUS client on the MikroTik ↓Step 3: Enable AAA on the PPP / PPPoE service ↓Step 4: Configure the PPP profile so MikroTik trusts the RADIUS reply ↓Step 5: Allow ProxPanel's IP to reach the MikroTik API ↓Step 6: Verify with a test connectStep 1 — register the NAS in ProxPanel
Section titled “Step 1 — register the NAS in ProxPanel”Done in the web panel. Cover all the fields described in RADIUS Server Setup → Registering a NAS:
- IP address = the MikroTik’s interface IP that will source RADIUS packets.
- RADIUS secret = a strong shared secret (you’ll paste this into RouterOS in the next step).
- CoA port = 1700 for default MikroTik, or 3799 if you’ve reconfigured it.
- API username = a RouterOS user with
read,write,policy,test(or at leastapi,read,write). - API password = that user’s password.
Step 2 — RADIUS client on RouterOS
Section titled “Step 2 — RADIUS client on RouterOS”Run on the MikroTik (CLI / Terminal):
/radiusadd address=<proxpanel-ip> \ secret=<your-radius-secret> \ service=ppp \ authentication-port=1812 \ accounting-port=1813 \ timeout=3s \ comment="ProxPanel"If your router has multiple WAN paths, pin the source interface so packets always come from the IP you registered:
/radius set [find comment="ProxPanel"] src-address=<interface-ip>Verify:
/radius print detailservice must include ppp, the secret must match, and accounting=yes is implicit (the accounting-port being set enables it).
Step 3 — enable AAA for PPPoE
Section titled “Step 3 — enable AAA for PPPoE”/ppp aaaset use-radius=yes accounting=yes interim-update=30s| Setting | Why |
|---|---|
use-radius=yes | RouterOS asks ProxPanel to authenticate every PPPoE Auth-Request. |
accounting=yes | RouterOS sends Acct-Start / Interim / Stop for every session. |
interim-update=30s | How often Acct-Interim-Update arrives. Match the value of radius_interim_update_seconds in Settings → RADIUS (default 30 s). |
Step 4 — PPP profile
Section titled “Step 4 — PPP profile”This step is where most MikroTik integrations go wrong. The PPP profile is the template applied to every PPPoE session before the RADIUS attributes are merged in. If the profile sets a value, RADIUS may or may not be able to override it.
/ppp profileadd name="ppp-radius" \ local-address=10.10.10.1 \ remote-address=none \ dns-server=8.8.8.8,1.1.1.1 \ only-one=yes \ use-encryption=default \ use-compression=defaultThe critical field is remote-address=none.
The default PPPoE server entry should point to this profile:
/interface pppoe-server serverset [find] default-profile="ppp-radius"Step 5 — API access
Section titled “Step 5 — API access”ProxPanel uses the RouterOS API (port 8728 plain, 8729 with TLS) for IP pool import, torch, ping, traceroute, and dynamic queue changes. Both are over TCP.
/ip serviceset api address=<proxpanel-ip>/32 disabled=no# Or for TLS:set api-ssl address=<proxpanel-ip>/32 disabled=no| Port | Protocol | Used by |
|---|---|---|
| 8728 | Plain TCP | mikrotik.NewClient(...) default. Use over a trusted LAN / WireGuard. |
| 8729 | TCP + TLS | Set use_ssl = true and api_ssl_port = 8729 on the NAS row. Cert validation is InsecureSkipVerify — MikroTik’s self-signed cert is accepted. |
The API user needs enough policy to read pools, queues, PPP active sessions, and run torch:
/user groupadd name=proxpanel-api policy=read,write,api,test,sniff/useradd name=proxpanel password=<strong-pw> group=proxpanel-api address=<proxpanel-ip>/32If the panel server’s IP changes — VPS migration, BGP flip — update both the /ip service api address= list and the API user’s address= field, or the panel will start logging Failed to send password: broken pipe.
Step 6 — verify
Section titled “Step 6 — verify”- Auth path: create a test subscriber in ProxPanel. PPPoE-dial from a real client. On the panel, Subscribers → live status should flip to online within ~5 s.
- Accounting path: wait 30 s. The Sessions page should show bytes increasing.
SELECT acctupdatetime FROM radacct WHERE username='...' ORDER BY acctstarttime DESC LIMIT 1;should be within the last minute. - API path: the NAS row in NAS / Routers should show
online = true. If it shows the red “API offline” badge, run the diagnostic in troubleshooting. - CoA path: edit the subscriber’s service to a different speed plan. The live session’s queue (
/queue simple printon RouterOS) should update within 30 s without disconnecting.
CoA port — 1700 vs 3799
Section titled “CoA port — 1700 vs 3799”RFC-3576 says CoA / Disconnect should arrive on UDP 3799. MikroTik defaults to UDP 1700. ProxPanel lets you pick per NAS (the coa_port column on nas_devices).
The MikroTik side is configured per /radius entry:
/radius incomingset accept=yes port=1700The MikroTik server (the side receiving CoA from ProxPanel) listens on whatever /radius incoming port is set to. ProxPanel sends CoA to whatever you wrote in the NAS row’s CoA port field. The two have to match.
What ProxPanel writes to RouterOS
Section titled “What ProxPanel writes to RouterOS”The RADIUS reply is enough for 90% of operation. The API client steps in for these tasks:
| Task | RouterOS endpoint | When |
|---|---|---|
| Auto-import IP pools | /ip/pool/print | First time a NAS is added with API credentials (internal/services/ip_pool_service.go). |
| Sync active sessions to IP pool tracker | /ppp/active/print | Right after pool import; marks pool IPs as in-use. |
| Live torch | /tool/torch | When operator clicks the torch icon on a subscriber. Polls every 1–3 s. |
| Per-session bytes | /ppp/active/print (bytes-in / bytes-out) | Every 30 s by QuotaSync. Note: not /queue simple/print — see the v1.0.387 fix below. |
| Push CDN PCQ rules | /queue/type, /ip/firewall/mangle, /queue/simple | When operator hits “Sync to MikroTik” on CDN. |
| MidsRate-limit override (mid-session) | RADIUS CoA, fallback /queue/simple/set | When operator changes a subscriber’s speed live. |
| Ping / traceroute from MikroTik | /ping, /tool/traceroute | Diagnostic Tools page. |
| WiFi changes (TR-069) | Not via MikroTik — handled by the TR-069 ACS. |
The bytes-in / bytes-out gotcha
Section titled “The bytes-in / bytes-out gotcha”Prior to v1.0.387, ProxPanel read session bytes from /queue/simple/print. That field is cumulative across PPPoE sessions and persists when an IP is reassigned. Result: a service change moved a subscriber to a new pool / IP, the new IP inherited the previous holder’s queue counter, and ProxPanel saw a phantom +60 GB delta.
The fix reads bytes-in= / bytes-out= from /ppp/active/print instead — those reset every reconnect. The simple-queue value is only used as a fallback when /ppp/active/print returns zero. If you write your own integration against the RouterOS API, do the same.
Troubleshooting
Section titled “Troubleshooting””API offline” on the NAS row
Section titled “”API offline” on the NAS row”- From the panel host,
nc -vz <mikrotik-ip> 8728. If it fails, your firewall is dropping it — open it. - On RouterOS,
/ip service print—apimust beenabledand eitheraddress=empty or include the panel’s IP. - On RouterOS,
/user print— the API user must haveaddress=empty or matching the panel’s IP, and a group withapiin its policy. - From the panel server,
docker logs proxpanel-api 2>&1 | grep -i "mikrotik"— look for the exact error.
”RADIUS timeout” on PPPoE dial
Section titled “”RADIUS timeout” on PPPoE dial”See RADIUS Server Setup → Troubleshooting.
Subscriber gets a wrong IP
Section titled “Subscriber gets a wrong IP”If a subscriber connects and gets an IP from the wrong pool / subnet, the cause is almost always the PPP profile’s remote-address not being none. Fix Step 4 and disconnect the subscriber once.
If you’ve fixed the profile but the subscriber still inherits a stale IP, delete the row in radreply (DELETE FROM radreply WHERE username = '...' AND attribute = 'Framed-IP-Address';) and the next reconnect will allocate fresh.
Related pages
Section titled “Related pages”- RADIUS Server Setup — the panel side of the conversation.
- CoA & Disconnect — the CoA wire format MikroTik expects.
- IP Pool Management — why pools are imported via API.
- Static IP Assignment — per-subscriber Framed-IP-Address.
- Speed Format (kb vs M) — how
Mikrotik-Rate-Limitis built.