Articles setup, updated 2026-09-28

MikroTik: RouterOS routers and switches

MikroTik routers and CRS switches can be watched two ways, and most estates use both. SNMP works on RouterOS 6 and 7 and is the cheapest route for hardware health, interfaces, PoE, optics and LTE signal. The REST API, RouterOS 7 only, is the only way to see BGP and OSPF sessions and WireGuard handshakes, and gives power supply state as plain words. The MikroTik MIB is already loaded into Oversight, so its objects can be picked by name.

MikroTik's own binary API on ports 8728 and 8729 is not HTTP, and no Oversight sensor can use it. REST is the HTTP route.

Which route for what

To watchSNMPREST (RouterOS 7)
A link going down, or flappingYesYes
Temperatures and voltagesYesYes
Power supply failedYes, once proved on the device (see below)Yes, as ok or fail
CPU loadPer coreWhole box
BGP and OSPF sessionsNo: RouterOS has no routing MIBsYes
WireGuard and IPsec peersIPsec count onlyYes, per peer
PoE ports, SFP optics, LTE signalYesNot reliably
A rebootYes, from uptimeAs text only

A Cloud Hosted Router (CHR) has no temperature, fan, voltage or power supply readings at all; that is the hypervisor's job. Watch a CHR for links, CPU and routing only.

Setting up SNMP

On the router, add a read-only community that answers only the probe groups' addresses, then shut the factory public community, which answers anyone:

/snmp community add name=<long-random-string> addresses=<probe-address>/32 read-access=yes write-access=no
/snmp set enabled=yes contact="NOC" location="Rack 3"
/snmp community set [find name=public] disabled=yes

Add one addresses entry per probe group address, comma separated. If the router refuses to disable public, set its addresses to 127.0.0.1/32 instead. Never enable write access: SNMP write can reboot the router and run scripts.

MikroTik recommends SNMP v3, but Oversight's probes use v2c, so make up for it: the address restriction above, a firewall rule allowing UDP 161 in the input chain from the probes only, and polling over a management network or VPN where there is one.

In Oversight, save an SNMP credential with version 2c and the community, on the device or anywhere above it. See Credentials.

Setting up REST

REST rides on the router's HTTPS web service, so it needs a certificate, the service switched on and limited to the probes, and a user that can read but not change anything.

/certificate add name=oversight-https common-name=<router-name-or-address> days-valid=3650
/certificate sign oversight-https
/ip service set www-ssl certificate=oversight-https disabled=no address=<probe-address>/32 tls-version=only-1.2
/user group add name=oversight-ro policy=read,api,rest-api
/user add name=oversight group=oversight-ro password=<strong-password> address=<probe-address>/32
  • Make a group of your own. The built-in read group also carries reboot, sniff and sensitive rights. read,api,rest-api is the set known to work; some versions manage with less, but that is the safe one.
  • Before RouterOS 7.12 the user's address limit is ignored for REST (CVE-2023-41570). The service's address and the firewall are what protect it there, so upgrade if you can.
  • Enabling www-ssl also serves WebFig on that port. The address limit covers both.
  • A self-signed certificate means turning off Verify the certificate on the sensor. If the router has a public name, /certificate/add-acme gets it a Let's Encrypt certificate and verification can stay on.

In Oversight, save an HTTP(S) credential with the username and password, and give every REST sensor these settings:

SettingValue
Scheme and porthttps, 443 (or the port you gave www-ssl)
MethodGET
HeadersAuthorization: Basic {{basicauth}}
Verify the certificateOff for a self-signed certificate
Interval60 seconds or more. On small single-core routers REST polling is noticeably heavy.

And give every REST sensor the guard rule SV01 not equal to 200 gives CRIT, so a refused login or a wrong path raises an alarm rather than reading OK with nothing in it.

Finding the numbers

SNMP reads one value per sensor, and anything that belongs to a port or a sensor chip needs its row number on the end of the OID.

  • Ports are numbered by ifIndex. On the router, /interface print oid lists every interface with its OIDs, row number included. PoE, SFP optics and LTE tables use the same number. Check again after adding interfaces or a major upgrade.
  • Health readings on RouterOS 7 (and late 6) come from one table, mtxrGaugeTable, and its row number is a fixed code for the kind of reading, not a position. The same code means the same thing on every model that has that reading.
RowReadingUnit and multiplier
17cpu-temperatureWhole degrees C, multiplier 1
14temperature (board)Whole degrees C
7101, 7102board-temperature1, 2Whole degrees C
50, 51sfp-temperature, switch-temperatureWhole degrees C
13voltageTenths of a volt, multiplier 0.1
16poe-out-consumptionTenths of a watt, multiplier 0.1
54fan-stateA status code
7001, 7002fan1-speed, fan2-speedRPM
7401, 7402psu1-state, psu2-stateA status code

