关于 routeros-firewall
routeros-firewall 是面向 MikroTik RouterOS 防火墙配置的技能,说明规则顺序、地址列表与接口列表、安全脚本模式、连接状态、NAT 及常见错误。
主要功能
- 01自上而下的规则顺序
- 02地址列表和接口列表模式
- 03用于幂等脚本的注释标签
- 04连接状态与 FastTrack 指引
- 05NAT 和 Layer7 示例
- 06常见 RouterOS 防火墙问题
适用场景
- 01正确安排 accept 与 drop 规则
- 02用一条规则匹配多组 IP 或接口
- 03重复运行脚本而不删除无关规则
- 04检查 FastTrack、mangle 与 IPv6 行为
MCP 相关
该技能提及 rosetta MCP,可通过 `routeros_search` 和 `routeros_get_page` 检查 `/ip/firewall` 命令树。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tikoci/ routeros-skills --skill routeros-firewall安装后在 Claude Code 中输入/routeros-firewall确认已加载。
附带文件references/dos-protection.mdreferences/mangle-routing.md
详细介绍
RouterOS 防火墙
规则顺序 — 按顺序匹配,而非基于优先级
规则按从上到下的顺序评估——匹配到的第一条规则生效。这是最容易造成 iptables 混淆的地方。
place-before=0会将规则插入顶部;默认情况下,add会将规则追加到底部- 对于相同流量,
action=accept规则必须位于任何action=drop规则之前 - 非终止操作不会停止评估:
action=add-src-to-address-list、action=add-dst-to-address-list、action=log,以及任何设置了passthrough=yes的规则,都会继续评估下一条规则。位于add-src-to-address-list下方的drop规则仍会生效。
# WRONG — drop fires before accept can match
/ip/firewall/filter/add chain=input action=drop
/ip/firewall/filter/add chain=input src-address=10.0.0.1 action=accept
# CORRECT — accept first, drop catches the rest
/ip/firewall/filter/add chain=input src-address=10.0.0.1 action=accept place-before=0
/ip/firewall/filter/add chain=input action=drop
将地址列表用作动态选择器
LLM 很少会建议这种模式——它们通常会为每个 IP 地址分别编写一条规则。地址列表只需一条防火墙规则,就能处理数百个 IP。
# Build the list (static or dynamic with auto-expiry)
/ip/firewall/address-list/add list=trusted-mgmt address=192.168.1.0/24
/ip/firewall/address-list/add list=trusted-mgmt address=10.0.0.5 timeout=1h
# One rule handles all list members
/ip/firewall/filter/add chain=input src-address-list=trusted-mgmt action=accept \
comment="myapp-accept-mgmt"
带有 timeout= 的动态条目会自动过期——这是 DoS 黑名单的主要模式。
将接口列表用作规则选择器
in-interface-list= / out-interface-list=——这是一个强大的 RouterOS 模式,但 LLM 从不会提出。多个接口承担相同角色时,它可以消除重复规则。
# Define the group once
/interface/list/add name=WAN
/interface/list/member/add list=WAN interface=ether1
/interface/list/member/add list=WAN interface=pppoe-out1
# One rule applies to all WAN interfaces
/ip/firewall/filter/add chain=input in-interface-list=WAN action=drop \
comment="myapp-drop-all-wan"
注释即标签模式(幂等脚本)
RouterOS 没有“upsert”功能——如果不先清理就重新运行脚本,会产生重复规则。可以使用注释前缀作为标签:
# Remove only rules we own — preserves rules from other tools
/ip/firewall/filter/remove [find comment~"myapp-"]
/ip/firewall/address-list/remove [find comment~"myapp-"]
/ip/firewall/nat/remove [find comment~"myapp-"]
# Add with consistent tag — readable in /print output
/ip/firewall/filter/add chain=input src-address-list=trusted-mgmt action=accept \
comment="myapp-accept-mgmt"
/ip/firewall/filter/add chain=input in-interface-list=WAN action=drop \
comment="myapp-drop-wan"
切勿使用 remove [find dynamic=no]——这会删除所有静态规则,包括由管理工具添加的规则。有些工具(例如 OptiWize)会用 comment~"#orchestrator-*" 标记其规则——批量删除会在不提示的情况下破坏远程管理。
连接状态
RouterOS 的 connection-state= 不等同于 iptables 的 -m state:
/ip/firewall/filter/add chain=input connection-state=established,related action=accept
/ip/firewall/filter/add chain=input connection-state=invalid action=drop
RouterOS 状态:new、established、related、invalid、untracked。
untracked 匹配通过 /ip/firewall/raw action=notrack 显式标记的数据包——它不会匹配 FastTrack 流。FastTrack 是一种独立的快速路径,会将流保留在 conntrack 中,但绕过 mangle。切勿在同一流量上同时使用 fasttrack-connection 和基于 mangle 的路由标记——mangle 标记不会应用于 FastTrack 数据包。
NAT 模式
# Port forward (dst-nat)
/ip/firewall/nat/add chain=dstnat \
dst-port=8080 protocol=tcp in-interface=ether1 \
action=dst-nat to-addresses=192.168.1.10 to-ports=80 \
comment="portfwd-web"
# Force DNS through router (prevents DNS bypass)
/ip/firewall/nat/add chain=dstnat action=redirect \
in-interface-list=LAN dst-port=53 protocol=udp to-ports=53 \
comment="force-dns-udp"
/ip/firewall/nat/add chain=dstnat action=redirect \
in-interface-list=LAN dst-port=53 protocol=tcp to-ports=53 \
comment="force-dns-tcp"
# Masquerade outgoing traffic
/ip/firewall/nat/add chain=srcnat action=masquerade \
out-interface=ether1 comment="nat-wan"
Layer7 协议(L7)
L7 使用 POSIX 正则表达式匹配未加密的负载内容——这会消耗大量 CPU,请谨慎使用:
/ip/firewall/layer7-protocol/add \
name=captive-detect \
regexp="^.*(gstatic|connectivitycheck|generate_204).*$" \
comment="android-captive-portal"
L7 的交替写法:(a|b|c) 是正确的。(a)|(b)|(c) 存在 POSIX ERE 运算符优先级问题——中间分支 (b) 会在流中的任意位置匹配,而不会受锚定限制。只使用在一对括号内包含 | 的分组形式。
LLM 常见错误
| 错误 | RouterOS 的正确行为 |
|---|---|
使用 priority= 或规则权重 | 规则按顺序执行——规则位置决定顺序,而非权重 |
| 为每个 IP 地址编写一条规则 | 使用 src-address-list= 或 dst-address-list= |
在脚本中使用 remove [find dynamic=no] | 使用基于标签的方式:仅执行 remove [find comment~"prefix-"] |
忘记在 accept 规则中设置 place-before= | 默认追加到末尾——位于 drop 规则下方的 accept 规则永远不会生效 |
使用 connection-state=new,established | 有效状态:new、established、related、invalid、untracked |
认为 action=log 或 passthrough=yes 会停止评估 | 非终止操作会继续执行下一条规则——下方的 drop 规则仍会生效 |
| 将 fasttrack 与 mangle 路由标记结合使用 | fasttrack 会绕过 mangle——二者只能择一 |
| 在 L7 正则表达式中使用 `(a) | (b) |
| 每个接口都写一条防火墙规则 | 使用带有命名接口列表的 in-interface-list= |
使用 /ip/firewall 处理 IPv6 流量 | IPv6 使用独立的 /ipv6/firewall——规则不会跨协议生效 |
其他资源
相关技能:
routeros-fundamentals— RouterOS CLI 语法、REST API、脚本基础routeros-hotspot— hotspot 链与防火墙、walled garden 的交互
此技能中的参考文件:
- references/mangle-routing.md — 使用路由标记进行策略路由,
hotspot=auth匹配器 - references/dos-protection.md —
psd、tarpit、connection-limitDoS 模式
MCP 工具:
rosettaMCP —/ip/firewall命令树检查(routeros_search、routeros_get_page)
MikroTik 文档: