防火墙
firewall 是顶层配置对象,和 inbounds、outbounds、routing 并列。
防火墙规则复用路由规则的匹配字段,但命中后的结果不是选择出站,而是执行防火墙动作,例如标记、放行、阻断或连接数限制。
FirewallObject
{
"firewall": {
"rules": []
}
}2
3
4
5
rules: [FirewallRuleObject]
防火墙规则数组。每条规则从上到下依次评估,具体行为由 action 决定。
执行顺序
防火墙在路由已经选出 outbound 之后执行。此时规则可以看到已经路由后的连接信息:
- 入站处理得到的来源地址、本地地址;
- 路由与 outbound 目标解析后的目标地址;
- 可用时的 inbound tag、outbound tag;
- 可用时的 sniffing 协议和
attrs属性。
防火墙没有独立的 domainStrategy。ip 匹配只使用连接上下文里已经存在的目标 IP,防火墙不会再额外触发一次 DNS 解析。
实时流量检测类规则会在流量开始后继续判断,因此可以关闭已经完成路由的连接。
FirewallRuleObject
{
"source": ["192.168.1.10/32"],
"ip": ["geoip:telegram"],
"action": "limit",
"ruleTag": "telegram-src-limit",
"limit": {
"key": "srcIp",
"mode": "activeConnections",
"maxConnections": 50
}
}2
3
4
5
6
7
8
9
10
11
支持的路由式匹配字段:
domain,ipsource/sourceIP,sourcePortlocalIP,localPortport,network,uservlessRoute,inboundTagprotocol,attrsprocess,ruleTag,requireRuleTag
不支持的字段:
destinationoutboundTagbalancerTagreLookup
这些字段属于路由决策,防火墙规则不能通过它们选择或重新选择出站。
action
action: "mark" | "allow" | "block" | "limit"
mark:写入ruleTag,继续评估后续规则。allow:允许当前连接,并停止防火墙评估。block:关闭或拒绝当前连接,并停止防火墙评估。limit:对当前规则选中的流量应用连接数限制。
如果省略 action 且配置了 ruleTag,规则等价于 mark。
协议与实时流量检测
protocol 可以匹配普通 sniffing 协议,也支持防火墙实时流量检测:
flow:trojan-tls-in-tlsflow:shadowsocks
示例:
{
"protocol": ["flow:trojan-tls-in-tls"],
"action": "block",
"ruleTag": "trojan-tls-in-tls-block"
}2
3
4
5
{
"protocol": ["flow:shadowsocks"],
"action": "mark",
"ruleTag": "ss-flow"
}2
3
4
5
LimitObject
limit 只在 action 为 limit 时有效。
{
"key": "srcIp",
"mode": "activeConnections",
"maxConnections": 50
}2
3
4
5
字段:
key:srcIp、dstIp、srcDstIp、srcPrefix或dstPrefixmode:activeConnections或newConnectionswindowSeconds:仅mode为newConnections时需要maxConnections:阈值,超过后阻断
连接数限制分两步执行:
- 防火墙规则先用普通匹配字段选中流量。
limit.key只对这些已选中的流量分桶计数,再应用maxConnections。
因此,相同来源、目标或前缀的其他连接,如果没有命中当前防火墙规则,不会消耗这条规则的配额。
limit.key
srcIp
按来源 IP 分桶。每个来源 IP 有自己的配额,只统计命中同一条防火墙规则的连接。
适合表达“这个客户端最多可以打开 N 条被选中的连接”。
dstIp
按目标 IP 分桶。目标 IP 必须已经存在于路由后的连接上下文中。
适合表达“每个被选中的目标 IP 最多接收 N 条连接”。例如 Telegram 有多个目标 IP 时,每个目标 IP 各自拥有独立配额。
srcDstIp
按来源 IP + 目标 IP 二元组分桶。
适合表达“每个客户端到每个目标 IP 的组合最多 N 条连接”。
srcPrefix
按当前规则 source / sourceIP 中匹配到的来源 CIDR 分桶。
同一个来源 CIDR 内的所有来源 IP 共享配额。必须在同一条规则里显式配置 CIDR。
dstPrefix
按当前规则 ip 中匹配到的目标 CIDR 分桶。
同一个目标 CIDR 内的所有目标 IP 共享配额。必须在同一条规则里显式配置 CIDR。
前缀分桶说明:
srcPrefix和dstPrefix都要求同一条规则中存在显式 CIDR。- 用作前缀分桶来源时,不接受
geoip、ext:*或反选 CIDR。 - 如果多个显式 CIDR 同时匹配,使用最具体的那个 CIDR。
limit.mode
activeConnections
统计当前仍活跃的连接数。
计数范围限定为:命中同一条防火墙规则,并且属于同一个 limit.key 分桶的连接。
newConnections
统计 windowSeconds 滑动窗口内观察到的新连接数。
计数范围同样限定为:同一条防火墙规则 + 同一个 limit.key 分桶。窗口事件保存在防火墙运行时内存中,防火墙规则热重载后会重置。
示例
单个来源访问 Telegram 的活跃连接限制
{
"source": ["39.110.230.59/32"],
"ip": ["geoip:telegram"],
"action": "limit",
"ruleTag": "single-source-telegram",
"limit": {
"key": "srcIp",
"mode": "activeConnections",
"maxConnections": 50
}
}2
3
4
5
6
7
8
9
10
11
含义:最多允许 50 条活跃的 39.110.230.59 -> Telegram 连接。
39.110.230.59 访问非 Telegram 目标的连接不会消耗这条规则的配额。
每个 Telegram 目标 IP 独立限额
{
"source": ["39.110.230.59/32"],
"ip": ["geoip:telegram"],
"action": "limit",
"ruleTag": "per-telegram-ip",
"limit": {
"key": "dstIp",
"mode": "activeConnections",
"maxConnections": 50
}
}2
3
4
5
6
7
8
9
10
11
每个被选中的 Telegram 目标 IP 都有独立配额。例如:
39.110.230.59 -> 91.108.56.13039.110.230.59 -> 149.154.175.55
这两个目标 IP 会分别计数。
每个来源和目标组合独立限额
{
"ip": ["geoip:telegram"],
"action": "limit",
"ruleTag": "telegram-pair-limit",
"limit": {
"key": "srcDstIp",
"mode": "activeConnections",
"maxConnections": 10
}
}2
3
4
5
6
7
8
9
10
每个来源 IP + 目标 IP 组合都有独立配额。不同来源 IP 访问同一个目标 IP 时不会共享同一个桶。
来源网段共享限额
{
"sourceIP": ["192.168.10.0/24", "192.168.20.0/24"],
"ip": ["geoip:telegram"],
"action": "limit",
"ruleTag": "lan-prefix-telegram",
"limit": {
"key": "srcPrefix",
"mode": "activeConnections",
"maxConnections": 50
}
}2
3
4
5
6
7
8
9
10
11
192.168.10.0/24 -> Telegram 共享一个桶,192.168.20.0/24 -> Telegram 共享另一个桶。
目标网段共享限额
{
"source": ["192.168.1.0/24"],
"ip": ["198.51.100.0/24", "203.0.113.0/24"],
"action": "limit",
"ruleTag": "dst-prefix-limit",
"limit": {
"key": "dstPrefix",
"mode": "activeConnections",
"maxConnections": 30
}
}2
3
4
5
6
7
8
9
10
11
每个显式目标 CIDR 都有一个共享配额。
新连接突发限制
{
"source": ["192.168.1.10/32"],
"action": "limit",
"ruleTag": "src-burst",
"limit": {
"key": "srcIp",
"mode": "newConnections",
"windowSeconds": 30,
"maxConnections": 20
}
}2
3
4
5
6
7
8
9
10
11
含义:192.168.1.10 在 30 秒窗口内最多创建 20 条命中当前规则的新连接。