A model only has the rows it has sensors for. To see which, walk 1.3.6.1.4.1.14988.1.1.3.100.1.2 once from any workstation: it lists the name of each row. In Oversight, pick MIKROTIK-MIB and mtxrGaugeValue from the MIB list, then put the row number on the end of the OID.

SNMP sensors worth having

In the table, MT stands for 1.3.6.1.4.1.14988.1.1, and <if> for the port's ifIndex.

WhatOIDSettingsRules
Link up1.3.6.1.2.1.2.2.1.8.<if> (ifOperStatus)GAUGE, as readSV01 not equal to 1 gives CRIT. Down ports read 2 on some builds and 6 on others, so test for not 1.
Link flapsMT.14.1.1.90.<if> (mtxrInterfaceStatsLinkDowns)COUNTER32, change per intervalAt least 1 gives WARN, at least 3 gives CRIT
CPU temperatureMT.3.100.1.3.17GAUGE, unit CGreater than 80 gives WARN, greater than 95 gives CRIT
Board temperatureMT.3.100.1.3.14GAUGE, unit CGreater than 65 gives WARN, greater than 75 gives CRIT
Input voltageMT.3.100.1.3.13GAUGE, multiplier 0.1, unit VOutside 10% either side of the supply's nominal voltage gives WARN. An unused input reads 0: leave it alone.
Power supplyMT.3.100.1.3.7401 and .7402GAUGEProve the codes first (below), or use REST.
Rebooted1.3.6.1.2.1.1.3.0 (sysUpTime)GAUGE, multiplier 0.01, unit sLess than 600 gives WARN: it restarted in the last ten minutes
CPU load1.3.6.1.2.1.25.3.3.1.2.<n>, n the core, from 1GAUGE, unit %Greater than 95 gives WARN. One sensor per core; REST gives the whole box in one.
PoE portMT.15.1.1.3.<if> (mtxrPOEStatus)GAUGE; labels come from the MIBOn a port feeding a known device: not equal to 3 (poweredOn) gives CRIT. Elsewhere: equal to (4,9,10,13) gives CRIT.
SFP signal receivedMT.19.1.1.10.<if> (mtxrOpticalRxPower)GAUGE, multiplier 0.001, unit dBmNote the reading when the link is commissioned. 3 dB below it gives WARN, 6 dB below gives CRIT.
SFP lost signalMT.19.1.1.3.<if> (mtxrOpticalRxLoss)GAUGEEqual to 1 gives CRIT
LTE signal (RSRP)MT.16.1.1.4.<if of lte1>GAUGE, unit dBmLess than -110 gives WARN, less than -120 gives CRIT
IPsec tunnels upMT.20.1.0 (mtxrIkeSACount)GAUGELess than the number of tunnels you expect gives CRIT

The temperature and signal thresholds are sensible starting points, not MikroTik's figures; MikroTik only publishes its overheating cut-out (105 C). Adjust them once you know what the kit normally reads.

Do not alarm on fan speed. Fans stop when the unit is cool, and a healthy router can read 0 RPM for days. Watch temperature and fan-state (row 54, 0 when healthy) instead.

Prove the power supply codes on the device

The health table gives power supply state as a number, and the published mapping (0 ok, 1 failed) has been contradicted by at least one real device. Before relying on rows 7401 and 7402, compare what the sensor reads with /system health print, which says ok or fail in words, and if you can, pull one supply while commissioning and watch the number change. Or use the REST sensor below, which reads the words and avoids the question.

RouterOS 6

Older routers have health as separate objects rather than the table: MT.3.10.0 (temperature), MT.3.11.0 (processor temperature) and MT.3.8.0 (voltage), all in tenths, so multiplier 0.1. Power supply state is MT.3.15.0 and MT.3.16.0, where 1 means ok: not equal to 1 gives CRIT. Some of these survive on RouterOS 7 and some do not, which is why the table is the one to use there.

REST sensors worth having

Every value in a RouterOS REST reply is a string, even numbers. A plain number such as "45" still goes into a numeric slot, but "true", "ok", "established" and durations such as "2d20h12m20s" are text. The neat way round that for anything that is simply up or down is to ask for only the healthy items and count them with JSONCOUNT and the expression ., meaning the whole reply: 1 means up, 0 means down or gone.

A filtered request (?name=...) returns a list, so paths start 0.; a request by name (/rest/interface/ether1) returns the item itself.

