☰
Linux防火墙完全配置指南:iptables、firewalld与ufw详解
2026/10/16 21:57:48 网站建设 项目流程

1. 为什么Linux服务器需要防火墙:先弄清楚它在挡什么

先讲一个我实际遇到过的场景。某开发者给公司内部部署了一套应用,把服务跑在8080端口,自以为端口开了就万事大吉。结果第二天用户反馈访问不了——排查到最后才发现,云厂商安全组和服务器本地防火墙双重拦截,8080端口压根没放通。业务进程在跑,端口在监听,网络层面却被掐断了,这类问题在运维现场非常常见。

很多人会有个误区:防火墙不就是"允许/拒绝端口"吗?确实,但远不止这么简单。防火墙在Linux系统里承担的是网络入口的安检员角色——所有进出服务器的数据包都要过一遍你制定的规则。做得好,它把攻击面缩到最小;做得随意,它要么放进了不该放的东西,要么把正常业务活活卡死。

从实际运维价值来看,Linux防火墙至少要解决这几类问题:

  • 端口暴露控制:服务器上可能跑了十几个服务,但只有少数需要对外开放。比如MySQL的3306端口,通常只允许内网网段访问,直接暴露到公网等于把数据库裸奔给人扫。
  • 来源IP限制:发现某个IP在暴力破解SSH,直接封掉;公司办公网段有固定出口IP,那就只让这个段访问管理端口。
  • 连接状态管理:允许已建立的连接返回数据,但拒绝从外部主动发起的"新鲜连接",防止服务器被当成跳板向外扫描。
  • 流量转发与映射:内网有多台服务器,外网只能访问入口机,这时候就要靠防火墙做端口转发或地址转换。

在你安装任何工具之前,得先想清楚:你的业务到底暴露了哪些端口?哪些人应该能访问?哪些IP绝对不能放进来?防火墙配置本质上就是把这些答案翻译成具体的规则。业务不明确、端口清单没梳理,后面配置再花哨也白搭。

1.1 防火墙不是"有一个就够",规则策略要跟着业务走

我见过不少服务器的防火墙配置停留在"装系统时默认开着的状态",或者干脆是某个教程里复制来的三行命令。这种配置最大的问题不是"没有防火墙",而是防火墙规则和实际业务脱节。

比如一台服务器只跑Nginx静态网站,其实只该放行80/443端口,但默认情况下可能连22、3306、8080都敞着。而另一台服务器明明还承担着后端API职责,防火墙却只开了80端口,导致前端调接口全部超时,最后排查发现是防火墙没配好。

所以配置防火墙的第一步不是敲命令,而是做一次端口和服务盘点:

  1. 用ss -tlnp或netstat -tlnp看当前哪些端口在监听。
  2. 逐一确认每个端口对应什么进程,是否必须对外开放。
  3. 区分出必须公网访问、仅内网访问、仅本机访问三个层级。
  4. 和业务方确认:哪些端口一旦放通可能引发安全风险(比如数据库、消息队列、管理后台)。

做完盘点,你才会知道防火墙规则应该怎么写——不是"放通所有端口然后祈祷",而是"默认拒绝,逐个放行"。

1.2 iptables、nftables、firewalld、ufw怎么选

iptables、nftables、firewalld、ufw这四个词经常把新手搞晕。简单捋一下关系:

  • iptables:Linux内核Netfilter框架的传统用户态工具,通过规则表决定数据包放行还是拒绝。绝大多数老教程都是基于它写的。
  • nftables:iptables的下一代替代品,语法更简洁、性能更好,在较新的发行版上逐渐成为默认底层实现。
  • firewalld:Red Hat系发行版(RHEL、CentOS、Rocky、Alma)的默认管理工具,它底层调用nftables/iptables,好处是用"区域(zone)"的概念简化配置。
  • ufw:Ubuntu/Debian系下的前端封装,一条命令就能放通端口,适合个人服务器和简单场景。

