MikroTik API Management
Communicate with MikroTik RouterOS devices using the Python routeros-api library over the API port (8728 plain, 8729 SSL).
Prerequisites
Install the library if not present:
CODEBLOCK0
Connection
It is highly recommended to use environment variables for credentials to avoid hardcoding.
Environment Variables
Set these in your environment or
.env file:
- -
MIKROTIK_HOST: Router IP or hostname - INLINECODE3 : Router username
- INLINECODE4 : Router password
Python Connection Pattern
CODEBLOCK1
Connection Rules
- - Prefer Environment Variables: Instruct the user to set
MIKROTIK_HOST, MIKROTIK_USERNAME, and MIKROTIK_PASSWORD. - Ask the user for these details only if not found in the environment.
- Default API port is 8728 (plain) or 8729 (SSL).
- Always call
conn.disconnect() when done. - Use
plaintext_login=True for RouterOS v6.43+ and v7.x.
SSL Connection
CODEBLOCK2
Core API Operations
Reading resources (GET / print)
CODEBLOCK3
Adding entries (ADD)
CODEBLOCK4
Updating entries (SET)
CODEBLOCK5
Removing entries (REMOVE)
``
python\nresource = api.get_resource('/ip/address')
resource.remove(id='*1')
CODEBLOCK6 python
resource = api.get_resource('/system')
resource.call('reboot')
# Call with parameters
resource = api.get_resource('/ip/firewall/filter')
resource.call('move', {'numbers': '*1', 'destination': '*5'})
CODEBLOCK7 python
resource = api.get_resource('/interface')
resource.set(id='*1', disabled='yes') # Disable
resource.set(id='*1', disabled='no') # Enable
CODEBLOCK8 python
resource = api.get_resource('/ip/firewall/filter')
rules = resource.get(chain='forward', action='drop')
CODEBLOCK9 python
resource = api.get_resource('/ip/firewall/filter')
resource.add(
chain='forward',
action='accept',
src_address='10.0.0.0/8',
place_before='*5' # Insert before rule *5
)
CODEBLOCK10 python
resource = api.get_resource('/ip/firewall/filter')
resource.call('move', {'numbers': '*A', 'destination': '*1'})
CODEBLOCK11 python
resource = api.get_resource('/ip/firewall/address-list')
ips = ['1.2.3.4', '5.6.7.8', '9.10.11.12']
for ip in ips:
resource.add(list='blocklist', address=ip, comment='Blocked via API')
CODEBLOCK12 python
resource = api.get_resource('/interface')
ifaces = resource.get(name='ether5')
if ifaces:
resource.set(id=ifaces[0]['id'], disabled='yes')
CODEBLOCK13 python
# The library always returns all properties; filter in Python:
resource = api.get_resource('/interface')
for iface in resource.get():
print(iface.get('name'), iface.get('type'), iface.get('running'))
CODEBLOCK14 python
# Tools that produce output need call() with parameters
resource = api.get_resource('/tool')
# Note: Some tools (ping, traceroute) run indefinitely.
# Use count parameter to limit.
result = resource.call('ping', {'address': '8.8.8.8', 'count': '4'})
for r in result:
print(r)
CODEBLOCK15 python
# Create a backup file
resource = api.get_resource('/system/backup')
resource.call('save', {'name': 'api-backup'})
# Export config to file
resource = api.get_resource('/')
resource.call('export', {'file': 'api-export'})
CODEBLOCK16 python
resource = api.get_resource('/system')
resource.call('reboot')
# resource.call('shutdown')
CODEBLOCK17 python
resource = api.get_resource('/system/package/update')
resource.call('check-for-updates')
result = resource.get()
print(result)
# resource.call('install') # Install and reboot
CODEBLOCK18 bash
# GET - Read resources
curl -k -u user:pass https://<IP>/rest/ip/address
# PUT - Create new entry
curl -k -u user:pass -X PUT https://<IP>/rest/ip/address \
--data '{"address":"192.168.1.1/24","interface":"ether1"}' \
-H "content-type: application/json"
# PATCH - Update entry
curl -k -u user:pass -X PATCH https://<IP>/rest/ip/address/*1 \
--data '{"comment":"updated"}' -H "content-type: application/json"
# DELETE - Remove entry
curl -k -u user:pass -X DELETE https://<IP>/rest/ip/address/*1
# POST - Run any command
curl -k -u user:pass -X POST https://<IP>/rest/ip/address/print \
--data '{"_proplist":["address","interface"]}' \
-H "content-type: application/json"
CODEBLOCK19 bash
curl -k -u user:pass -X POST https://<IP>/rest/interface/print \
--data '{".query":["type=ether"],"_proplist":["name","type","running"]}' \
-H "content-type: application/json"
CODEBLOCK20 python
import requests
from requests.auth import HTTPBasicAuth
base = 'https://<IP>/rest'
auth = HTTPBasicAuth('<USER>', '<PASS>')
# GET all interfaces
r = requests.get(f'{base}/interface', auth=auth, verify=False)
print(r.json())
# POST (run commands with parameters)
r = requests.post(f'{base}/ip/address/print',
auth=auth, verify=False,
json={'_proplist': ['address', 'interface']})
print(r.json())
CODEBLOCK21 python
import routeros_api
from routeros_api.exceptions import RouterOsApiCommunicationError
try:
conn = routeros_api.RouterOsApiPool(host, username=user, password=pw, plaintext_login=True)
api = conn.get_api()
resource = api.get_resource('/ip/address')
resource.add(address='invalid', interface='nonexistent')
except RouterOsApiCommunicationError as e:
print(f"API Error: {e}")
except ConnectionError:
print("Cannot reach router")
finally:
try:
conn.disconnect()
except:
pass
`
### API Error Categories
| Code | Meaning |
|------|---------|
| 0 | Missing item or command |
| 1 | Argument value failure |
| 2 | Command interrupted |
| 3 | Scripting related failure |
| 4 | General failure |
| 5 | API related failure |
| 6 | TTY related failure |
| 7 | Value from :return command |
## Workflow
1. **Connect** to the router using credentials from environment variables or the user.
2. **Read first** — always fetch current state before making changes.
3. **Confirm** destructive operations (delete, disable, reboot, firewall changes) with the user.
4. **Apply changes** using add/set/remove.
5. **Verify** by reading back the resource after changes.
6. **Disconnect** when done.
## Important Notes
- The id
field in responses (e.g., 1, A
) is the internal MikroTik ID used for set/remove.
- Use underscore in Python kwargs for hyphenated RouterOS attributes: src-address
→ src
address.
- Filter and NAT rules are **order-sensitive** — use placebefore
when adding to control position.
- Always show the user what currently exists before modifying firewall rules.
- For bulk operations, iterate over results and apply changes one by one.
- RouterOS 7.x uses different paths for routing (e.g., /routing/ospf/instance
not /routing/ospf
).
- If the API port is closed, advise the user to enable it: /ip/service enable api
.
- Tools like ping/traceroute run indefinitely — always pass count
or duration
parameter.
- REST API requires www
or www-ssl
service enabled on the router.
- REST API has a **60-second timeout** for commands; use limiting params (count
, duration
, once`).
MikroTik API 管理
使用 Python 的 routeros-api 库通过 API 端口(8728 明文,8729 SSL)与 MikroTik RouterOS 设备通信。
前置条件
如果未安装该库,请执行以下命令:
bash
pip3 install --break-system-packages routeros-api
连接
强烈建议使用环境变量存储凭据,避免硬编码。
环境变量
在环境或 .env 文件中设置以下变量:
- - MIKROTIKHOST:路由器 IP 或主机名
- MIKROTIKUSERNAME:路由器用户名
- MIKROTIK_PASSWORD:路由器密码
Python 连接模式
python
import routeros_api
import os
从环境变量获取凭据
host = os.getenv(MIKROTIK_HOST)
username = os.getenv(MIKROTIK_USERNAME)
password = os.getenv(MIKROTIK_PASSWORD)
如果环境变量缺失,回退到手动输入
if not all([host, username, password]):
print(环境变量 MIKROTIK
HOST、MIKROTIKUSERNAME 或 MIKROTIK_PASSWORD 未设置。)
# host = input(输入主机:) ...
conn = routeros_api.RouterOsApiPool(
host=host,
username=username,
password=password,
plaintext_login=True, # RouterOS 6.43+ 需要
port=8728 # SSL 使用 8729
)
api = conn.get_api()
... 执行操作 ...
conn.disconnect()
连接规则
- - 优先使用环境变量:指导用户设置 MIKROTIKHOST、MIKROTIKUSERNAME 和 MIKROTIKPASSWORD。
- 仅在环境变量中未找到时,才向用户询问这些详细信息。
- 默认 API 端口为 8728(明文)或 8729(SSL)。
- 操作完成后始终调用 conn.disconnect()。
- RouterOS v6.43+ 和 v7.x 使用 plaintextlogin=True。
SSL 连接
python
conn = routeros_api.RouterOsApiPool(
host=host,
username=username,
password=password,
plaintext_login=True,
use_ssl=True,
ssl_verify=False, # 使用正确证书时设为 True
ssl
verifyhostname=False,
port=8729
)
核心 API 操作
读取资源(GET / print)
python
resource = api.get_resource(/ip/address)
items = resource.get() # 获取所有
items = resource.get(interface=ether1) # 按参数过滤
items = resource.get(disabled=false) # 按状态过滤
添加条目(ADD)
python
resource = api.get_resource(/ip/address)
resource.add(address=192.168.1.1/24, interface=ether1)
带注释
resource.add(address=192.168.1.1/24, interface=ether1, comment=管理)
更新条目(SET)
python
resource = api.get_resource(/ip/address)
resource.set(id=*1, address=192.168.2.1/24)
resource.set(id=*1, comment=通过 API 更新)
resource.set(id=*1, disabled=yes) # 禁用条目
resource.set(id=*1, disabled=no) # 启用条目
删除条目(REMOVE)
python
resource = api.get_resource(/ip/address)
resource.remove(id=*1)
调用命令(CALL)
python
resource = api.get_resource(/system)
resource.call(reboot)
带参数调用
resource = api.get_resource(/ip/firewall/filter)
resource.call(move, {numbers:
1, destination: 5})
启用/禁用条目
python
resource = api.get_resource(/interface)
resource.set(id=*1, disabled=yes) # 禁用
resource.set(id=*1, disabled=no) # 启用
完整资源路径参考
系统
| 任务 | 资源路径 |
|---|
| 系统信息(CPU、内存、运行时间) | /system/resource |
| 路由器标识 |
/system/identity |
| 系统时钟 | /system/clock |
| NTP 客户端 | /system/ntp/client |
| NTP 服务器 | /system/ntp/server |
| 调度器 | /system/scheduler |
| 脚本 | /system/script |
| 日志规则 | /system/logging |
| 日志条目 | /log |
| 软件包 | /system/package |
| 软件包更新 | /system/package/update |
| 路由器板信息 | /system/routerboard |
| 许可证 | /system/license |
| 健康状态(电压、温度) | /system/health |
| 历史记录 | /system/history |
| 用户 | /user |
| 用户组 | /user/group |
| 活跃用户 | /user/active |
| SSH 密钥 | /user/ssh-keys |
| 文件 | /file |
| 备份 | /system/backup |
| SNMP | /snmp |
| SNMP 团体 | /snmp/community |
| 证书 | /certificate |
| 控制台 | /system/console |
| LED | /system/leds |
接口
/interface/ethernet |
| 桥接 | /interface/bridge |
| 桥接端口 | /interface/bridge/port |
| 桥接 VLAN | /interface/bridge/vlan |
| 桥接主机(MAC 表) | /interface/bridge/host |
| 桥接 MSTi | /interface/bridge/msti |
| 桥接设置 | /interface/bridge/settings |
| VLAN | /interface/vlan |
| 绑定(LACP/绑定) | /interface/bonding |
| EoIP 隧道 | /interface/eoip |
| GRE 隧道 | /interface/gre |
| IPIP 隧道 | /interface/ipip |
| VXLAN | /interface/vxlan |
| VXLAN VTEP | /interface/vxlan/vtep |
| WireGuard | /interface/wireguard |
| WireGuard 对等体 | /interface/wireguard/peers |
| L2TP 客户端 | /interface/l2tp-client |
| L2TP 服务器 | /interface/l2tp-server/server |
| SSTP 客户端 | /interface/sstp-client |
| SSTP 服务器 | /interface/sstp-server/server |
| OVPN 客户端 | /interface/ovpn-client |
| OVPN 服务器 | /interface/ovpn-server/server |
| PPPoE 客户端 | /interface/pppoe-client |
| PPPoE 服务器 | /interface/pppoe-server/server |
| PPTP 客户端 | /interface/pptp-client |
| PPTP 服务器 | /interface/pptp-server/server |
| LTE | /interface/lte |
| LTE APN | /interface/lte/apn |
| 无线(旧版 WiFi) | /interface/wireless |
| WiFi(新版,ROS 7) | /interface/wifi |
| WiFi 信道 | /interface/wifi/channel |
| WiFi 数据路径 | /interface/wifi/datapath |
| WiFi 安全 | /interface/wifi/security |
| WiFi 配置 | /interface/wifi/configuration |
| WiFi 配置 | /interface/wifi/provisioning |
| WiFi 注册表 | /interface/wifi/registration-table |
| WiFi 访问列表 | /interface/wifi/access-list |
| WiFi 互通 | /interface/wifi/interworking |
| 接口列表 | /interface/list |
| 接口列表成员 | /interface/list/member |
| 以太网交换机 | /interface/ethernet/switch |
| 以太网交换机端口 | /interface/ethernet/switch/port |
| 流量监控 | /interface/monitor-traffic |
IP
| 任务 | 资源路径 |
|---|
| IP 地址 | /ip/address |
| ARP 表 |
/ip/arp |
| 路由 | /ip/route |
| 路由规则 | /ip/route/rule |
| DNS 设置 | /ip/dns |
| DNS 静态条目 | /ip/dns/static |
| DNS 缓存 | /ip/dns/cache |
| DHCP 客户端