nftables的quota表达式可限制特定端口流量累计值,但不支持自然月自动重置,需通过cron或systemd定时任务每月重置命名quota对象,并配合ct state new避免重复计数。

使用 nftables 的 quota 表达式可以对特定端口的流量进行累计限制,但需注意:它本身不支持“自然月”自动重置,必须配合外部脚本或系统定时任务实现按月归零。下面给出可落地的配置方案。
理解 quota 表达式的基本行为
quota 是一个有状态的计数器,匹配时递增字节数,达到限额后返回非匹配结果(可用于跳过后续规则或触发丢弃)。它默认是“无符号64位整数”,支持字节级精度,且可设置为“仅首次匹配时生效”(overlimit 模式)或“持续匹配直到超限”(默认模式)。
- 不自动清零,重启 nftables 或 reload 规则表会重置计数器
- 不能直接绑定到“每月1号0点”,需依赖外部机制定期重置
- 建议搭配
ct state new使用,避免重复计数连接中的分片或重传包
配置示例:限制 TCP 8080 端口每月最多 100GB
假设业务服务监听在 tcp dport 8080,目标是累计流量超过 100GB 后丢弃新连接(不影响已有连接):
# 创建命名 quota 对象(便于后续重置) nft add quota inet filter web_monthly_quota 100 gbytes <h1>添加规则:只对新连接计数,并在超限时跳过 ACCEPT,进入 DROP 链</h1><p>nft add rule inet filter input tcp dport 8080 ct state new @web_monthly_quota counter name "web-quota" drop </p>
- 使用
@web_monthly_quota引用命名 quota,比匿名 quota 更易管理 -
ct state new确保每个连接只计一次初始包(SYN),避免重复累加 -
counter name "web-quota"方便用nft list quota inet filter web_monthly_quota查看实时用量
实现“每月自动重置”的两种可靠方式
Linux 本身不提供“月度定时器”,需借助 cron + nft 命令组合完成:
-
方式一:每月1日0点重置 quota(推荐)
编辑/etc/cron.d/nft-quota-reset:0 0 1 * * root /usr/sbin/nft delete quota inet filter web_monthly_quota && /usr/sbin/nft add quota inet filter web_monthly_quota 100 gbytes -
方式二:用 systemd timer 实现更精确控制(适合容器/云环境)
创建/etc/systemd/system/nft-monthly-reset.timer和.service,设定OnCalendar=1-31 *-01-01 00:00:00类似逻辑
⚠️ 注意:重置操作会短暂中断计数,但因 quota 是 per-rule 状态,只要规则未删除,重置后新连接立即开始计数,不影响服务连续性。
监控与调试技巧
日常运维中需及时掌握配额使用情况:
- 查看当前已用字节数:
nft list quota inet filter web_monthly_quota - 统计历史超限次数:
nft list ruleset -a | grep -A5 "web-quota"(结合counter的 handle 号) - 临时禁用限制(如紧急扩容):
nft insert rule inet filter input position <handle> tcp dport 8080 accept</handle>,优先级高于 quota 规则 - 日志告警建议:在 quota 规则后加
log prefix "QUOTA_EXCEEDED_WEB: ",配合 rsyslog 过滤触发通知