WhatPathExtractionRules
Link up/rest/interface?name=ether1&running=trueSV03, JSONCOUNT, expression .SV03 equal to 0 gives CRIT
CPU load/rest/system/resource?.proplist=cpu-loadSV03, JSON, cpu-load, unit %Greater than 80 gives WARN, greater than 95 gives CRIT
Power supply/rest/system/health?name=psu1-stateSD03, JSON, 0.valueSD03 not equal to ok gives CRIT. A second sensor for psu2-state.
CPU temperature/rest/system/health?name=cpu-temperatureSV03, JSON, 0.value, unit CGreater than 80 gives WARN, greater than 95 gives CRIT
BGP sessions up/rest/routing/bgp/session?established=trueSV03, JSONCOUNT, expression .Less than the number of sessions you expect gives CRIT
One BGP session/rest/routing/bgp/session?name=<session>&established=trueSV03, JSONCOUNT, expression .SV03 equal to 0 gives CRIT
OSPF neighbours/rest/routing/ospf/neighbor?state=FullSV03, JSONCOUNT, expression .Less than the number expected gives CRIT
IPsec peer/rest/ip/ipsec/active-peers?remote-address=<peer>&state=establishedSV03, JSONCOUNT, expression .SV03 equal to 0 gives CRIT
WireGuard peer/rest/interface/wireguard/peers?name=<peer>SD03, REGEX, /"last-handshake":"([^"]*)"/SD03 matching /[hdw]/ gives CRIT: no handshake for an hour or more
LTE link up/rest/interface/lte?name=lte1&running=trueSV03, JSONCOUNT, expression .SV03 equal to 0 gives CRIT

Plus SV01 not equal to 200 gives CRIT on every one. A few notes on the table:

  • BGP session names are not always what you typed: RouterOS often adds -1 to the connection's name. Read the real name from /routing/bgp/session print first. Session entries linger for a while after a session drops, which is why the filter asks for established=true rather than counting every row.
  • BGP fields with a dot in their name, such as remote.address, cannot be read by an Oversight JSON path, which uses dots to separate names. Filter and count instead, as above.
  • WireGuard peers can be filtered by name from RouterOS 7.15; before that, filter on comment= or public-key=. A peer that has never shaken hands has no last-handshake at all, so the slot is empty and the sensor cannot tell: pair it with a ping across the tunnel. With a keepalive set, a healthy peer's handshake is never more than two or three minutes old.
  • /rest/system/resource should return a single item, but MikroTik's own example shows a list. If cpu-load reads nothing, tick Store raw response, look at what came back, and use 0.cpu-load if it is a list.

A starting set

Not every reading needs a sensor. For a RouterOS 7 router doing routing, these catch what actually goes wrong:

  1. Link up on each uplink (SNMP), and link flaps on the same ports.
  2. CPU temperature (SNMP row 17).
  3. Power supplies, on models with two (REST, ok or fail).
  4. CPU load for the whole box (REST).
  5. BGP sessions established, or OSPF neighbours Full (REST).
  6. WireGuard or IPsec peers, where the site depends on them.
  7. Rebooted (SNMP uptime).

For a CRS switch, drop the routing sensors and add PoE state on ports feeding cameras or access points, and received signal and lost signal on fibre uplinks. For an LTE router, add the lte1 link and its RSRP. On RouterOS 6, use SNMP throughout. At the default 60 seconds from one probe group, an SNMP sensor costs about £1.73 a month and a REST sensor about £3.46.

Things that catch people out

  • Tenths and wholes. In the health table, temperatures are whole degrees but volts, amps and watts are tenths. The old RouterOS 6 objects are tenths throughout. A voltage reading of 237 is 23.7 V.
  • An SFP reading of exactly 0 dBm usually means the module reports nothing (a direct attach cable or copper module), not a perfect signal. RouterOS 7.24 also lists empty SFP cages in the optics table; MT.19.1.1.13.<if> is 1 where a module is actually fitted.
  • PoE state 5 (shortCircuit) has been seen on idle, unused ports of an RB5009. Only alarm on ports with something plugged in.
  • Health readings are approximate, in MikroTik's own words, and meant to warn of trouble coming. Some older PoE-powered CRS models show a fixed 16 V whatever the input.
  • Polling cost. Health readings are expensive for some models to produce: MikroTik warns that the CCR2004-16G-2S+PC is one. Keep health sensors at 60 seconds or more. Oversight asks for one value at a time and never walks the table, which is the gentle way.
  • Permission changes are slow to take. A REST user's rights can take several minutes to change after you alter the user or group. If a login is refused straight after setting it up, wait and try again before changing anything.

MIBs

MIKROTIK-MIB, IF-MIB, HOST-RESOURCES-MIB and SNMPv2-MIB are all loaded already, so everything above can be picked from the MIB list or typed as a number. RouterOS does not implement the BGP or OSPF MIBs, so there is nothing more to load for routing.