Connection tracking
MikroTik RouterOS 中的连接跟踪(connection tracking)通过监控逻辑网络连接来实现有状态防火墙功能,并支持 NAT 及多种防火墙特性。它把数据包归入 new、established、related、invalid 或 untracked 等状态,同时使用 FastTrack 优化 TCP/UDP 数据包转发。
Connection tracking
连接跟踪让内核能够跟踪所有逻辑网络连接或会话,从而将构成该连接的所有数据包关联起来。
NAT 依赖这些信息,以相同的方式转换所有相关的数据包。
借助连接跟踪,即使对于 UDP 这类无状态协议,也可以使用有状态防火墙功能。
受连接跟踪影响的防火墙功能
- NAT
- 防火墙:
- connection-bytes
- connection-mark
- connection-type
- connection-state
- connection-limit
- connection-rate
- layer7-protocol
- new-connection-mark
- tarpit
已跟踪连接的列表可在 IPv4 的 /ip/firewall/connection 和 IPv6 的 /ipv6/firewall/connection 中查看。
[admin@3C22-atombumba] /ip/firewall/connection> print
Flags: S - seen-reply, A - assured
# PR.. SRC-ADDRESS DST-ADDRESS TCP-STATE TIMEOUT
0 udp 10.5.8.176:5678 255.255.255.255:5678 0s
1 udp 10.5.101.3:646 224.0.0.2:646 5s
2 ospf 10.5.101.161 224.0.0.5 9m58s
3 udp 10.5.8.140:5678 255.255.255.255:5678 8s
4 SA tcp 10.5.101.147:48984 10.5.101.1:8291 established 4m59s
[admin@3C22-atombumba] /ipv6/firewall/connection> print
Flags: S - seen reply, A - assured
# PRO.. SRC-ADDRESS DST-ADDRESS TCP-STATE
0 udp fe80::d6ca:6dff:fe77:3698 ff02::1
1 udp fe80::d6ca:6dff:fe98:7c28 ff02::1
2 ospf fe80::d6ca:6dff:fe73:9822 ff02::5
连接状态
根据连接表条目,到达的数据包会被赋予以下连接状态之一:new、invalid、established、related 或 untracked。
当数据包被视为 new 时,有两种不同的情形。第一种是无状态连接(如 UDP)的情形,此时连接表中没有对应的连接条目。另一种是有状态协议(TCP)的情形。在这种情况下,开启新连接的新数据包始终是带有 SYN 标志的 TCP 数据包。
如果数据包不是 new,它可能属于 established 或 related 连接,也可能不属于任何连接,从而成为 invalid。处于 established 状态的数据包,正如大多数人已经猜到的那样,属于连接跟踪表中已存在的连接。related 状态与之非常相似,区别在于该数据包属于与某个已存在连接相关联的连接,例如 ICMP 错误数据包或 FTP 数据连接的数据包。
连接状态 untracked 是一种特殊情况,当使用 RAW 防火墙规则将连接排除在连接跟踪之外时出现。该规则会使所有转发的流量绕过连接跟踪,从而提高数据包经过设备的处理速度。
其他任何数据包都被视为 invalid,在大多数情况下应当被丢弃。
基于这些信息,我们可以设置一组基本的 filter 规则,通过接受 established/related 数据包、丢弃 invalid 数据包,并仅对 new 数据包进行更细致的过滤,来加快数据包过滤速度并降低 CPU 负载。
/ip/firewall/filter
add chain=input connection-state=invalid action=drop comment="Drop Invalid connections"
add chain=input connection-state=established,related,untracked action=accept comment="Allow Established/Related/Untracked connections"
危险
此类规则集不得应用于具有非对称路由的路由器,因为非对称路由的数据包可能被视为 invalid 并被丢弃。
FastTrack
IPv4 FastTrack 是一种特殊处理器,它绕过 Linux 的一些机制,从而实现更快的数据包转发。该处理器用于通过 fasttrack-connection 动作标记的 TCP 和 UDP 连接。IPv4 FastTrack 处理器支持 NAT(SNAT、DNAT 或两者)。
请注意,并非一条连接的所有数据包都能被 FastTrack 处理,因此即使连接已标记为 FastTrack,你也可能看到部分数据包走慢速路径。这就是 fasttrack-connection 之后通常紧跟一条相同的 action=accept 规则的原因。
经 FastTrack 处理的数据包会绕过:
- 防火墙。
- 连接跟踪。
- Simple queue。
- 带有 parent=global 的 queue tree。
- IP accounting。
- IPSec。
- Hotspot universal client。
- VRF 分配。
管理员需要确保 FastTrack 不会干扰其他配置。
前提条件
满足以下条件时,IPv4 FastTrack 才会生效:
- 没有 mesh、metarouter 接口配置。
- 未运行 sniffer、torch 或 traffic generator。
- 未主动使用
/tool/mac-scan。 - 未主动使用
/tool/ip-scan。 - 在 IP/Settings 下启用了 FastPath 和 Route cache。
示例
例如,对于采用出厂默认配置的 SOHO 路由器,你可以用这一条放在 Firewall Filter 顶部的规则来 FastTrack 所有 LAN 流量。同时还需要一条相同的 accept 规则:
/ip/firewall/filter/add chain=forward action=fasttrack-connection connection-state=established,related
/ip/firewall/filter/add chain=forward action=accept connection-state=established,related
提示
- 连接会一直处于 FastTrack 状态,直到连接关闭、超时或路由器重启。
- 只有删除/禁用 FastTrack 防火墙规则并重启路由器后,dummy 规则才会消失。
- 当设备上同时启用了 FastPath 和 FastTrack 时,同一时间只有一个能生效。
警告: Queue(除挂接到接口下的 Queue Tree 外)、防火墙 filter 和 mangle 规则不会应用于 FastTrack 处理的流量。
连接跟踪设置
连接跟踪设置通过 /ip/firewall/connection/tracking 菜单管理。
属性
| 属性 | 描述 |
|---|---|
| enabled (yes | no | auto; Default: auto) | 允许禁用或启用连接跟踪。连接跟踪被禁用时,上面列出的防火墙功能将停止工作。若设置为 "auto",则在至少添加一条防火墙规则之前,连接跟踪处于禁用状态。 |
| liberal-tcp-tracking (yes | no; Default: no) | 通过切换内核参数 nf_conntrack_tcp_be_liberal 来启用或禁用宽松的 TCP 连接跟踪。设为 yes 时,系统只把窗口之外的 RST 段标记为 INVALID。注意: 启用该设置可能放行原本会被防火墙 connection-state 匹配器视为 invalid 的畸形数据包,这会增加遭受某些规避技术攻击的风险。仅在排查问题或规避已知问题时才应启用此属性。 |
| loose-tcp-tracking (*yes | no*; Default: yes) |
| tcp-syn-sent-timeout (time; Default: 5s) | TCP SYN 超时。 |
| tcp-syn-received-timeout (time; Default: 5s) | TCP SYN 超时。 |
| tcp-established-timeout (time; Default: 1d) | 已建立的 TCP 连接在该时间后超时。 |
| tcp-fin-wait-timeout (time; Default: 10s) | |
| tcp-close-wait-timeout (time; Default: 10s) | |
| tcp-last-ack-timeout (time; Default: 10s) | |
| tcp-time-wait-timeout (time; Default: 10s) | |
| tcp-close-timeout (time; Default: 10s) | |
| udp-timeout (time; Default: 30s) | 指定只有一个方向有数据包的 UDP 连接的超时时间 |
| udp-stream-timeout (time; Default: 3m) | 指定两个方向都有数据包的 UDP 连接的超时时间 |
| icmp-timeout (time; Default: 10s) | ICMP 连接超时 |
| generic-timeout (time; Default: 10m) | 所有其他连接条目的超时时间 |
| tcp-max-retrans-timeout | |
| tcp-unacked-timeout |
只读属性
| 属性 | 描述 |
|---|---|
| max-entries (integer) | 连接跟踪表能够容纳的最大条目数量。该值取决于已安装的 RAM 容量。请注意,系统启动时并不会创建最大规模的连接跟踪表;如果有需要且系统仍有空闲 RAM,表可能会增大,但不会超过 1048576 |
| total-entries (integer) | 连接表当前保存的连接数量 |
| active-ipv4 | |
| active-ipv6 | |
| total-ip4-entries | |
| total-ip6-entries |
连接列表
已跟踪连接的列表可在 IPv4 的 /ip/firewall/connection 和 IPv6 的 /ipv6/firewall/connection 中查看。
属性
连接列表中的所有属性均为只读
| 属性 | 描述 |
|---|---|
| assured (yes | no) | 表示该连接已获保证,即使达到可跟踪连接的最大数量也不会被清除。 |
| confirmed (yes | no) | 连接已确认,并且有数据包从设备发出 |
| connection-mark (string) | 由 mangle 规则设置的连接标记。 |
| connection-type (pptp | ftp) | 连接类型;如果连接跟踪无法确定预定义的连接类型,该属性为空。 |
| dst-address (ip) | 目的地址。 |
| dst-port(integer) | 目的端口。 |
| dstnat (yes | no) | 连接经过了 DST-NAT(例如端口转发)。 |
| dying (yes | no) | 由于连接超时,该连接正在消亡。 |
| expected (yes | no) | 连接是使用 connection helper(预定义服务规则)建立的。 |
| fasttrack (yes | no) | 该连接是否被 FastTrack 处理。 |
| gre-key (integer) | GRE Key 字段的内容。 |
| gre-protocol (string) | 被封装的载荷的协议。 |
| gre-version (string) | 该连接中使用的 GRE 协议版本。 |
| hw-offload(yes | no) | 硬件卸载的连接。 |
| icmp-code (string) | ICMP Code 字段 |
| icmp-id (integer) | 包含 ICMP ID |
| icmp-type (integer) | ICMP Type 编号 |
| orig-bytes (integer) | 使用该特定连接从源地址发出的字节数。 |
| orig-fasttrack-bytes (integer) | 使用该特定连接从源地址发出的、经 FastTrack 处理的字节数。 |
| orig-fasttrack-packets (integer) | 使用该特定连接从源地址发出的、经 FastTrack 处理的数据包数。 |
| orig-packets (integer) | 使用该特定连接从源地址发出的数据包数。 |
| orig-rate (integer) | 使用该特定连接从源地址发出数据包的数据速率。 |
| protocol (string) | IP 协议类型 |
| repl-bytes (integer) | 使用该特定连接从目的地址接收到的字节数。 |
| repl-fasttrack-bytes (integer) | 使用该特定连接从目的地址接收到的、经 FastTrack 处理的字节数。 |
| repl-fasttrack-packets (integer) | 使用该特定连接从目的地址接收到的、经 FastTrack 处理的数据包数。 |
| repl-packets (integer) | 使用该特定连接从目的地址接收到的数据包数。 |
| repl-rate (string) | 使用该特定连接从目的地址接收数据包的数据速率。 |
| reply-dst-address (ip) | 返回数据包的预期目的地址。 |
| reply-dst-port(integer) | 返回数据包的预期目的端口。 |
| reply-src-address (ip) | 返回数据包的预期源地址。 |
| reply-src-port (integer) | 返回数据包的预期源端口。 |
| seen-reply (yes | no) | 目的地址已向源地址作出应答。 |
| src-address (ip) | 源地址。 |
| src-port(integer) | 源端口。 |
| srcnat (yes | no) | 连接经过 SRC-NAT,包括通过 NAT 进行 masquerade 的数据包。 |
| tcp-state (string) | TCP 连接当前状态:"established""time-wait""close""syn-sent""syn-recv""fin-wait""close-wait""last-ack""listen" |
| timeout (time) | 连接在该时间后将从连接列表中移除。 |
| uses-helper(yes | no) | 已对特定连接应用 "IP/Firewall/Service Port" helper。 |