当前位置:首页 > 文章列表 > 文章 > linux > Linux nftables 怎样按接口限制入站端口

Linux nftables 怎样按接口限制入站端口

来源:17golang原创 2026-11-03 12:44:40 0浏览 收藏

Linux nftables 按接口限制入站端口,可以在处理本机流量的 input 基本链中,把入接口名称 iifname 和目标端口 tcp dport 组合起来。只写“指定接口 accept”并不能排除其他接口;还需要明确处理其他接口对这个端口的访问。

我会把规则的目标收窄到一个端口,再考虑它与原有防火墙怎样共同生效。下面用一个虚构的双网卡服务案例展开,配置、接口名和排查记录均为教学示例,命令未在本文中实际执行。

nftables 官方项目文档:https://netfilter.org/projects/nftables/manpage.html

先把“外网也能访问”写成可核对的现象

设想一台主机的管理接口叫 enp2s0,另一条接入路径经过 enp3s0,本机应用监听 TCP 8080。期望是管理接口保留访问机会,其他非回环接口不能向本机这个端口送入报文;本机回环 lo 作为显式例外保留。

为了复盘清楚,可以把操作记录按三件事整理:最初只有一条管理接口放行规则;随后从另一入口仍能连到应用;最后发现其他报文落到默认 accept,根本没有被排除。这只是一个用于解释原因的案例,不是对某次线上事故的描述。

案例中的对象必须确定的事实
TCP 8080它确实是需要限制的本机服务端口
enp2s0报文实际进入本机时的接口名称
enp3s0 或其他非回环接口它们不属于本例允许的入口
lo本例保留本机回环访问

我通常先明确“允许从哪张接口进入”,再讨论地址。目的地址属于某块网卡,不等于报文必然从那块网卡进入;接口约束和地址约束表达的是不同条件。

复盘时先看入口接口,再看本机还是转发

# 查看接口名、地址和监听状态,以下均为读取操作。
ip -brief link
ip -brief address
ss -lnt
# 同时查看所有现有基本链与规则,不能只看一个自建链。
sudo nft -a list ruleset

iifname 匹配收到报文的接口名称,iif 则按接口索引匹配。名称匹配适合表达固定接口名的约定,但接口改名后规则含义也会受影响。桥接、VLAN、隧道和容器网络要根据实际网络命名空间与 hook 所见接口判断,不能只照抄物理网卡外壳上的名字。

input 处理交付本机的报文,forward 处理转发报文。本文的规则覆盖前者。如果端口映射通过 DNAT 把连接转发到容器,或者应用位于其他网络命名空间,需要按真实路径配置相应位置;宿主机 input 链并不自动等于容器端口入口。

入接口、目标端口、本机交付与转发边界的静态关系
图1:接口与作用范围说明图。iifname 对应入接口名称,TCP 8080 对应目标端口条件,本机交付关联 input,转发关联 forward;图示不是报文执行轨迹或现场截图。

只增加针对 TCP 8080 的接口约束

先确认没有同名 iface_8080_guard 表,再将以下内容保存成文件。它是一个首次增加的专用约束,不是替换整台主机的完整防火墙。inet 表让这里的 TCP 条件用于 IPv4 和 IPv6。

# 保存为 iface-8080.nft;仅在同名专用表尚不存在时首次载入。
table inet iface_8080_guard {
    chain local_ingress {
        type filter hook input priority -10; policy accept;

        # 本机回环作为明确例外,本链不限制它。
        iifname "lo" accept

        # 管理接口为 enp2s0;其他接口进入的 TCP 8080 报文在此丢弃。
        iifname != "enp2s0" tcp dport 8080 counter drop
    }
}

拒绝规则的含义是:入接口不是 enp2s0 且 TCP 目标端口为 8080,就计数并丢弃。lo 在前面作为例外结束本链判断。其他端口、UDP 报文和符合例外的流量继续受现有其他规则管理。

这里没有单独写 enp2s0 accept,因为它不匹配拒绝条件,会到达本链的 accept 策略。但这只表示本专用链没有否决它,不能覆盖已有防火墙的 drop。如果原有规则不允许管理接口访问,仍应通过它原来的管理入口增加精确放行。

# 先确认接口名和专用表名,再在有控制台回退条件的主机上加载。
sudo nft -f iface-8080.nft
# 核对实际规则与拒绝规则的计数器,不根据配置文件猜测生效状态。
sudo nft -a list table inet iface_8080_guard

