MikroTik-Geräte im großen Stil verwalten mit der RouterOS API: Architekturnotizen aus der Praxis
Die Architektur zur zentralen und autonomen Verwaltung von Hunderten oder Tausenden MikroTik-Geräten über die RouterOS API: librouteros Binary-API, asyncio-Brücke, Redis-Arbeitswarteschlange, idempotenter Config-Push, Circuit Breaker und die Unterschiede zwischen v6 und v7. Mit den Lehren aus dem Aufbau unserer eigenen Automatisierungsplattform.
Die Architektur zur zentralen und autonomen Verwaltung von Hunderten oder Tausenden MikroTik-Geräten über die RouterOS API: librouteros Binary-API, asyncio-Brücke, Redis-Arbeitswarteschlange, idempotenter Config-Push, Circuit Breaker und die Unterschiede zwischen v6 und v7. Mit den Lehren aus dem Aufbau unserer eigenen Automatisierungsplattform.
İçindekiler▾
- Wege zur programmatischen Verwaltung von RouterOS: API, SSH und REST
- Gleichzeitig Befehle an Hunderte Geräte senden: die Warteschlangen-Architektur
- Eine synchrone Bibliothek in die async-Welt bringen: die asyncio.to_thread-Brücke
- Die heimtückischste Falle der API: der Unterschied zwischen “print” und “action”
- Warum /export in der API fehlt und man auf SSH ausweichen muss
- Sichere Massenänderung: desired state → diff → idempotenter Befehl → Verifizierung
- Unterschiede zwischen RouterOS v6 und v7: wo die Automatisierung den meisten Code verbraucht
- Zugangsdaten und Nachvollziehbarkeit: Sicherheit im großen Stil
- Und wie groß ist dieser Maßstab wirklich?
- Selbst aufbauen oder verwalten lassen?
Kurze Antwort: Dutzende Geräte lassen sich noch einzeln von Hand verwalten; bei Hunderten oder Tausenden wird das unmöglich. Der richtige Weg im großen Stil ist eine auf der RouterOS API aufsetzende, mit strukturierten Daten arbeitende, warteschlangenbasierte und idempotente Automatisierung. Dieser Beitrag beschreibt genau die Architekturentscheidungen und Fallstricke, die wir beim Aufbau unserer eigenen zentralen MikroTik-Verwaltungsplattform in der Praxis gelernt haben: warum die Binary-API, warum eine Arbeitswarteschlange, wie ein Config-Push sicher durchgeführt wird und welche realen Sonderfälle bei RouterOS die Automatisierung erschweren.
Dieser Inhalt ist keine Produktwerbung, sondern ein Leitfaden für Ingenieure, die ein ähnliches System aufbauen wollen, und eine Antwort auf die Frage “was steckt eigentlich dahinter” für Organisationen, die ihre MikroTik-Infrastruktur extern verwalten lassen möchten. Wenn Sie neu bei MikroTik sind, empfiehlt es sich, zunächst die Grundlagen dazu zu lesen, was MikroTik überhaupt ist und wofür RouterOS steht.
Wege zur programmatischen Verwaltung von RouterOS: API, SSH und REST
RouterOS lässt sich von außen auf drei Wegen automatisieren; im großen Stil ist die Wahl eindeutig:
- Binary-API (8728 / api-ssl 8729): Das eigene binäre Protokoll von RouterOS. Befehle und zurückgelieferte Datensätze sind strukturiert. Das heißt, Sie erhalten aus Menüs wie
interface,ip addressoderfirewall filterFeld-Wert-Paare und müssen keinen Text parsen. Dies ist die richtige Ebene für die Massenverwaltung. - REST API (v7, HTTP/HTTPS): Mit RouterOS 7 eingeführt, liefert JSON. Für einfache Integrationen praktisch; wir haben uns für die Binary-API entschieden, weil wir auch v6-Geräte unterstützen und bei einer einzigen Client-Abstraktion bleiben mussten (REST gibt es nur in v7).
- SSH: Der flexibelste, aber zugleich fragilste Weg: die Ausgabe ist Freitext, ändert sich von Version zu Version und lässt sich nur mühsam parsen. SSH behalten wir ausschließlich für eng umgrenzte Aufgaben, die die API nicht abdeckt (siehe den Abschnitt zu
/exportweiter unten).
Unsere Entscheidung: primäre Methode ist die Binary-API, sekundäre und eng zweckgebundene Methode ist SSH. Auf der Python-Seite setzen wir das mit der Bibliothek librouteros um; ein ausgereifter Client, der das Protokoll korrekt implementiert und den Login-Ablauf der Binary-API für Sie übernimmt.
Gleichzeitig Befehle an Hunderte Geräte senden: die Warteschlangen-Architektur
Der häufigste Fehler ist der Reflex “wenn es tausend Geräte gibt, öffne ich eben tausend Verbindungen gleichzeitig”. Das bringt einen einzelnen Server samt Netzwerkstack rasch in die Knie; obendrein lässt ein einziges langsames Gerät den gesamten Prozess warten. Das im großen Stil funktionierende Muster ist ein anderes:
- Fan-out: Wird eine Massenoperation ausgelöst (z. B. “Backup aller Geräte erstellen”), wird für jedes Gerät ein eigener Job erzeugt.
- Priorisierte Warteschlange: Diese Jobs werden in eine Redis-Warteschlange geschrieben. Verschiedene Job-Typen werden mit unterschiedlichen Prioritäten geführt; ein dringender Reconcile hat Vorrang vor einem routinemäßigen Monitoring-Scan.
- Horizontale Worker-Skalierung: Die Warteschlange wird von zahlreichen voneinander unabhängigen Worker-Prozessen parallel abgearbeitet. Der Parallelitätsgrad wird nicht dadurch erhöht, dass man eine einzelne riesige Schleife beschleunigt, sondern durch Erhöhung der Anzahl der Worker-Replikate. Das macht das System in Docker/Kubernetes von Natur aus horizontal skalierbar.
Diese Architektur bietet drei kritische Garantien:
- Reliable Queue (ACK/NACK): Sobald ein Job entnommen wird, wird er als “in Bearbeitung” markiert. Stürzt ein Worker ab, kehrt der Job nach einer bestimmten Zeit automatisch in die Warteschlange zurück, sodass kein Gerät stillschweigend übersprungen wird.
- Verteiltes Lock pro Gerät: Für jedes Gerät wird in Redis ein Lock (
lock:device:<id>) belegt. So können nicht zwei Worker gleichzeitig eine Konfiguration auf dasselbe MikroTik-Gerät schreiben. Kann das Lock nicht belegt werden, wird der Job mit einem kurzen exponentiellen Backoff (5 → 10 → 20 → 40 s) erneut versucht. - Circuit Breaker: Bei einem ausgeschalteten oder nicht erreichbaren Gerät jedes Mal vergeblich einen Verbindungsversuch zu unternehmen, ist eine Verschwendung von Zeit und Warteschlangenkapazität. Nach einer bestimmten Anzahl aufeinanderfolgender Verbindungsfehler (bei uns 3) wird für dieses Gerät der “Schaltkreis geöffnet” und für eine Abkühlzeit (5 Minuten) kein Versuch mehr unternommen. Kommt das Gerät zurück, schließt sich der Schaltkreis automatisch.
Eine ehrliche Grenze: Nicht jeder Massenjob ist ein “echtes Fan-out”. Beispielsweise ist es auch möglich, einen Health-Check über Tausende Geräte als einen einzigen Job in die Warteschlange zu legen und innerhalb des Workers der Reihe nach durchzugehen; das ist einfach, aber seriell. Echte Parallelität entsteht erst, wenn Sie die Arbeit pro Gerät aufteilen. Welcher Job ein Fan-out und welcher seriell sein soll, ist eine bewusste Design-Entscheidung.
Eine solche zentrale Verwaltung gewinnt erst zusammen mit einer Überwachungsschicht ihren vollen Sinn; wir binden das Inventar auch an die Netzwerküberwachung mit Zabbix an. Für mehrstandortige und ISP-artige Strukturen ist ein Leitfaden zur ISP-Netzwerkverwaltung eine ergänzende Lektüre.
Eine synchrone Bibliothek in die async-Welt bringen: die asyncio.to_thread-Brücke
librouteros ist eine synchrone Bibliothek: Wenn Sie einen Befehl senden, blockiert sie, bis die Antwort eintrifft. Unsere Worker hingegen basieren auf asyncio. Diese beiden in ihrer Rohform zu vermischen bedeutet, dass ein einziges langsames Gerät den gesamten Event Loop (und damit alle von diesem Worker bearbeiteten Geräte) blockiert.
Die Lösung besteht darin, jeden I/O-Aufruf zum Gerät in einen Thread auszulagern:
# Synchronen librouteros-Aufruf ausführen, ohne den Event Loop zu blockieren
api = await asyncio.to_thread(librouteros.connect, host=ip, username=user,
password=pw, port=8728, timeout=10)
data = await asyncio.to_thread(lambda: tuple(api.path("interface")))
Diese klein wirkende Brücke ist im großen Stil entscheidend: Verbindung, Lesen, Befehl, also jeder Schritt, der mit dem Gerät spricht, steckt in to_thread. Andernfalls sieht das System “async” aus, läuft in der Praxis aber mit der Geschwindigkeit eines einzelnen Geräts.
Hinweis: In Sprachen wie Go lässt sich der gleichzeitige Zugriff auf Tausende Geräte mit Goroutinen natürlicher aufbauen. Da der Rest der Plattform (FastAPI, Datenmodell, Vertrautheit des Teams) in Python liegt, sind wir bei Python geblieben und haben es mit dieser Brücke ausgeglichen. Die Sprachwahl ist kein Richtig-oder-Falsch, sondern eine Kontextentscheidung.
Die heimtückischste Falle der API: der Unterschied zwischen “print” und “action”
In der RouterOS API sind das Lesen eines Menüs und das Senden einer Aktion an dieses Menü unterschiedliche Aufrufe, und das ist die Falle, in die Automatisierungs-Einsteiger am häufigsten tappen.
- Über
api.path("interface")zu iterieren führt im Hintergrund/interface/printaus, es liest also. - Aber Befehle wie
reboot,upgradeoderbackup savekönnen auf diesem Weg nicht gesendet werden; dafür ist ein separater Aufruf nötig, der den Befehl direkt ausführt (etwaapi(cmd="/system/reboot")).
Ohne dieses Wissen verbringt man Stunden mit der Frage “warum funktioniert der Reboot nicht”. In unserem Code ist diese Unterscheidung am Anfang jeder Aktionsfunktion per Kommentar markiert, damit wir nicht ein halbes Jahr später in dieselbe Falle tappen.
Eine damit zusammenhängende Tatsache: Dass die Verbindung nach einem Reboot abbricht, ist normal. Während das Gerät neu startet, wird die API-Sitzung naturgemäß getrennt; diese Ausnahme darf nicht als Fehler gewertet, sondern muss geschluckt (und als “Gerät wurde neu gestartet” protokolliert) werden.
Warum /export in der API fehlt und man auf SSH ausweichen muss
Der klassische Weg, einen vollständigen und lesbaren Konfigurations-Dump eines MikroTik zu erhalten, ist der Befehl /export. Aber die Binary-API liefert kein /export zurück. Das war eine der konkretesten Wände, gegen die wir beim Aufbau der Automatisierung gelaufen sind.
Es gibt zwei Lösungen, und wir nutzen beide:
- Echtes
/exportper SSH: Wenn ein originalgetreuer Dump der Konfiguration nötig ist (z. B. für Audit oder Archiv), öffnen wir per paramiko eine SSH-Verbindung und holen die/export-Ausgabe. Das ist das perfekte Beispiel für das Prinzip “SSH nur für eng umgrenzte Aufgaben behalten”. - “Pseudo-Export” aus der API: Die Menüs Abschnitt für Abschnitt auslesen und einen RSC-ähnlichen Text erzeugen. Erfordert kein SSH, ist aber nicht so vollständig wie
/export.
Die Lektion: Die Binary-API ist mächtig, deckt aber nicht alles ab; eine ausgereifte Automatisierung muss dort, wo die API endet, sauber auf SSH umschalten können.
Sichere Massenänderung: desired state → diff → idempotenter Befehl → Verifizierung
Eine Massenänderung der Konfiguration muss nicht beängstigend sein; beängstigend ist die blinde Änderung. Unsere Reconcile-Schleife (Abgleich) durchläuft folgende Schritte:
- Desired State: Der Soll-Zustand des Geräts wird aus einer YAML-Vorlage erzeugt (NTP, SNMP, Firewall-Basis, Verwaltungsnutzer usw.).
- Actual State: Die aktuelle Konfiguration wird per API vom Gerät gelesen.
- Diff: Die beiden Zustände werden Abschnitt für Abschnitt verglichen; nur die Differenz (Drift) wird berechnet.
- Vorab-Backup: Vor Anwendung der Änderung wird ein Konfigurations-Backup des Geräts angelegt: die Garantie für einen Rückweg.
- Idempotente Anwendung: Die Befehle werden nach der Logik “vorhanden: nicht anfassen, fehlend: hinzufügen” (
add-if-missing) und “finden und aktualisieren” (set-by-find) erzeugt. Selbst wenn derselbe Reconcile zweimal läuft, ändert sich das Ergebnis nicht. - Verifizierung: Das Gerät wird erneut gelesen und bestätigt, dass der Drift auf null zurückgegangen ist.
Der praktische Wert der Idempotenz ist folgender: Bricht ein Reconcile wegen einer Netzwerkunterbrechung ab, ist das kein Grund zur Panik. Den Job erneut auszuführen vervollständigt die fehlenden Teile, ohne die bereits angewandten Schritte zu wiederholen. Ein Teilerfolg wird zudem ausdrücklich als partial markiert; selbst wenn ein Befehl fehlschlägt, werden die übrigen weiter versucht und das Ergebnis wird ehrlich berichtet.
Diese Disziplin ist der einzig nachhaltige Weg, Firewall-Regeln, VLAN-Konfigurationen oder zentrale WLAN-Einstellungen (CAPsMAN) über Hunderte Geräte hinweg konsistent zu halten.
Unterschiede zwischen RouterOS v6 und v7: wo die Automatisierung den meisten Code verbraucht
Es ist nicht möglich, mit einer einzigen Befehlsvorlage sowohl RouterOS-6- als auch -7-Geräte zu verwalten; die Versionsunterschiede müssen in die Automatisierung selbst eingebaut werden. Das, worauf wir in der Praxis am häufigsten stoßen:
| Thema | RouterOS v6 | RouterOS v7 |
|---|---|---|
| BGP | /routing/bgp/peer |
/routing/bgp/connection |
| NTP | primary-ntp / secondary-ntp (separate Felder) |
servers= (kommagetrennte Liste) |
| Bridge-VLAN-Filtering | Eingeschränkt / nicht ausgereift | Voll unterstützt |
| WireGuard | Nicht vorhanden | Vorhanden (mit v7 eingeführt) |
Der praktische Ansatz: Nach dem Verbindungsaufbau zuerst die RouterOS-Version auslesen, die Major-Version bestimmen und die Befehlserzeugung entsprechend verzweigen. Fallbacks nach dem Muster “den v7-Weg versuchen, sonst auf den v6-Weg zurückfallen” sind unvermeidlich. Das ist eine Schicht, die den Code aufbläht, in der Praxis aber unverzichtbar ist. Wenn Sie den Versionsumstieg als Dienstleistung betrachten, gehen wir auf der Seite zum MikroTik-Support gesondert auf den Übergang von RouterOS 6 zu 7 ein.
Zugangsdaten und Nachvollziehbarkeit: Sicherheit im großen Stil
Ein System, das Zugriff nicht auf ein einzelnes, sondern auf Hunderte Geräte vorhält, ist im Fall einer Kompromittierung ein weitaus wertvolleres Ziel. Die Mindestlinien, an denen wir festhalten:
- Passwörter werden verschlüsselt gespeichert: Die Gerätepasswörter liegen in der Datenbank nicht im Klartext, sondern als per symmetrischer Verschlüsselung (Fernet) erzeugter Ciphertext vor; der Schlüssel wird in einer Umgebungsvariable gehalten und gelangt niemals ins Repository. Das Passwort wird erst in dem Moment, in dem ein Worker sich mit einem Gerät verbindet, im Arbeitsspeicher entschlüsselt. (Ehrliche Grenze: Das ist kein HashiCorp Vault / KMS, sondern eine env-basierte Lösung: die Sicherheit hängt an einem einzigen Schlüssel und ist ein Reifungsfeld.)
- Audit-Log: Jeder Job wird mit der Information “wer hat ausgelöst” (
created_by: Nutzer / Scheduler / automatisch) protokolliert. Jede Geräteaktion (Backup erstellt, Reconcile angewandt/fehlgeschlagen, Reboot erkannt) wird mit Wer-Was-Wann-Detail in eine eigene Ereignistabelle geschrieben. - Geringste Rechte: Auf Anwendungsseite gibt es rollenbasierten Zugriff (viewer als Standard, Verwaltungsoperationen erfordern admin) und gruppenbasierte Mandantenfähigkeit. Auf Geräteseite wird die von der Automatisierung hinzugefügte SNMP-Community schreibgeschützt (
read-access=yes, write-access=no) angelegt. (Die Rechte der geräteseitigen Verwaltungsnutzer einzuschränken, ist hingegen ein Bereich, den wir laufend verbessern; ehrlicherweise ist das Ideal der “geringsten Rechte” hier nicht immer leicht zu erreichen.)
Und wie groß ist dieser Maßstab wirklich?
Wir haben die Plattform mit dem Ziel von 50.000+ Geräten entworfen; die Architektur (Warteschlange, horizontale Worker, verteiltes Lock, Circuit Breaker) haben wir so ausgelegt, dass sie diese Größenordnung trägt. Hier ist Ehrlichkeit wichtig: 50.000 ist keine im Live-Betrieb nachgewiesene Zahl, sondern ein Design-Ziel. Dass eine Architektur so dimensioniert ist, dass sie diesen Maßstab trägt, ist nicht dasselbe wie tatsächlich in diesem Maßstab betrieben worden zu sein; Letzteres lässt sich nur unter realer Last nachweisen.
Die praktische Schlussfolgerung für Sie: Bei 10–20 Geräten genügen manuelle Verwaltung oder einfache Skripte. Sobald Sie zu 100+ Geräten, zu mehreren Standorten oder in die Position eines Dienstleisters übergehen, der MikroTik für seine Kunden verwaltet, ist die obige Architektur (strukturierte API + Arbeitswarteschlange + idempotenter Reconcile + Nachvollziehbarkeit) kein “Luxus”, sondern die Vorbedingung für Nachhaltigkeit.
Selbst aufbauen oder verwalten lassen?
Alles in diesem Beitrag ist umsetzbar und lässt sich mit Open-Source-Werkzeugen (Python, librouteros, Redis, PostgreSQL) aufbauen. Aber man muss das ehrliche Bild sehen: die Unterschiede zwischen v6/v7, Idempotenz, Reliable Queue, Circuit Breaker und sichere Credential-Verwaltung sind eine ernsthafte Ingenieursinvestition, und ihre Wartung ist fortlaufend.
Wenn Sie es mit Ihrem eigenen Team aufbauen, bietet Ihnen dieser Beitrag eine realistische Roadmap und eine Liste von Fallstricken. Wenn Sie diese Last nicht tragen möchten, können Sie die zentrale und nachvollziehbare Verwaltung zahlreicher MikroTik-Geräte als Dienstleistung von Teams wie unserem beziehen; dafür sind unsere Seiten zur Netzwerk-Infrastruktur und zum MikroTik-Support da. In beiden Fällen gilt dasselbe Schlüsselprinzip: Verwalten Sie Ihre Geräte nicht von Hand, sondern mit einem wiederholbaren und überprüfbaren System.
Kaynaklar
- librouteros: Python-Client für die RouterOS API — PyPI / librouteros (2026)
- Offizielle Dokumentation der RouterOS API — MikroTik (2026)
- Offizielle RouterOS-Dokumentation von MikroTik — MikroTik (2026)
Sıkça Sorulan Sorular
Sollte ich die RouterOS API oder SSH verwenden?+
Für die programmatische Verwaltung im großen Stil ist die Binary-API von RouterOS (8728/8729) deutlich besser geeignet als SSH: Sie liefert strukturierte Daten zurück, Sie müssen keine Befehlsausgabe als Text parsen, und idempotente 'add/set/find'-Operationen werden direkt unterstützt. SSH behalten wir nur für eng umgrenzte Aufgaben, die die API nicht abdeckt; das typischste Beispiel ist das Abrufen der `/export`-Ausgabe, für die es in der API keine Entsprechung gibt.
Welchen Port verwendet die RouterOS API?+
Die unverschlüsselte API läuft auf Port 8728, die TLS-gesicherte API (api-ssl) auf Port 8729. Bei einer über das Internet erreichbaren Verwaltung sollte ausschließlich 8729 (api-ssl) genutzt und der Zugriff auf vertrauenswürdige Quellen beschränkt werden; das unverschlüsselte 8728 ist nur in einem sicheren/internen Verwaltungsnetz vertretbar. Der API-Dienst wird unter `/ip service` aktiviert und per Adressfilter eingeschränkt.
Wie sendet man gleichzeitig Befehle an Hunderte MikroTik-Geräte?+
Der richtige Ansatz im großen Stil besteht nicht darin, in einem einzigen Prozess Tausende gleichzeitiger Verbindungen zu öffnen; stattdessen erzeugt man für jedes Gerät einen eigenen 'Job', legt diese in eine Warteschlange (wir nutzen Redis) und lässt viele Worker die Warteschlange parallel abarbeiten. So skaliert die Parallelität horizontal mit der Anzahl der Worker, ein einzelnes langsames Gerät blockiert nicht das ganze System, und dank eines gerätespezifischen Locks kollidieren keine zwei Änderungen am selben Gerät.
Ist eine Massenänderung der Konfiguration sicher?+
Richtig aufgesetzt, ja. Unser Ablauf sieht so aus: den gewünschten Zustand (desired state) aus einer Vorlage erzeugen, ihn mit dem vom Gerät gelesenen tatsächlichen Zustand (actual state) vergleichen (diff), vor jeder Änderung ein Konfigurations-Backup anlegen, die Befehle idempotent anwenden (vorhanden: nicht anfassen, fehlend: hinzufügen) und anschließend erneut lesen, um zu bestätigen, dass der Drift auf null zurückgegangen ist. Dank der Idempotenz lässt sich ein abgebrochener Vorgang gefahrlos erneut ausführen.
Ist die API von RouterOS v6 und v7 identisch?+
Nein, es gibt bedeutende Unterschiede, und genau hier steckt die Automatisierung den meisten Code hinein. Beispielsweise liegt BGP in v7 unter `/routing/bgp/connection`, in v6 unter `/routing/bgp/peer`; die NTP-Einstellung wird in v7 kommagetrennt über `servers=` übergeben, während v6 separate Felder `primary-ntp`/`secondary-ntp` nutzt; das Bridge-VLAN-Filtering ist erst mit v7 ausgereift. Die Automatisierung muss die RouterOS-Version des Geräts auslesen und den Befehl entsprechend erzeugen.
Profesyonel Destek mi Lazım?
Bu konuda yardıma ihtiyacın varsa yanındayız. Kurulum, konfigürasyon ve sorun giderme için ulaş.