实际选型遵循一个原则:你的发行版默认带什么就用什么,不要刻意替换。因为默认工具和系统服务、SELinux、NetworkManager的配合是经过测试的,自己换一套反而容易引入兼容性问题。

发行版默认管理工具底层实现适用场景
RHEL/CentOS/Rocky/Almafirewalldnftables/iptables企业服务器、需要zone隔离的多网卡场景
Ubuntu/Debianufwiptables/nftables个人服务器、云主机、简单端口放行
通用/最小化系统iptables/nftables直接操作Netfilter定制化需求、无systemd环境、容器网络

不过无论你选哪个工具,iptables的规则思想都是躲不开的基础。firewalld和ufw只是帮你把复杂语法封装成了更友好的命令,但它们的规则最终都会转化为内核Netfilter里的条目。所以后面会先从iptables的核心概念讲起,再去讲firewalld和ufw怎么用,这样你无论换到哪台机器都不会懵。

2. 把规则讲清楚:iptables的表、链、匹配与动作

iptables的语法看起来晦涩,一句话就能概括:当数据包走到某个链(chain)时,我检查它是否满足某些条件,如果满足就执行某个动作(target)。跟写if语句差不多,只不过语法是固定的。

2.1 数据包在服务器里经过了哪些检查点

Linux内核Netfilter框架在数据包传递路径上放了五个钩子,iptables把规则挂在这些钩子上,每个钩子就是一条"链(chain)":

  • PREROUTING:数据包刚进来,还没做路由决策之前。适合做DNAT(目的地址转换)。
  • INPUT:数据包目的地址是本机,即将交给本地进程。这是配置服务器自身防护时最常用的链。
  • FORWARD:数据包目的地址不是本机,需要转发到别的机器。做路由器、网关时会用到。
  • OUTPUT:本机进程产生的数据包刚出来。限制服务器主动外发的流量时用它。
  • POSTROUTING:数据包即将离开网卡,适合做SNAT(源地址转换)和MASQUERADE。

五条链各有分工,而规则又按功能分到不同"表(table)"里。最常用的三张表:

  • filter表:负责放行、拒绝,是防火墙的核心表。ACCEPT / DROP / REJECT 都在这张表里生效。
  • nat表:负责地址转换,做端口映射、内网上网就靠它。
  • mangle表:用于修改数据包的特定字段,比如改TTL、打标记,一般用不上。

数据包进服务器大致是这样的流程:进网卡 → PREROUTING → 判断目的地址是不是本机 → 是则走INPUT → 交给本地进程;否则走FORWARD → 出POSTROUTING → 出网卡。本地进程发出的包,则走OUTPUT → POSTROUTING。配上这个流程,你再看iptables命令里-A INPUT、-A FORWARD就知道是在管哪一段了。

2.2 匹配条件与目标动作:选择放行还是拒绝是有讲究的

iptables规则的核心结构是"匹配条件 + 目标动作",匹配条件可以从来源、目的、协议、接口、状态多维度组合。举几个最常见的:

# 放行来自某个IP的所有流量 iptables -A INPUT -s 192.168.1.100 -j ACCEPT # 放行TCP协议的SSH端口,仅允许来自指定网段 iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT # 拒绝所有访问8080端口的流量,并返回拒绝消息 iptables -A INPUT -p tcp --dport 8080 -j REJECT # 不做任何回应地丢弃来自某个IP的流量 iptables -A INPUT -s 203.0.113.5 -j DROP

ACCEPT、DROP、REJECT三个动作的选择值得单独说:

  • ACCEPT:放行,无需解释。
  • DROP:直接把包丢掉,不告诉对方。看起来像"服务器不存在",会让对方一直等到超时。适合对付扫描器和攻击IP,增加对方判断成本。
  • REJECT:拒绝并返回错误消息(如icmp-port-unreachable)。对方能立刻知道"这里不可达",排障时更友好,适合普通业务端口。

