拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Linux防火墙封禁高危端口:firewalld等三工具实操

上个月帮朋友收拾一台被扫的测试机日志里刷得最凶的不是登录失败而是一串来自不同 IP 的 445 端口连接请求。他问我机器上根本没开 Samba为什么还有人一直敲 445答案很直白——扫描器并不知道你开没开它是按清单打的而 445、3389、6379、23 这些端口就在几乎所有批量扫描工具的默认清单里。Linux 防火墙封禁高危端口这件事本质不是防住某个黑客而是把一大片无差别扫描的噪音直接掐掉让真正需要被关注的告警浮出水面。这篇文章围绕Linux下的防火墙命令展开重点讲怎么用firewalld、iptables、nftables三套工具把高危端口干净利落地封掉包括规则怎么写、顺序怎么排、重启为什么不生效、Docker 和云安全组为什么会绕过你的规则、封完之后怎么验证真的生效。内容偏实操命令都可以直接复制改改就用。读者对象很宽刚接手服务器的新人、需要做等保加固的运维、写后端但得自己维护机器的开发以及准备面试被问到Linux 防火墙怎么封端口的同学都能从里面找到能落地的东西。需要先说明一点封端口是减少暴露面不是解决问题。真正的加固是三步——关掉不需要的服务、只监听必要地址、最后才是防火墙兜底。很多人在第三步上花了很多时间却忘了第一步结果规则越写越多机器上的服务还是照开不误。1. 高危端口到底高在哪先搞清封谁、为什么封在敲命令之前得先明白自己封的是什么。端口本身没有原罪所谓高危通常来自三个事实协议设计年代久远缺少认证、历史漏洞多到被写进自动化利用工具、以及一旦被打通就能成为横向移动的跳板。搞清楚这一点你才能判断某个端口在自己环境里到底该全封、只对内网开还是保持开放。1.1 445 端口被反复点名原因不止一个漏洞经常有人问 445 端口列为高危的原因到底是啥。我的总结是四层叠加。第一层是协议本身SMB 承担文件共享、打印共享、远程管理命名管道等一堆职责功能多意味着攻击面大匿名会话、空口令枚举这些老问题一直存在。第二层是历史漏洞密度从早期的远程代码执行到后来臭名昭著的永恒之蓝系列每隔几年就会冒出一个能被蠕虫化传播的严重漏洞。第三层是传播方式445 的漏洞利用往往不需要用户交互一个能联网的机器就可能被自动打穿然后在同网段里像流感一样扩散。第四层是勒索软件的偏好大量勒索家族把 445 当作横向移动的首选通道因为内网里总有那么几台机器默认开着共享。所以对于一台只提供 Web 服务或数据库服务的 Linux 服务器如果它根本不承担跨平台文件共享职能445 就应该直接封。这里有个常被忽略的点Linux 上默认并不监听 445但一旦装了 Samba、或者某些 NAS 类服务、某些容器镜像带上了 SMB 组件端口就悄悄开了。判断方法很简单用ss -tlnp看一眼有没有进程绑在 445 上没有就封有就先确认业务是否真的依赖。顺带说一句跨平台环境的坑。我见过不少团队把 Linux 侧的 445、135 封得很严Windows 服务器却完全没动结果一台机器中招之后横向移动全部走 Windows 之间的 SMB 通道。防火墙加固必须成套做只封一半等于没封。1.2 一份可以直接抄的 Linux 高危端口封禁清单下面这张表是我自己常用的基础清单按暴露后典型风险排了优先级。注意端口号是两侧都列因为很多服务 TCP 和 UDP 都监听只封 TCP 是常见疏漏。端口协议常见服务暴露后的典型风险建议策略445TCPSMB 文件共享远程代码执行、勒索横向移动全封仅必要内网白名单放行135TCPRPC 端点映射配合 445 做横向移动、信息枚举全封137-139TCP/UDPNetBIOS 名称与会话主机信息泄露、旧式共享利用全封3389TCP远程桌面协议暴力破解、凭据填充全封需要时走白名单23TCPTelnet明文传输凭据全封改用加密远程管理21TCPFTP明文凭据、匿名登录全封改用加密文件传输1433TCPSQL Server弱口令爆破、提权全封业务机走内网白名单3306TCPMySQL未授权访问、爆破仅监听本地或内网禁止公网6379TCPRedis未授权写入、写公钥提权内网加认证禁止公网27017TCPMongoDB历史未授权访问问题内网加认证禁止公网11211TCP/UDPMemcached反射放大攻击、数据泄露全封公网111 / 2049TCP/UDPrpcbind / NFS目录挂载泄露全封公网5900-5905TCPVNC弱口令、明文会话全封走隧道或跳板161 / 162UDPSNMP团体字泄露设备信息全封或改用 v3 加白名单69UDPTFTP无认证文件传输全封这张表不是让你一次性全怼进去而是给你一个对照检查的起点。做法是先跑一次端口监听清单把表里的端口和实际监听项做交集交集部分再判断业务是否真的需要外部访问。绝不动正在服务的业务端口是第一条纪律。1.3 封之前先问自己三个问题避免误伤自己第一问这个端口是谁在监听监听在哪个地址上如果服务只监听127.0.0.1那它本来就不接外网封不封意义不大但封掉也没影响。命令就是ss -tlnp和ss -ulnp加-p才看得到进程名我习惯直接ss -tulnp | grep -E 445|3389|6379快速筛。第二问这个端口的外部来源是可预期的吗如果答案是只有办公网段和跳板机需要访问那正解不是全封而是白名单放行其余拒绝。很多团队一刀切全封结果运维自己上不去半夜又悄悄打开规则形同虚设。第三问我手里的操作通道安全吗如果你正通过 SSH 连着一台远程机器准备动防火墙请务必先确认 22 端口不会被自己的规则误伤。我踩过最惨的一次坑就是规则写反了方向一条-A INPUT -p tcp --dport 22 -j DROP把整台机器锁死最后只能通过控制台去救。封禁动作本身需要有退路这一点后面第 7 章会专门讲保命习惯。2. 工具选型iptables、firewalld、nftables 该用哪个这是被问得最多的问题。很多人以为三者是三选一的竞品实际上它们的关系更像壳和芯理解这一点能省掉大量纠结时间也能解释为什么你在 firewalld 环境下敲iptables -L看到的规则列表可能为空。2.1 三者关系不是三选一而是壳与芯内核里真正干活的框架叫 Netfilter它是数据包在内核协议栈上的钩子集合。iptables 是操作 Netfilter 的一套老牌命令行工具nftables 是它的后继者用更统一的语法和更高效的数据结构取代了 iptables 的若干扩展模块。firewalld 则是站在更高层的服务它把规则组织成区域zone和服务service的概念底层根据发行版配置可能调用 iptables也可能调用 nftables。这就解释了一个经典困惑在 CentOS 或者较新的 openEuler 上装了 firewalld你直接敲iptables -L常常看不到自己用 firewall-cmd 添加的规则或者看得到但一 reload 就没了。原因就是真正的规则在 firewalld 的 nftables 表里iptables 命令只是通过兼容层看到的影子。两套工具混用是规则时灵时不灵的头号原因。2.2 按发行版和运维习惯做决定如果你的机器上 firewalld 已经在跑systemctl status firewalld一看便知那就老老实实用 firewall-cmd别去和 iptables 较劲。RHEL 系、CentOS 系、以及国内不少信创发行版默认就是这个组合用 firewalld 的 rich rule 写白名单比裸写 iptables 好维护得多。如果机器上 firewalld 没装也没跑比如一些精简的 Debian、Alpine 容器基础镜像那就直接上 iptables 或 nftables。判断标准很简单nft list ruleset有输出说明内核和用户态都支持 nftables优先用它只有 iptables 命令可用就用 iptables。Ubuntu 服务器上还有一层ufw它本质是 iptables 的前端语法极简适合单机小规模场景但表达复杂白名单时不如 firewalld 直观。2.3 选型对照表维度iptablesfirewalldnftables定位内核规则的经典命令行工具面向服务的规则管理层Netfilter 的新一代命令行工具语法直观度一般需要理解链和顺序较好zone service rich rule好支持集合、区间、映射批量端口表达需要 multiport 或 ipsetrich rule 里可列多个端口原生集合一条顶多条规则持久化需额外工具保存--permanent reload写入配置文件典型发行版通用老环境多RHEL/CentOS/openEuler 系新内核通用推荐场景与 firewalld 不共存时使用单机服务器统一管理新环境、规则量大选型定下来之后就别再换混用带来的排查成本远高于工具本身的差异。我见过一台机器上三套规则同时存在最后没人敢改只能整机重建。3. firewalld 实战五条命令封掉一批端口假设你的服务器是 CentOS 或 openEulerfirewalld 正在运行。下面这套流程是我实际用得最多的从看清现状到落规则再到确认生效一步步来。3.1 先看清当前策略--list-all 里藏着答案第一件事永远是看清楚现在放行了什么而不是上来就封。systemctl status firewalld --no-pager firewall-cmd --get-active-zones firewall-cmd --list-all firewall-cmd --list-all --zonepublic输出里几个字段要重点看interfaces表示哪块网卡归这个 zone 管services是放行的服务名ports是放行的端口rich rules是自定义规则target决定未匹配流量怎么处理。默认的 public zone 通常只放行 ssh、dhcpv6-client 这类基础服务也就是说大部分高危端口在 firewalld 的默认策略下本来就进不来。那为什么还要封因为现实里经常是有人为了临时调试执行过firewall-cmd --add-port3306/tcp之后忘了删。所以第一步的正确动作是检查放行列表里有没有不该出现的端口有就删掉。firewall-cmd --permanent --remove-port3306/tcp firewall-cmd --permanent --remove-port6379/tcp firewall-cmd --permanent --remove-port445/tcp firewall-cmd --reload如果某个端口本来就不在放行列表里remove-port会打印一行Warning: NOT_ENABLED: 445:tcp。这只是提示不是错误说明它本来就没被放开属于好消息。3.2 用 rich rule 做端口封禁与网段白名单真正需要显式封禁的场景是默认策略较宽松、或者你想对特定来源做区分的环境。这时候用 rich rule 最清晰它的可读性远高于往 iptables 里塞一堆参数。比如只允许运维网段访问 445其余全部拒绝firewall-cmd --permanent --add-rich-rulerule familyipv4 source address10.10.20.0/24 port port445 protocoltcp accept firewall-cmd --permanent --add-rich-rulerule familyipv4 port port445 protocoltcp drop firewall-cmd --reload很多人会问既然 public zone 默认就拒绝未放行的流量第二条 drop 是不是多余在默认 target 下确实多余但它有两个实际价值。一是当 zone 的 target 被改成了 accept 时这条规则就是唯一的拦截线二是让规则意图显式化半年后接手的人一眼就能看懂445 是被主动封的而不是恰好没放行。安全规则的可维护性往往比省一行更重要。一次性封一批端口时rich rule 要一条条写略啰嗦。这时候可以把端口归到一个自定义 zone或者干脆改用 nftables 的集合语法后面第 5 章会说。3.3 --permanent 与 --reload 的坑firewalld 的命令有两个作用域不加--permanent是改运行时配置立刻生效但重启丢失加了--permanent是改持久化配置重启仍在但当前不生效。两条经验必须记住。第一条写完--permanent一定要跟一条--reload。reload 会重新加载配置过程中规则有一瞬间的空窗因此绝不要在远程会话里连续执行删规则 reload这类操作而不做保底万一删的是 22 端口reload 那一刻你就断了。第二条不要用--complete-reload。它比--reload更彻底会重置连接跟踪表把已建立的连接也一起打断在承载业务的机器上属于危险动作。常规场景用--reload足够。还有一个替代玩法不加--permanent先加运行时规则确认自己不断线、业务正常再执行firewall-cmd --runtime-to-permanent把当前运行时配置整体落盘。这个顺序比先永久后重载更安全我现在的习惯就是先跑运行时验证再一把固化。3.4 日志开关让拒绝有迹可循规则封上了但你不知道它有没有在干活。firewalld 提供了一个全局的拒绝日志开关firewall-cmd --set-log-deniedall firewall-cmd --get-log-denied打开之后被拒绝的入站包会写进内核日志用journalctl -k -f或者dmesg -T | tail -50就能看到类似INeth0 ... DPT445的记录。看到成片的 445 记录你就知道外面确实在扫而规则确实在挡。不过要注意日志量可能很大尤其是在公网机器上。低频环境开着无所谓高频环境建议用firewall-cmd --set-log-deniedunicast缩小范围或者转用 iptables 的-m limit做限速避免日志把磁盘写满——这种事真的发生过而且往往在凌晨。4. iptables 实战手写规则的顺序、模块与持久化环境里没有 firewalld或者你需要精确控制规则的插入位置时iptables 依然是最直接的方案。它最大的特点是顺序敏感规则从上往下匹配命中即停所以插在哪一行比写什么内容更容易出错。4.1 一条 DROP 规则的正确插入姿势先看现状再动手。-n不解析域名-v显示包计数--line-numbers显示行号这三个参数我几乎每次都用。iptables -L INPUT -n -v --line-numbers假设输出里第 1 行是放行已建立连接、第 2 行是放行 22 端口。要封 445正确做法是插到放行规则之后、但仍在链的前部iptables -I INPUT 3 -p tcp --dport 445 -j DROP iptables -L INPUT -n -v --line-numbers为什么强调位置因为如果你的机器上有一条第 1 行是-A INPUT -j ACCEPT这种大放行那你在后面加多少 DROP 都不会生效。规则不生效十次里有八次是顺序问题先看行号别急着怀疑内核。-I是插入-A是追加。用-I INPUT 3明确指定位置比-A追加到末尾可预期得多。如果你只是想在链首拦截-I INPUT 1也可以但要确保它不会挡掉你赖以远程连接的 ESTABLISHED 放行规则——这也是为什么更稳的做法是把它放在处理已建立连接的那条规则之后。4.2 multiport 与 ipset批量端口两种打法端口只有一两个直接写。要封 135、137、138、139、445 这一串用 multiport 模块一次搞定比写五条规则清爽得多iptables -I INPUT 3 -p tcp -m multiport --dports 135,137,138,139,445 -j DROP iptables -I INPUT 3 -p udp -m multiport --dports 135,137,138,139 -j DROPmultiport 单条规则最多支持 15 个端口超出就得拆多条。如果你的封禁清单有几十个端口或者需要按来源 IP 集合做匹配那就该上 ipset 了。ipset 把端口或地址放到内核里的哈希表中iptables 只需引用集合名规则数量恒定为一条匹配效率也更高。ipset create highrisk bitmap:port range 0-65535 ipset add highrisk 445 ipset add highrisk 135 ipset add highrisk 3389 iptables -I INPUT 3 -m set --match-set highrisk dst -j DROP这里的参数选择值得说一句。bitmap:port以位图存端口端口范围固定 0 到 65535 时占用的常驻内存是 65536 位也就是 8KB 左右几乎可以忽略而如果换成hash:ip存来源地址hashsize建议取实际条目数的两倍并向上取到 2 的幂否则冲突链变长会影响匹配速度。这是能直接算出来的一千个地址就设hashsize 2048够用且不浪费。4.3 DROP 还是 REJECT别凭感觉选这两个动作的差别在于是否回一个 ICMP 拒绝消息。DROP 是静默丢弃对端只能等到超时REJECT 会明确告诉对方不允许连接立刻失败。我的经验是面向公网、面向未知来源的封禁用 DROP。理由是扫描器在等超时时会占用少量资源静默丢弃不给任何反馈还能少暴露一点主机存活信息。而面向内网、面向已知合作方的白名单外拒绝用 REJECT 更友好业务方排查时能立刻拿到连接被拒不用怀疑网络链路。统一用 DROP 还有个小代价你自己的telnet测试会卡很久才返回容易误判成网络不通。所以做验证的时候优先用带超时参数的探测方式或者干脆用 nmap 的-Pn直接看端口状态不要傻等着telnet超时。4.4 重启不丢规则四种持久化方案对比iptables 规则默认在内存里重启即失。这是新手最容易栽的跟头——重启前封得好好的重启后端口又开了还以为是规则写错了。持久化方案有好几种选错一种会带来长期的维护混乱。方案适用系统保存命令恢复方式评价netfilter-persistentDebian/Ubuntunetfilter-persistent save开机自动加载首选规范稳定iptables-servicesRHEL/CentOS 7 系service iptables save开机自动加载老环境常用与 firewalld 冲突导出文件 开机任务通用iptables-save /etc/iptables/rules.v4iptables-restore配 systemd 单元灵活但需自己维护rc.local 追加通用旧式直接在脚本里写规则开机执行不推荐排查困难Ubuntu 上装iptables-persistent的时候安装过程会问你是否保存当前规则这一步别顺手回车过去先确认当前规则是干净的再决定要不要保存否则会把一堆调试期间的临时规则固化下来。CentOS 系如果同时装了 firewalld 和 iptables-services两者会争夺 Netfilter 的控制权典型症状是重启后规则互相覆盖这种情况必须二选一把另一个彻底停掉并屏蔽开机启动。5. nftables 与容器、云环境容易被绕过的三层规则写对了、也持久化了是不是就万事大吉不一定。在容器化和云上跑的服务有三层东西会悄无声息地绕过你精心写的规则。这三层我都踩过讲清楚能省你很多个深夜。5.1 nftables 集合语法一条顶四条新内核的环境建议直接用 nftables它最舒服的地方是原生支持集合和区间批量端口一条规则说完nft add table inet filter nft add chain inet filter input { type filter hook input priority 0; policy accept; } nft add rule inet filter input tcp dport { 135, 137, 138, 139, 445, 3389 } drop nft add rule inet filter input udp dport { 137, 138, 161, 1900 } drop方括号里的逗号分隔列表就是集合内核会按集合做匹配规则条数从六条压到一条。要按来源做白名单写ip saddr 10.10.20.0/24 tcp dport 445 accept放在 drop 之前即可。持久化用导出再加载的方式nft list ruleset /etc/nftables.conf systemctl enable --now nftables装好之后建议再systemctl status nftables确认一遍Debian 系和 RHEL 系的配置文件路径可能不同写错路径的结果就是开机加载失败而失败信息默认不会推到你面前等你下次重启才会发现规则全没了。5.2 Docker 发布端口绕过 INPUT 链的真相这是最经典的坑很多人的 Redis 6379 明明用 iptables 封了外部一测还是通的。原因在于 Docker 在启动容器时会往 nat 表和 filter 表的DOCKER链写规则并把经过容器的流量从 INPUT 链引导到 FORWARD 链。也就是说你写在 INPUT 链上的 DROP对通过-p 6379:6379发布出去的流量根本不起作用。两个解法各有取舍。第一个是治本容器端口不要发布到0.0.0.0只绑本地外部访问走反向代理。docker run -d -p 127.0.0.1:6379:6379 redis:7第二个是在 Docker 自己的链上封iptables -I DOCKER-USER -p tcp --dport 6379 -j DROP iptables -I DOCKER-USER -s 10.10.20.0/24 -p tcp --dport 6379 -j RETURN注意这里的顺序先放行白名单再 DROP因为 DOCKER-USER 链同样是顺序匹配先命中先结束。RETURN表示回到上一级链继续处理而不是直接接受这个语义差别很关键写错会变成白名单变成了全放行。顺带提醒Docker 在重启时可能会重刷自己的规则因此放在 DOCKER-USER 里的规则最好也纳入持久化流程别只靠一次手工执行。5.3 云安全组和主机防火墙谁先谁后云主机的流量路径是先过云平台的安全组再过你机器上的防火墙。所以安全组是更外层的闸门它不放行流量根本到不了你的网卡主机防火墙也就无从匹配。反过来说如果安全组放行了0.0.0.0/0的 6379而你以为主机上封了就安全那实际上是安全的——只要主机防火墙真的生效了。问题在于很多时候主机防火墙并没有生效比如规则没持久化、比如被容器绕过。所以这两层要做的是双重保险不是二选一。实践中的做法是安全组里把高危端口全部删掉只留必需的 80、443 和受限来源的 22主机侧再加一层显式拒绝。这样即使有人误改了安全组还有第二道闸门。排查方向搞反是很浪费时间的比如端口外部不通先怀疑防火墙其实可能是安全组没放行——我建议的排查顺序是从外到内安全组 → 主机防火墙 → 服务监听地址 → 服务本身。5.4 只封 Linux 不封 Windows 的横向移动风险前面提过一句这里展开讲。同一个网段里Linux 服务器往往是对外提供服务的Windows 服务器往往是内部办公和管理的。攻击者打进来之后真正想做的是从这台机器跳到内网其他机器而这条路径上最常用的通道就是 445 和 135。如果你的 Linux 侧封得很到位Windows 侧完全敞开那本质上只是把入口从大门挪到了侧门。所以加固清单要横跨平台Linux 侧用本文的命令Windows 侧用系统自带防火墙策略或组策略统一推送规则。重点不是谁的规则写得更漂亮而是整个网段里高危端口对本网段之外是否一致地不可达。这件事靠个人手工做很难维持最终一定要落到配置管理或者自动化脚本上否则新增一台机器就多一个缺口。6. 封完之后怎么验证从监听、规则到外部探测规则敲完了心里没底是常态。验证要做三件事确认本机状态、确认规则内容、确认外部探测结果。三层都对上才能说封住了。跳步验证的典型后果是自认为封了三个月某天被安全扫描报告打脸。6.1 本机自检三步第一步看监听确认哪些端口确实在对外服务。ss -tulnp | grep -E :(445|135|139|3389|6379|3306)\b如果某个端口根本没有出现在这里说明本机没有服务在跑防火墙封不封它其实无所谓但封上仍是好习惯防止将来装上服务后忘记加固。第二步看规则内容。firewall-cmd --list-all firewall-cmd --list-rich-rules iptables -L INPUT -n -v --line-numbers nft list ruleset三套工具按你实际使用的选一条即可。看的时候重点确认两点规则真的存在以及规则的位置在所有 ACCEPT 之前。第三步看服务状态别把防火墙整个关掉了还以为规则在生效。systemctl is-enabled firewalld systemctl is-active firewalld防火墙关闭有影响吗是热搜里常见的问题我的看法是不要用关闭服务的方式规避规则冲突那等于把门拆了。真正解决冲突的办法是理清哪些工具在管规则、只保留一套而不是停掉它。6.2 外部探测nmap 与 telnet 的正确用法从另一台机器上探测最直观。nmap 的-Pn跳过主机存活检测因为很多机器不响应 ICMP不加这个参数会得到主机似乎不可达的误导结论。nmap -Pn -p 445,3389,6379 10.0.0.15结果解读filtered表示包被丢弃没有回应通常对应 DROP 规则这是封禁生效的标志closed表示主机可达但端口没服务在听说明应答了但拒绝连接open才是真正的坏消息说明规则没拦住。telnet也能用来测但要注意被 DROP 的端口会一直卡在那里直到超时用的时候加上超时控制别守着屏幕等timeout 5 telnet 10.0.0.15 445至于telnet ip 端口 命令这组用法记住核心就是连上即说明通拒绝即说明不通卡住即说明被丢三种表现对应三种状态比看任何文档都直接。6.3 用计数器判断规则是否真的命中规则存在但没生效怎么判断看包计数。iptables -L INPUT -n -v输出里的pkts列就是命中次数nftables 里对应nft -a list ruleset配合-s查看统计。iptables -L INPUT -n -v --line-numbers watch -n 2 iptables -L INPUT -n -v --line-numbers用一个watch盯着看几秒如果 445 那条规则的计数在涨说明外面确实在扫、你的规则也确实在挡。如果计数一直是 0两种可能没有流量打到这条规则可能被更前面的规则拦截了或者规则没生效。这时候要回到顺序检查逐条看前置规则。这套方法在排查我以为封了但其实没封的场景里特别有效因为计数不会骗人。相比之下看日志、看配置文件都可能有延迟或缓存只有内核计数器是实时真相。6.4 conntrack 已建立连接规则生效了但攻击还在连接跟踪表是另一层容易忽略的机制。如果你的规则是通过放行 ESTABLISHED 状态来实现已建立连接不受影响的那么在新规则生效前就已经建立的连接不会因为新增的 DROP 而中断。表现出来就是规则加了、计数也涨了但那台可疑机器还连着。处理办法是主动清理相关会话conntrack -L -p tcp --dport 445 conntrack -D -p tcp --dport 445第一条是查看第二条是删除。conntrack-tools这个包需要单独装很多精简系统默认没有。这个技巧在实际应急响应里非常好用发现某台机器正在被暴力破解规则加上去之后还得把已经建立的会话清掉才能立刻切断。同样的道理反过来也成立如果你清完 conntrack 之后发现自己 SSH 断了那就是因为你把自己那条连接也清了。所以执行前先确认当前会话的来源端口别把管理通道一起清掉。7. 常见问题速查与避坑清单写到这里命令层面的东西基本齐了。下面这些是我在真实环境里反复遇到的问题整理成速查表配上几条封禁动作本身的保命习惯以及关于 fail2ban 的一点定位说明。7.1 十个高频问题速查表现象大概率原因处理方式规则加了但端口还是通匹配顺序被前置 ACCEPT 拦走用--line-numbers看顺序把 DROP 前移重启后规则消失没做持久化用 netfilter-persistent 或 nftables.conf 固化firewall-cmd 改了没效果漏了--reload补firewall-cmd --reloadfirewalld 与 iptables 混用乱套两套工具争夺规则二选一停掉并屏蔽另一个容器端口封不住流量走 FORWARD 和 DOCKER 链改绑 127.0.0.1 或在 DOCKER-USER 封云上封了还通安全组放行了 0.0.0.0/0先查安全组再查主机规则封了 22 导致失联规则误伤管理通道用控制台救援后续加白名单日志把磁盘写满拒绝日志限速缺失用-m limit或缩小 log-denied 范围规则生效但连接还在conntrack 保留了旧会话conntrack -D清理规则数量多导致性能下降长链线性匹配改用 ipset 或 nftables 集合这张表建议存下来遇到问题先按现象行扫一遍大多数情况能直接定位不用从零开始猜。7.2 封禁动作本身的三个保命习惯第一个习惯动防火墙之前先确认自己有带外通道。云主机有控制台、VNC物理机有带外管理虚拟机有宿主控制台。没有退路就在远程会话里改规则属于给自己埋雷。我现在的做法是每次动规则前先确认一遍控制台能登进去。第二个习惯用定时回滚做双保险。远程改规则时先挂一个几分钟后自动恢复的定时任务确认自己没断线再取消它。echo systemctl restart firewalld | at now 10 minutes atq atrm 任务号at服务没装的话用nohup bash -c sleep 600; systemctl restart firewalld 也能起到类似作用。这个技巧看起来笨但它救过我至少三次。第三个习惯规则只加不删先加后删。先把新的限制规则加进去确认业务正常、自己不断线再去删旧的放行规则。反过来操作中间会有一段两边都没保护或者彻底锁死的窗口期风险不成比例。7.3 fail2ban 只做补充不做替代最后说说 fail2ban。它做的是动态封禁监控日志发现某个 IP 反复登录失败就临时把它封掉。很多人以为装了它就不用管端口了这是误解。fail2ban 拦的是已经到达服务、并且在日志里留下痕迹的行为如果你的 6379 直接暴露在公网攻击者写入数据这一步根本不产生登录失败日志fail2ban 也就无从触发。正确的分工是防火墙负责静态的暴露面收敛把不该开的端口关掉fail2ban 负责动态的行为拦截把反复试探的 IP 临时拉黑。两者叠加效果最好。配置上要注意 fail2ban 的封禁动作最终也是写 iptables 或 nftables 规则所以它和你的防火墙体系需要协调好别让它加了一堆链和规则之后把你的手工规则挤到后面去了。另外提一句面试里经常被问到的问题就是iptables 的规则匹配顺序是怎样的DROP 和 REJECT 有什么区别怎么持久化规则这三个问题在本文里都能找到答案而且都是那种知道就能答上、不知道就完全卡住的题目。真正动手封过一遍端口的人回答这类问题会非常自然。我个人在这些年的实操中最大的体会是封端口的难点从来不在命令本身命令加起来不超过二十条难点在于搞清楚这套规则系统里到底有几个东西在管流量。Netfilter、firewalld、Docker、云安全组四层叠在一起任何一层没对齐你的规则就形同虚设。所以我现在的习惯是每接手一台新机器第一件事不是写规则而是把ss -tulnp、firewall-cmd --list-all、nft list ruleset、iptables -L -n全跑一遍把当前状态画成一张简图再动手。这个习惯花不了十分钟但能避免后面几个小时的无效排查。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门