需构建“感知—标记—拉黑—清理”闭环:nftables按源IP统计60秒内新建连接数超15次即打标并记录日志;脚本解析日志提取IP写入带10分钟超时的ipset黑名单;iptables或nftables匹配该集合阻断流量;自动超时清理+白名单校验+手动解封保障精准性。

要在 Linux 下实现 nftables 对持续低频分布式扫描的秒级联动封杀,关键不是靠单条规则“堵”,而是构建一个“感知—标记—拉黑—清理”闭环。低频扫描(比如每分钟 5–20 次连接,跨 IP、端口、时间)容易绕过传统限速,必须结合连接状态、源 IP 行为聚合与外部工具协同,ipset 在这里承担高效匹配和自动过期的“黑名单执行层”角色。
用 nftables 做轻量行为识别与触发标记
低频扫描不拼速度,拼的是“异常模式”。nftables 不适合做复杂分析,但可完成两个轻量动作:统计 + 打标。
- 对常见服务端口(22、80、443、3306 等)新建连接,按 /32 源 IP 统计 60 秒内连接数,阈值设为 15(低于高频但显著高于正常用户):
nft add rule inet filter input tcp dport {22, 80, 443, 3306} ct state new @scan_counter ip saddr limit rate over 15/minute burst 5 packets counter name lowfreq_scan - 给命中该规则的连接打上 connmark 标记,便于后续识别:
nft add rule inet filter input meta mark set 0x00000001(需在 limit 规则后立即加) - 配合日志记录(加 log),供脚本消费:
nft add rule inet filter input meta mark 0x00000001 log prefix "LOWFREQ_SCAN: " counter
用脚本监听日志并写入 ipset 黑名单
nftables 自身不支持动态写 IP 到集合,但可通过 ulogd2 或 journalctl 实时捕获 log 事件,交由 Shell/Python 脚本处理。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 启用 nflog 并配置 ulogd2 将标记流量发到指定 netlink 组(如 group=1),或直接用 journalctl -u systemd-journald -o json | grep "LOWFREQ_SCAN" 流式解析
- 脚本提取源 IP 后调用 ipset 添加(带超时):
ipset add deploy_blocklist "$ip" timeout 600(10 分钟足够覆盖扫描窗口) - 确保 ipset 集合已创建:
ipset create deploy_blocklist hash:ip timeout 600 - 避免重复添加:ipset 默认去重,无需额外判断
用 iptables/nftables 规则匹配 ipset 并阻断
ipset 只是数据结构,必须挂载到防火墙链中才生效。推荐用 iptables 做最后拦截(兼容性好、成熟稳定),也可用 nftables 的 @set 语法(需 kernel ≥ 5.10)。
- iptables 方式(推荐,稳定):
iptables -I INPUT -m set --match-set deploy_blocklist src -j DROP - nftables 方式(统一栈):
nft add rule inet filter input ip saddr @deploy_blocklist drop(前提:nft 中已定义同名 set,类型为 ipv4_addr) - 注意顺序:该规则必须放在“允许 established”之后、“放行新连接”之前,否则会误杀回连流量
自动清理与防误封兜底机制
低频扫描常混杂真实用户(如爬虫、CDN 回源),不能一劳永逸封禁,必须设计自动衰减与人工干预出口。
- 所有 ipset 条目强制设 timeout(如 600 秒),到期自动移除,无需脚本干预
- 脚本可增加白名单校验:查 IP 是否在可信 ASN 或 CDN 段(用 iprange 或 cidr-tools),跳过添加
- 保留手动解封接口:
ipset del deploy_blocklist 192.0.2.50或批量清空:ipset flush deploy_blocklist - 加一条 debug 规则记录被拦 IP:
iptables -I INPUT -m set --match-set deploy_blocklist src -j LOG --log-prefix "BLOCKED_BY_SCAN: "

