经验法则:对攻击来源IP用DROP,对业务限制用REJECT。比如公司内部网段之外的地址访问MySQL,用REJECT让业务方第一时间意识到"我被防火墙挡了",而不是陷入"数据库是不是挂了"的猜疑。

2.3 规则的顺序意味着什么

iptables是从上到下逐条匹配,匹配到就执行动作,不再往下看。这意味着规则的顺序直接决定最终效果。最常见的错误就是把"拒绝所有"放在"放行特定端口"前面,结果全被拒了。

正确的思路是:先放行需要的,最后再拒绝兜底。比如:

iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A INPUT -j DROP

前三条放行需要的,最后一条作为默认策略挡住其余所有流量。这也是生产环境最常见的配置思路——白名单机制,默认拒绝,显式放行。

3. 从零配置一台服务器的防火墙:放行、拒绝与端口管理实战

纸上谈兵差不多了,现在就以一台全新Linux服务器为例,演示一套完整的防火墙配置过程。

3.1 先定基线:默认拒绝还是默认放行

配置防火墙前必须先回答一个问题:这台服务器默认该接受所有流量,再排除危险项;还是默认拒绝所有流量,再放行必要项?

这两种思路对应了两种安全策略:

  • 默认放行 + 黑名单:配置简单,运维省心,但一旦漏配某个危险端口,攻击面就是敞开的。适合内网测试机、个人开发机。
  • 默认拒绝 + 白名单:安全级别高,但每次上新业务都得记得放行端口,否则服务跑起来却连不通,容易被自己坑。

生产环境我强烈建议用白名单思路。具体做法就是先把默认策略改成DROP,再逐条放行必要端口。这会让排障过程更痛苦,但长远看安全收益大得多。

# 先把默认策略设置为拒绝(INPUT链默认拒绝,FORWARD默认拒绝) iptables -P INPUT DROP iptables -P FORWARD DROP

这里有个非常重要的提醒:在你执行iptables -P INPUT DROP之前,必须先确保有一条ACCEPT规则允许SSH访问,否则当前连接会立刻断开。如果你是通过SSH远程操作这台服务器,就先把下面这条加上:

# 放行现有SSH连接及相关状态,避免把自己锁在外面 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 22 -j ACCEPT

第一条的意思是"已经建立连接的返回流量直接放行"。很多人只放行22端口却不加这一条,结果SSH连接能建上但非常不稳定,因为返回的数据包没有被识别为"已有连接"。加了conntrack状态匹配后,所有从本机发出的连接对应的回应包都会自动放行,这是生产配置里不可缺少的一行。

3.2 放行业务端口的完整操作流程

假设这台服务器的角色是"Web服务器 + API后端",需要对外开放的端口有:80(HTTP)、443(HTTPS)、8080(业务API),SSH端口保持默认22但只允许公司网段访问。下面是完整命令序列:

# 1. 清空现有规则(仅在新配置时使用,谨慎执行) iptables -F iptables -t nat -F iptables -t mangle -F # 2. 设置默认策略为DROP iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT # 3. 放行回环接口,保证本机内部通信正常 iptables -A INPUT -i lo -j ACCEPT # 4. 放行已建立连接和相关连接,保证SSH稳定 iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT # 5. 放行公司办公网段访问SSH iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT # 6. 放行80、443、8080端口 iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT iptables -A INPUT -p tcp --dport 8080 -j ACCEPT # 7. 限制ping:允许内网ping,外网ping直接丢弃 iptables -A INPUT -p icmp --icmp-type echo-request -s 10.0.0.0/8 -j ACCEPT iptables -A INPUT -p icmp --icmp-type echo-request -j DROP # 8. 查看最终规则 iptables -L -n --line-numbers

