防火墙是任何联网服务器的第一道防线。在 Linux 中,防火墙功能由内核中的 netfilter 框架提供,用户通过用户空间工具(如 iptables、nftables 或发行版封装的 ufw、firewalld)来定义规则,控制数据包能否进出系统。
为什么需要防火墙
即使你只在服务器上运行一个 Web 应用,也可能有多个端口在监听(SSH、数据库、监控代理等)。防火墙让你能够精确控制哪些 IP 可以访问哪些端口、哪些协议可以被放行,从而减少攻击面,防止未授权的访问。简而言之,防火墙就是一套“网络流量准入规则”。
核心概念:表、链、规则
无论是老的 iptables 还是新的 nftables,都遵循类似的逻辑:
- 表(table):区分不同类型的操作,例如过滤(filter)、网络地址转换(nat)、修改数据包(mangle)。
- 链(chain):数据包经过系统时依次触发的检查点,例如 INPUT(进入本机)、OUTPUT(从本机发出)、FORWARD(转发经过本机)。
- 规则(rule):每条规则决定匹配某个条件的数据包是“接受”(ACCEPT)、“丢弃”(DROP)还是“拒绝”(REJECT)等。
你添加的规则会被组织在这些链里,系统按顺序检查:一旦数据包匹配某条规则,就执行相应的动作,不再继续匹配后续规则。
实用示例:用 iptables 创建基础规则集
假设你有一台服务器,只希望接受 SSH(端口 22)、HTTP(80)和 HTTPS(443)的入站流量,其他全部丢弃。
# 清空已有规则
iptables -F
# 设置默认策略:入站丢弃,出站和转发允许
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
# 允许回环接口(本机内部通信)
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的和相关联的连接(例如 SSH 返回数据)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 开放 SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 开放 HTTP 和 HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 保存规则(视发行版而定)
iptables-save > /etc/iptables/rules.v4 # Debian/Ubuntu
# 或 service iptables save # CentOS/RHEL
这样就形成了一个“白名单”模式:只有你明确允许的端口才能被外部访问,其余入站尝试会静默丢弃。
新一代 nftables
越来越新的发行版开始默认使用 nftables 替代 iptables。nftables 使用统一的命令行工具 nft,语法更一致,性能更好。等效的简单规则集如下:
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0; policy drop; }
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport { 22, 80, 443 } accept
它用一个命令 nft 完成所有操作,并且在一个表中可以同时包含 IPv4 和 IPv6 规则(inet 类型)。
发行版的高级包装:ufw 与 firewalld
如果你觉得直接操作 iptables 或 nftables 过于琐碎,可以使用发行版提供的简化工具体。
- ufw(Uncomplicated Firewall):Ubuntu/Debian 常用,目的就是简化配置。
ufw enable
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw allow 80/tcp
ufw allow 443/tcp
ufw status verbose
- firewalld:RHEL/CentOS/Fedora 常用,引入了“区域(zone)”概念的动态管理。
systemctl start firewalld
firewall-cmd --set-default-zone=public
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
这些工具最终都会转换成内核级规则,但提供了更友好、不易出错的接口。
实践建议
- 始终保持“默认拒绝”的策略,然后明确开放需要的服务,而不是反过来。
- 使用“已建立/相关”状态匹配规则,确保主动发起的连接能正常通信,同时不必为返回数据专门打开大量端口。
- 修改防火墙规则前,最好保留一个备用登录会话,以免误操作把自己锁在服务器外。
- 定期用
iptables -L -nv或nft list ruleset检查当前生效的规则,确保理解每一条规则的含义。
防火墙并非“设置一次就忘记”的东西,而应该随服务部署、架构变更而同步调整。掌握基础的包过滤逻辑,就能为你的 Linux 系统筑起第一道有效的安全屏障。