本文不用 flush ruleset 清空全机规则。已有 firewalld、容器网络或发行版管理工具时,应优先把相同条件整合进其受管配置,避免规则来源互相覆盖。文件首次载入也不等于可以反复叠加;后续修改由同一个规则管理者维护该专用表。

不要让已有放行规则掩盖判断

单个链里的规则会受排列位置影响:若在同一链中先命中宽泛 accept,后面的限制就没有机会判断。独立基本链的关系又不同:同一 hook 上 priority 数值较小的链先参与;一个基本链 accept 之后,其他基本链仍可能丢弃报文。不要把它理解为“任何一处 accept 都能最终放行”。

本例用 priority -10 把专用约束与常见的优先级 0 过滤链区分开,但它不是适用于所有规则集的万能位置。要查看整份规则集,特别是相同优先级的链,不依赖它们未保证的相对顺序。

示例没有 ct state established,related accept 例外,也没有仅匹配新连接:因此,通过不允许接口进入的现有 TCP 8080 会话报文同样可能被丢弃。这个取舍是为了表达按接口约束该端口的所有入站报文;若产品要求旧会话自然退出,就需要另行设计连接状态策略,并清楚说明过渡期的差异。

专用表、input基本链、接口条件、端口条件与其他基本链的静态边界
图2:规则边界结构图。专用表包含 local_ingress,拒绝条件同时关联接口名与 TCP 8080;其他基本链仍有自己的策略。连线只解释包含与约束关系,不表示未经执行的过滤流程。

用两条访问路径核对,并保留局部回退

读者加载后应从两条真实入口分别发起新的连接。仅在服务器本机访问它自己的地址,不能代替从另一网卡进入的外部连接;本例又刻意保留了回环访问,本机访问成功尤其不能当作接口限制失效。

核对场景预期和判断方式
经 enp2s0 访问 TCP 8080本专用链不拒绝;是否成功还取决于服务监听及其他规则
经其他非回环接口访问 TCP 8080若报文到达本链并命中条件,应被丢弃并增加 counter
IPv4 与 IPv6按主机实际启用的协议分别覆盖,不能只核对一种
其他业务端口确认本例限定范围与原有访问约定相符

如果访问失败但计数器不变,先确认报文是否到达此网络命名空间的 input hook,也可能已被更早的规则丢弃。反过来,计数增加只证明拒绝条件命中过报文,不代表某个指定客户端请求必定就是它。需要关联具体访问时段与网络路径,不能把计数器当作完整请求日志。

变更前保留当前规则记录和控制台访问条件。需要撤回本文约束时,核实专用表中只有本次内容,再执行局部回退:

# 只撤销本文新增的专用表;执行前核实表中没有其他人追加的规则。
sudo nft delete table inet iface_8080_guard

删除专用表会移除这条接口约束,不会让服务自动恢复成某种安全状态;撤回后的访问仍由原有规则决定。不要为了回退一条规则而清空整台主机的防火墙。

把接口约束写进长期维护清单

我会把受限端口、允许接口、回环例外、地址族、网络命名空间、规则来源和回退方式一起交接。临时用 nft -f 加载只改变当前运行规则,是否重启保留要按发行版和现有管理工具的配置入口处理,不能随手再开一套重复管理服务。

为什么只写允许接口的 accept 仍然挡不住其他接口?

未匹配那条规则的报文还会继续按后续规则和默认策略处理。要实现单端口入口限制,必须明确其他接口对该端口的处理,而不是把未匹配理解成自动拒绝。

接口名写错会怎样?

名称可以先于接口存在写进规则,加载成功不代表名字正确。对本文的反向匹配规则,写错管理接口名可能把真正的管理入口也算成其他接口,因此变更前必须确认名字。

相同端口的 UDP 也会被限制吗?

不会,本文明确匹配 TCP。若应用同时使用 UDP,应在既有规则管理方式中为 UDP 单独表达对应条件,不要根据端口数字相同就推断协议范围相同。

参考资料:官方命令与表达式:https://netfilter.org/projects/nftables/manpage.html;基本链、优先级与裁决关系:https://wiki.nftables.org/wiki-nftables/index.php/Configuring_chains;规则语法速查:https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Linux BPF map 怎样在用户态读取内核数据Linux BPF map 怎样在用户态读取内核数据
上一篇
Linux BPF map 怎样在用户态读取内核数据
Linux rsync 怎样保留权限并排除缓存目录
下一篇
Linux rsync 怎样保留权限并排除缓存目录
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    857次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    862次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    938次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    919次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    747次使用