几个值得注意的细节:

  • OUTPUT策略保持ACCEPT是常态,限制服务器主动外连是更高级的玩法,基础阶段不用碰。
  • 回环接口lo必须放行,很多应用(如MySQL本机连接、消息队列)依赖127.0.0.1通信,误杀会引发莫名其妙的问题。
  • --line-numbers显示规则编号,后续删改规则时非常有用,几乎每次排查都要用到。
  • 建议在修改防火墙期间保持一个已建立的SSH会话作为"逃生通道",万一手滑把22端口规则删了,至少当前连接不会断(配合conntrack规则还能持续维持一段时间)。

3.3 封禁与限制:怎么对付扫描和异常IP

服务器跑在公网上,每天都会被各类扫描器光顾,这是常态。看日志时发现某个IP反复尝试登录SSH,或者在短时间内发起大量连接,手动封禁的操作很简单:

# 封禁单个IP iptables -A INPUT -s 203.0.113.50 -j DROP # 封禁整个网段 iptables -A INPUT -s 203.0.113.0/24 -j DROP # 封禁对22端口的暴力尝试(配合速率限制) iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSHAttack --rsource iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 5 --name SSHAttack --rsource -j DROP

第二条命令的逻辑:如果有来自同一来源的SSH新连接在60秒内超过5次,就丢包。这就是最简单的暴力破解防护。不过手动封禁只能治标,要防得彻底,还得配合Fail2ban这类工具,它能自动分析日志、动态封锁攻击IP,原理其实就是调iptables。

再提醒一个容易忽略的点:封禁IP前先确认是不是公司出口IP。我见过有人把一家外包公司的整个网段封了,结果对方技术对接联调了整整一周,最后发现是自家防火墙把对方IP误封了。封禁前至少看一眼IP归属,核下日志确认是攻击行为再动手。

3.4 不要踩的坑:iptables规则重启后全没了

新手用iptables最容易踩的坑就是规则"一重启就消失"。原因很简单:iptables命令只是临时修改内存里的规则表,并没有写入任何配置文件。系统每次启动时都会加载一份默认规则,你手动加的那些都不在。

这是个极其隐蔽的坑,因为配置当时一切正常,等下次机房重启或系统更新自动重启,业务就全断在防火墙上了。所以每改完一批正式规则,务必立刻保存。常见做法:

# CentOS/RHEL 7前 service iptables save # 通用做法 iptables-save > /etc/iptables/rules.v4 iptables-save > /etc/sysconfig/iptables

具体保存到哪里取决于你的发行版和启动方式,下一节会详细展开讲。

4. NAT转发、端口映射与规则持久化:从临时命令到开机自启

前面几节讲的都是INPUT链上的收发包控制,解决了"哪些流量能进出服务器"的问题。但Linux防火墙还有一个更强大的能力:改写数据包的地址信息,实现转发和映射。这节会涉及内网服务器、跳板机、端口转发等场景,也是网上教程里最乱的部分。

4.1 什么时候才需要NAT和端口映射

假设一个场景:某公司内网有一台数据库服务器(内网IP 192.168.1.10),它没有公网IP,外网无法直接访问。但业务上偶尔需要从外部连过去做管理,怎么解决?在防火墙上加一条DNAT规则,把公网IP的某个端口映射到内网这台数据库服务器的3306端口。

另一个更常见的场景:公司有多台内网服务器要访问外网(比如下载软件包),但只有一个公网IP出口。这时候需要SNAT或MASQUERADE,让内网IP的数据包伪装成公网IP的流量出去,回来时再转换给对应内网机器。

可以看到,NAT本质上解决的是"内网与外部网络互通"的问题。除非你的服务器就是网关/路由器角色,或者有"外网访问内网特定端口"的需求,不然大概率用不到这节的知识。但一旦用到,iptables的NAT配置是绕不开的。

4.2 一条命令实现的DNAT与SNAT

**端口映射(DNAT)**的操作是在PREROUTING链上改写目标地址,语法如下:

# 将公网网卡IP的2222端口,转发到内网IP 192.168.1.10的22端口 iptables -t nat -A PREROUTING -p tcp --dport 2222 -d 公网IP -j DNAT --to-destination 192.168.1.10:22 # 同时需要放行FORWARD链上的对应流量 iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 22 -j ACCEPT # 为了回程包能正确回去,通常还要开启IP转发 echo 1 > /proc/sys/net/ipv4/ip_forward

**源地址转换(SNAT)**则是在POSTROUTING链上改写源地址:

# 内网网段10.0.0.0/24的所有流量,从eth0出去时统一伪装成eth0的IP iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

MASQUERADE和SNAT有细微区别:MASQUERADE会自动读取网卡当前IP,适合动态IP(比如PPPoE拨号);SNAT --to-source指定固定源地址,性能比MASQUERADE略好。家庭路由、云主机拨号场景用MASQUERADE就行,固定IP的网关服务器用SNAT更稳。

做NAT转发时有三个坑值得提前说:

  1. 内核IP转发默认是关闭的。很多人配完NAT没反应,最后发现/proc/sys/net/ipv4/ip_forward还是0。最好通过/etc/sysctl.conf写入net.ipv4.ip_forward = 1永久开启。
  2. 只做DNAT不改FORWARD策略会失灵。如果你把FORWARD默认策略设成了DROP,就必须单独放行对应转发流量,否则DNAT规则本身不会生效。
  3. NAT规则写在nat表,别误放到filter表。不少人照抄命令结果写错了表,明明在-t nat后面却加了filter才有的参数,规则当然不会工作。

4.3 规则持久化:不同发行版的保存方式

规则的持久化问题前面已经埋了伏笔,这里给出不同发行版下的标准做法:

CentOS/RHEL 7及以上(firewalld环境),如果你还在直接使用iptables命令,需要先确认firewalld是否在运行:

systemctl status firewalld

如果firewalld在运行,官方推荐用firewall-cmd管理规则,它自己会负责持久化。如果你确实要用原生iptables,就得停掉firewalld并安装iptables-services:

systemctl stop firewalld systemctl disable firewalld yum install iptables-services systemctl enable iptables

之后iptables-save > /etc/sysconfig/iptables保存的规则会在开机时自动加载。

Ubuntu/Debian(ufw环境),推荐直接用ufw管理。如果你用原生iptables,最常见的持久化方法:

# 安装iptables-persistent apt install iptables-persistent # 保存规则 iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6

iptables-persistent会在系统启动时自动加载/etc/iptables/rules.v4和rules.v6,这是目前Debian/Ubuntu系比较省心的方案。

不管哪个发行版,都要养成一个习惯:规则改完,立刻iptables-save验证一下文件内容,确保已经落盘。别等到重启后再后悔。

5. firewalld和ufw:不同发行版下的更省心路径

原生iptables虽然灵活,但配置复杂、规则顺序容易出错,日常管理其实有更顺手的前端工具。如果你用的是CentOS/Red Hat系,多半会面对firewalld;Ubuntu/Debian则是ufw的天下。

5.1 firewalld的zone概念与常用命令

firewalld引入了"区域(zone)"的概念。每个区域定义了一组对数据包的信任程度和放行策略,网卡和来源IP可以被归入某个区域。默认区域是public(不信任外部流量),接口绑定了公网网卡就用它。

zone的设计理念是:不同来源的流量给不同级别的信任。比如内网接口绑到trusted区域就等于"什么端口都放行";对外网卡绑到public,只显式放行需要的端口。这种"按区域划分信任"的思路在大规模服务器上很有用,比纯iptables规则好理解得多。

常用命令如下:

# 查看当前默认区域和已绑定的接口 firewall-cmd --get-default-zone firewall-cmd --list-all # 放行端口(立即生效) firewall-cmd --add-port=8080/tcp # 放行端口(永久生效,重启后仍在) firewall-cmd --permanent --add-port=8080/tcp # 放行服务(firewalld内置了服务名映射,如http、https、ssh) firewall-cmd --permanent --add-service=http # 移除端口 firewall-cmd --permanent --remove-port=8080/tcp # 重载配置让永久规则生效 firewall-cmd --reload # 禁止某个来源IP访问 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.50" drop'

最容易被坑的地方是临时规则与永久规则的区别。直接--add-port不加--permanent,只对当前会话生效,重启就没了。很多人以为自己放行了端口,过了几天服务器重启,业务又开始不通,排查一圈才发现这个细节。

rich-rule是firewalld的高级玩法,它的语法可以表达比普通add-port更复杂的规则,比如"端口+来源IP"的组合限制。实际使用频率不高,但写复杂策略时会用得上。

5.2 ufw的一行命令哲学

ufw的设计目标就是"简单"。一条命令解决一个需求,非常适合个人开发者和云主机场景。最常用的操作基本都能用一行搞定:

# 启用防火墙(默认拒绝外部访问,允许所有出站) ufw enable # 放行SSH端口(注意,启用前务必先执行,否则会断连) ufw allow 22/tcp # 放行Web端口范围 ufw allow 80,443/tcp # 放行来自特定IP的访问 ufw allow from 10.0.0.0/8 to any port 22 # 拒绝来自特定IP ufw deny from 203.0.113.50 # 查看规则列表 ufw status numbered # 删除规则(按编号) ufw delete 3

ufw底层仍然操作iptables,但它帮你管理了规则顺序、状态匹配这些细节。对单台服务器来说,用ufw就够了,没必要去记iptables那套复杂语法。有个额外提醒:在云服务器上执行ufw enable之前,一定确认云厂商安全组也已经放行了22端口。有一次我在某云主机上用ufw启用了默认拒绝,结果把厂商安全组也忘了核对,两个层面一叠加,后悔都来不及。

5.3 从配置文件看懂默认规则

很多服务默认是允许从任何地方访问的,它们的安装脚本或服务启动时会自动放行端口,但未必会写进防火墙配置里。所以"为什么某个端口突然通了"和"为什么配置了却不通"在排查时容易被忽略。

看firewalld的规则文件在/etc/firewalld/zones/*.xml和/usr/lib/firewalld/zones/*.xml,ufw的规则则记录在/etc/ufw/*.rules中。如果你发现某个端口没配规则却意外放行了,多半是服务安装时往这些文件里写了内容。这也是排查网络问题时另一个值得看的点。

对比起来,firewalld比ufw更适合复杂网络环境,ufw更适合简单服务器。但工具只是外衣,内核里跑的始终是Netfilter。理解这一点后,你会发现无论在哪台机器上,排查路径都是通用的。

6. 排查链路与实际坑:规则不生效、连接超时、重启丢失

防火墙配置出问题,最典型的症状就两种:该通的连不上,该断的却在通。下面把这几类问题的完整排查链路走一遍,这是我运维时总结的固定套路。

6.1 排查"端口不通"的完整链路

某天收到告警:服务端口访问不了。我的排查顺序基本固定:

第一步,确认进程在不在监听:

ss -tlnp | grep 8080

如果没有任何输出,那是服务根本没起来,防火墙再放行也没用。这一步排掉了60%的"假防火墙问题"。

第二步,确认监听地址是否绑到了正确网卡:

ss -tlnp | grep 8080

如果看到监听在127.0.0.1:8080,那只能本机访问,外部永远不通。这就是应用配置的问题了。

第三步,确认防火墙规则是否放行:

iptables -L -n --line-numbers | grep 8080 # 或者用firewalld/ufw查看 firewall-cmd --list-all ufw status verbose

第四步,确认云安全组/上层网络设备也放行了。服务器本地防火墙只是第一道门,云厂商安全组、机房硬件防火墙、NAT网关都可能拦截。这一步经常被忽略,尤其是"本地明明通了,公网却访问不了"的情况。

第五步,确认默认策略没有把规则顺序搞错。已经提过,iptables是顺序匹配的,如果某条DROP规则错误地排在了放行规则前面,那么后面的规则永远不会被执行。用iptables -L --line-numbers仔细检查每一行的顺序。

第六步,用tcpdump抓包确认数据包是否到达了网卡:

tcpdump -i eth0 port 8080 -nn

如果数据包到达了网卡但连接仍然失败,说明是防火墙或内核层面的问题;如果压根没抓到包,那问题出在网络路径的某个上游设备上。

6.2 三类高频故障复盘

故障一:重启后规则丢失

症状很典型:服务器一切正常,某天机房断电重启,所有业务端口全不通。原因前面反复提过——iptables规则没保存。这个故障的伤害性极大,因为它发生在"最不经意的时刻",而且排查时很容易先怀疑服务而不是防火墙。

故障二:放行了端口但连不上,且没有报错

这类问题的特点是"客户端一直卡在连接中"。按上面链路走一遍,最终可能会发现:要么服务监听在127.0.0.1,要么规则匹配了更前面的DROP,要么云安全组没放行。有一次某开发者反馈8080不通,我查了半个小时,最后发现是他在本机上把端口写错成了8008,防火墙规则倒是一点问题没有。

故障三:防火墙规则只生效了一部分

常见于DNAT和FORWARD场景。比如PREROUTING的DNAT规则加了,但FORWARD链默认DROP,于是丢弃的包根本走不到内网服务器。这个故障现象是"外网访问映射端口超时",但内网直接访问目标服务器又是通的。解法就是前面说的,留意ip_forward和FORWARD链的联动。

6.3 运维阶段的检查习惯与最小化权限原则

防火墙不是"配完就完事"的东西,它更像一份需要持续维护的策略文件。在长期运维中,我养成了几个习惯,分享出来供参考:

  1. 每次变更前备份当前规则:iptables-save > rules-$(date +%F).bak,一行命令的备份成本极低,回滚收益极高。特别是服务器上跑了重要业务时,这条能救你命。
  2. 变更后立刻验证再保存:加完规则不要急着save,先确保当前业务正常,观察几分钟,没问题再保存持久化。
  3. 定期核对规则和业务端口清单:业务会变,端口会开也会关,但防火墙规则不会自动更新。每季度用脚本对比一次ss -tln和防火墙规则,发现"没规则的监听端口"和"没端口的陈旧规则",逐一确认处理。
  4. 权限最小化:默认拒绝是所有安全配置的基石,但"最小化"不应该只是"少放端口",还体现在来源IP、协议类型、端口范围上。能限制来源IP的,就不要放行给所有人;能只放行TCP的,就不要顺便把UDP也放了。

7. 写在最后的几个小建议

这些年在各种机器上配防火墙,最深切的感受是:危险往往不是来自规则复杂,而是来自对规则的失控。一张清晰的端口清单、一份备份好的规则文件、一条确认过的持久化路径,远比记住一堆iptables参数更有价值。

我个人的一个小习惯是:在每台服务器的/root/下放一份FIREWALL_RULES.md,记录这台机器的业务端口、开放原因、对应负责人、最后变更日期。看起来有点"过度规范",但当你同时维护几十台机器、某天深夜被叫起来排查问题时,这份文档能帮你省下一晚上的折腾。

另外,如果你刚开始接触防火墙,建议先在测试机上把整套操作走一遍,包括"故意把规则写错"和"模拟重启后恢复"这两个演练。经历过一次规则写错导致连不上服务器的过程,你才会真正理解为什么要在动手前留好逃生通道。

防火墙做得好,应该让你感受不到它的存在——业务该通的通,不该通的一律进不来。希望这篇文章能帮你少走几步弯路,把Linux防火墙这个"网络守门人"真正用明白。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询