主题
Linux 防火墙配置 - iptables、ufw 与 firewalld 详解
1. 防火墙基础
1.1 防火墙概念
防火墙是一种网络安全系统,用于监控和控制传入和传出的网络流量。它基于预定义的安全规则,决定是允许还是阻止特定的数据包。在 Linux 系统中,防火墙可以在不同级别实现:
- 主机防火墙:保护单个 Linux 主机
- 网络防火墙:保护整个网络,通常部署在网络边界
防火墙通过以下机制工作:
- 数据包过滤:根据源 IP、目标 IP、端口、协议等过滤数据包
- 状态检测:跟踪连接状态,只允许属于已建立连接的数据包通过
- 应用层过滤:在应用层检查数据包内容
1.2 Linux 防火墙架构
Linux 防火墙架构包含以下组件:
内核空间组件:
- netfilter:Linux 内核中的网络数据包处理框架
- nf_tables:新一代 Linux 内核数据包过滤框架
用户空间工具:
- iptables:传统的防火墙配置工具,与 netfilter 交互
- nftables:新一代防火墙配置工具,与 nf_tables 框架交互
- ufw:Ubuntu 防火墙,iptables 的前端工具
- firewalld:动态防火墙管理器,主要用于 RHEL/CentOS 系统
数据包处理流程:
- 数据包从网络接口进入内核
- 经过 netfilter 钩子点(PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING)
- 在每个钩子点,执行相应的防火墙规则
- 根据规则决定接受、拒绝或丢弃数据包
1.3 防火墙策略类型
常见的防火墙策略类型:
- 默认拒绝策略:默认拒绝所有流量,只允许明确允许的流量通过
- 默认允许策略:默认允许所有流量,只拒绝明确禁止的流量
安全最佳实践是采用默认拒绝策略,这样可以减少潜在的安全漏洞。
2. iptables 基础
2.1 iptables 概述
iptables 是 Linux 系统上最常用的防火墙工具,它是与内核中的 netfilter 框架交互的命令行工具。iptables 允许用户定义规则来过滤、修改或转发网络数据包。
iptables 的基本组成部分:
表 (Tables):包含规则链的集合
- filter 表:用于过滤数据包(默认表)
- nat 表:用于网络地址转换
- mangle 表:用于修改数据包属性
- raw 表:用于处理连接跟踪前的数据包
- security 表:用于强制访问控制
链 (Chains):数据包处理路径上的检查点
- PREROUTING:数据包到达后但路由决策前
- INPUT:目标为本机的数据包
- FORWARD:需要转发的数据包
- OUTPUT:本机产生的数据包
- POSTROUTING:路由决策后发送前
规则 (Rules):定义处理数据包的条件和动作
- 匹配条件:如源/目标 IP、端口、协议等
- 目标动作:如 ACCEPT、DROP、REJECT 等
2.2 iptables 基本命令
安装 iptables:
bash
# Debian/Ubuntu 系统
sudo apt update
sudo apt install iptables iptables-persistent
# CentOS/RHEL 系统
sudo yum install iptables-services查看 iptables 规则:
bash
# 查看所有表的规则
sudo iptables -L -n -v
# 查看特定表的规则
sudo iptables -t nat -L -n -v
# 查看规则并显示行号
sudo iptables -L -n -v --line-numbers
# 查看原始规则(带注释)
sudo iptables-save清除 iptables 规则:
bash
# 清除所有链的规则(默认表)
sudo iptables -F
# 清除特定表的规则
sudo iptables -t nat -F
# 删除用户自定义链
sudo iptables -X
# 将计数器归零
sudo iptables -Z设置默认策略:
bash
# 设置默认拒绝策略(默认表)
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# 设置特定表的默认策略
sudo iptables -t nat -P PREROUTING ACCEPT
sudo iptables -t nat -P POSTROUTING ACCEPT
sudo iptables -t nat -P OUTPUT ACCEPT保存和恢复规则:
bash
# 保存规则(Debian/Ubuntu)
sudo netfilter-persistent save
# 保存规则(CentOS/RHEL)
sudo service iptables save
# 或手动保存到文件
sudo iptables-save > /etc/iptables/rules.v4
# 从文件恢复规则
sudo iptables-restore < /etc/iptables/rules.v42.3 iptables 规则语法
基本语法:
bash
iptables [-t table] [command] [chain] [match] [-j target]命令选项:
-A, --append:向链末尾添加规则-I, --insert:在指定位置插入规则-D, --delete:删除规则-R, --replace:替换规则-L, --list:列出链中的所有规则-F, --flush:清空链中的所有规则-P, --policy:设置链的默认策略-N, --new-chain:创建新链-X, --delete-chain:删除链
匹配条件:
-p, --protocol:匹配协议(tcp, udp, icmp, all)-s, --source:匹配源 IP 地址或网段-d, --destination:匹配目标 IP 地址或网段--sport:匹配源端口--dport:匹配目标端口-i, --in-interface:匹配入站网络接口-o, --out-interface:匹配出站网络接口-m state --state:匹配连接状态(NEW, ESTABLISHED, RELATED, INVALID)-m multiport --sports:匹配多个源端口-m multiport --dports:匹配多个目标端口
目标动作:
ACCEPT:接受数据包DROP:丢弃数据包,不发送任何响应REJECT:拒绝数据包,并发送拒绝响应LOG:记录数据包信息到系统日志REDIRECT:重定向数据包到本地端口MASQUERADE:源地址转换(SNAT)SNAT:源地址转换DNAT:目标地址转换
2.4 iptables 实用规则示例
基础安全规则:
bash
# 允许已建立和相关连接
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许本地环回接口
sudo iptables -A INPUT -i lo -j ACCEPT
# 允许 ICMP (ping)
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 允许 SSH 访问
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 HTTP 和 HTTPS 访问
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# 限制特定 IP 访问 SSH
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT
# 限制特定时间段访问
sudo iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon-Fri -j ACCEPT限制连接数:
bash
# 限制单个 IP 的 SSH 连接尝试次数
sudo iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j REJECT
# 限制连接速率
sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# 防止 SYN 洪水攻击
sudo iptables -A INPUT -p tcp --syn -m limit --limit 25/s --limit-burst 100 -j ACCEPT日志记录:
bash
# 记录丢弃的数据包
sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
# 记录特定端口的访问尝试
sudo iptables -A INPUT -p tcp --dport 2222 -j LOG --log-prefix "SSH-ATTEMPT: " --log-level 4
sudo iptables -A INPUT -p tcp --dport 2222 -j DROP网络地址转换 (NAT):
bash
# 配置 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward
# SNAT (共享上网)
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# DNAT (端口转发)
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80
# 将内部服务映射到公网端口
sudo iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.20:22
sudo iptables -A FORWARD -p tcp -d 192.168.1.20 --dport 22 -j ACCEPT3. ufw (Uncomplicated Firewall)
3.1 ufw 概述
ufw(Uncomplicated Firewall)是 Ubuntu 开发的一个简化的防火墙配置工具,它是 iptables 的前端,使防火墙配置变得更加简单易用。ufw 主要用于 Debian、Ubuntu 等系统,但也可以在其他 Linux 发行版上使用。
ufw 的主要特点:
- 简单的命令行界面
- 默认拒绝策略
- 支持基于应用程序的配置文件
- 提供状态信息查看
- 支持 IPv4 和 IPv6
3.2 ufw 基础命令
安装 ufw:
bash
# Debian/Ubuntu 系统
sudo apt update
sudo apt install ufw基本操作:
bash
# 查看 ufw 状态
sudo ufw status
# 启用 ufw
sudo ufw enable
# 禁用 ufw
sudo ufw disable
# 重置所有规则
sudo ufw reset
# 查看应用配置文件
sudo ufw app list
# 查看特定应用的详细规则
sudo ufw app info "OpenSSH"设置默认策略:
bash
# 设置默认拒绝入站连接,允许出站连接
sudo ufw default deny incoming
sudo ufw default allow outgoing添加和删除规则:
bash
# 允许特定端口
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
# 允许特定 IP 地址的所有连接
sudo ufw allow from 192.168.1.100
# 允许特定 IP 访问特定端口
sudo ufw allow from 192.168.1.0/24 to any port 22
# 允许特定应用
sudo ufw allow OpenSSH
sudo ufw allow "Apache Full"
# 删除规则
sudo ufw delete allow 22/tcp
# 或使用规则编号删除
sudo ufw status numbered
sudo ufw delete 13.3 ufw 高级配置
限制连接:
bash
# 限制特定 IP 访问特定端口的频率
sudo ufw limit 22/tcp # 限制 SSH 连接尝试
# 这相当于添加了如下 iptables 规则:
# -A ufw-user-input -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 6 --name DEFAULT --rsource -j REJECT --reject-with tcp-reset
# -A ufw-user-input -p tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource -j ACCEPT配置 IPv6:
编辑 /etc/ufw/ufw.conf 文件:
bash
IPV6=yes # 启用 IPv6然后重新加载 ufw:
bash
sudo ufw reload自定义应用配置文件:
创建新的应用配置文件,例如 /etc/ufw/applications.d/myapp:
bash
[MyApp]
title=My Application
description=My custom application
ports=8080/tcp|8443/tcp然后更新 ufw 应用列表:
bash
sudo ufw app update MyApp
sudo ufw app info MyApp
sudo ufw allow MyApp查看和修改 ufw 规则文件:
bash
# 查看规则文件
cat /etc/ufw/user.rules
# 添加自定义 iptables 规则
cat > /etc/ufw/before.rules << EOF
# 在默认规则前添加自定义规则
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
# 自定义规则示例
-A ufw-before-input -p tcp --dport 8080 -j ACCEPT
# 原有的默认规则...
COMMIT
EOF
sudo ufw reload4. firewalld
4.1 firewalld 概述
firewalld 是一个动态防火墙管理器,它提供了一个支持网络区域的防火墙管理系统。firewalld 主要用于 RHEL、CentOS 7+、Fedora 等系统,它使用 nftables 作为默认后端(在较新的版本中),而不是 iptables。
firewalld 的主要特点:
- 动态规则更新,无需重启服务
- 支持网络区域(zones)
- 支持服务和端口管理
- 支持富规则(rich rules)
- 提供 CLI 和图形界面配置工具
4.2 firewalld 基础命令
安装 firewalld:
bash
# CentOS/RHEL 系统
sudo yum install firewalld
# 安装图形界面工具
sudo yum install firewall-config基本操作:
bash
# 启动并启用 firewalld 服务
sudo systemctl start firewalld
sudo systemctl enable firewalld
# 查看 firewalld 状态
sudo firewall-cmd --state
sudo systemctl status firewalld
# 查看当前活动区域
sudo firewall-cmd --get-active-zones
# 查看默认区域
sudo firewall-cmd --get-default-zone
# 设置默认区域
sudo firewall-cmd --set-default-zone=public
# 查看所有可用区域
sudo firewall-cmd --get-zones区域(Zones)管理:
bash
# 查看特定区域的配置
sudo firewall-cmd --zone=public --list-all
# 查看所有区域的配置
sudo firewall-cmd --list-all-zones
# 将网络接口添加到区域
sudo firewall-cmd --zone=public --add-interface=eth0
# 永久添加网络接口到区域
sudo firewall-cmd --permanent --zone=public --add-interface=eth0服务(Services)管理:
bash
# 查看所有可用服务
sudo firewall-cmd --get-services
# 查看特定服务的详细信息
sudo firewall-cmd --info-service=http
# 添加服务到区域
sudo firewall-cmd --zone=public --add-service=http
# 永久添加服务到区域
sudo firewall-cmd --permanent --zone=public --add-service=http
# 同时添加多个服务
sudo firewall-cmd --permanent --zone=public --add-service={ssh,http,https}端口管理:
bash
# 允许特定端口和协议
sudo firewall-cmd --zone=public --add-port=8080/tcp
# 永久允许特定端口范围
sudo firewall-cmd --permanent --zone=public --add-port=8000-9000/tcp
# 列出已允许的端口
sudo firewall-cmd --zone=public --list-ports4.3 firewalld 高级配置
富规则(Rich Rules):
富规则提供了更灵活的规则定义方式,可以基于源/目标地址、端口、协议等条件创建复杂规则。
bash
# 允许来自特定 IP 的 SSH 访问
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept'
# 拒绝来自特定网段的 HTTP 访问
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port protocol="tcp" port="80" reject'
# 限制连接速率
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" port port="80" protocol="tcp" limit value="25/m" accept'
# 记录日志并接受连接
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" log prefix="SSH-ACCESS: " level="info" accept'端口转发:
bash
# 启用 IP 伪装(NAT)
sudo firewall-cmd --permanent --zone=public --add-masquerade
# 设置端口转发(将 80 端口转发到 8080 端口)
sudo firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toport=8080
# 设置端口转发到另一台主机
sudo firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=8080自定义服务:
创建自定义服务文件,例如 /etc/firewalld/services/myapp.xml:
xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>MyApp</short>
<description>My custom application</description>
<port protocol="tcp" port="8080"/>
<port protocol="tcp" port="8443"/>
</service>然后重新加载 firewalld 并添加服务:
bash
sudo firewall-cmd --reload
sudo firewall-cmd --permanent --zone=public --add-service=myapp
sudo firewall-cmd --reload修改和删除规则:
bash
# 查看所有永久规则
sudo firewall-cmd --permanent --list-all
# 重新加载规则使永久规则生效
sudo firewall-cmd --reload
# 删除规则
sudo firewall-cmd --permanent --zone=public --remove-service=http
sudo firewall-cmd --reload
# 删除富规则
sudo firewall-cmd --permanent --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept'
sudo firewall-cmd --reload5. nftables
5.1 nftables 概述
nftables 是 Linux 内核中的新一代数据包过滤框架,它设计用来替代传统的 netfilter/iptables 框架。nftables 提供了更灵活的语法、更好的性能和更强大的功能。
nftables 的主要特点:
- 简化的语法,类 C 语言风格
- 更强大的表达式评估引擎
- 减少代码重复和冗余规则
- 更好的性能,尤其是在大量规则的情况下
- 支持可重用的命名集和映射
5.2 nftables 基础命令
安装 nftables:
bash
# Debian/Ubuntu 系统
sudo apt update
sudo apt install nftables
# CentOS/RHEL 系统
sudo yum install nftables基本操作:
bash
# 启动 nftables 服务
sudo systemctl start nftables
sudo systemctl enable nftables
# 查看当前规则集
sudo nft list ruleset
# 查看特定表
sudo nft list table inet filter
# 清空所有规则
sudo nft flush ruleset创建表和链:
bash
# 创建表(inet 家族同时支持 IPv4 和 IPv6)
sudo nft add table inet filter
# 创建链
sudo nft add chain inet filter input { type filter hook input priority 0; policy drop; }
sudo nft add chain inet filter forward { type filter hook forward priority 0; policy drop; }
sudo nft add chain inet filter output { type filter hook output priority 0; policy accept; }5.3 nftables 规则示例
基础安全规则:
bash
# 允许已建立和相关连接
sudo nft add rule inet filter input ct state { established, related } accept
# 允许本地环回接口
sudo nft add rule inet filter input iifname "lo" accept
# 允许 SSH 访问
sudo nft add rule inet filter input tcp dport 22 accept
# 允许 HTTP 和 HTTPS 访问
sudo nft add rule inet filter input tcp dport { 80, 443 } accept
# 允许 ICMP 消息
sudo nft add rule inet filter input ip protocol icmp accept
sudo nft add rule inet filter input ip6 nexthdr icmpv6 accept使用命名集:
bash
# 创建 IP 地址集
sudo nft add set inet filter allowed_ips { type ipv4_addr; flags interval; }
sudo nft add element inet filter allowed_ips { 192.168.1.0/24, 10.0.0.5 }
# 使用集创建规则
sudo nft add rule inet filter input ip saddr @allowed_ips tcp dport 22 accept
# 创建端口集
sudo nft add set inet filter allowed_ports { type inet_service; flags interval; }
sudo nft add element inet filter allowed_ports { 80, 443, 8080-8090 }
sudo nft add rule inet filter input tcp dport @allowed_ports accept地址转换:
bash
# 创建 nat 表
sudo nft add table nat
sudo nft add chain nat prerouting { type nat hook prerouting priority -100; }
sudo nft add chain nat postrouting { type nat hook postrouting priority 100; }
# SNAT (源地址转换)
sudo nft add rule nat postrouting oifname "eth0" snat to 203.0.113.1
# DNAT (目标地址转换/端口转发)
sudo nft add rule nat prerouting iifname "eth0" tcp dport 8080 dnat to 192.168.1.10:80保存和恢复规则:
bash
# 保存规则到文件
sudo nft list ruleset > /etc/nftables.conf
# 从文件加载规则
sudo nft -f /etc/nftables.conf6. 防火墙最佳实践
6.1 基本安全原则
- 默认拒绝策略:默认拒绝所有入站连接,只允许明确授权的服务
- 最小权限原则:只开放必要的端口和服务
- 定期审查规则:定期检查防火墙规则,移除不再需要的规则
- 使用主机防火墙:即使在有网络防火墙的环境中,也要启用主机防火墙
- 日志记录:记录防火墙活动,便于监控和故障排除
6.2 通用防火墙配置
Web 服务器防火墙配置示例:
bash
# iptables 示例
# 设置默认策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允许已建立和相关连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许本地连接
iptables -A INPUT -i lo -j ACCEPT
# 允许 Web 服务
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT # HTTPS
# 限制 SSH 仅允许从管理网络访问
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 22 -j ACCEPT
# 可选:限制访问速率
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/min --limit-burst 100 -j ACCEPT数据库服务器防火墙配置示例:
bash
# ufw 示例
# 允许 Web 服务器访问数据库
sudo ufw allow from 192.168.1.5 to any port 3306 # MySQL
sudo ufw allow from 192.168.1.5 to any port 5432 # PostgreSQL
# 允许管理网络的 SSH 访问
sudo ufw allow from 192.168.1.0/24 to any port 226.3 性能优化
- 优化规则顺序:将常用规则和匹配频率高的规则放在前面
- 合并相似规则:使用多端口匹配合并多个规则
- 使用 iptables 模块:如 multiport、state 等,减少规则数量
- 对于 nftables:使用命名集和映射提高性能
- 定期清理:移除未使用的规则和链
6.4 监控和日志分析
设置防火墙日志:
bash
# iptables 日志示例
iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4
# firewalld 富规则日志示例
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule log prefix="FIREWALL-DROP: " level="warning" drop'使用日志分析工具:
- logwatch:自动分析系统日志
- rsyslog:集中日志收集
- ELK Stack:企业级日志分析平台
- Fail2ban:基于日志自动封禁可疑 IP
7. 故障排除
7.1 常见问题与解决方案
无法访问服务:
检查服务是否正在运行
bashsudo systemctl status <service-name>检查端口是否已开放
bash# iptables sudo iptables -L -n | grep <port> # ufw sudo ufw status | grep <port> # firewalld sudo firewall-cmd --list-ports | grep <port>暂时禁用防火墙测试
bash# iptables sudo iptables -P INPUT ACCEPT # ufw sudo ufw disable # firewalld sudo systemctl stop firewalld
防火墙规则不生效:
- 检查规则语法是否正确
- 确认是否重新加载了规则bash
# ufw sudo ufw reload # firewalld sudo firewall-cmd --reload - 检查是否有冲突的规则
- 查看规则顺序是否正确
连接被拒绝:
检查日志文件
bashsudo tail -f /var/log/syslog # Debian/Ubuntu sudo tail -f /var/log/messages # CentOS/RHEL检查连接状态
bashsudo netstat -tuln sudo ss -tuln验证防火墙规则是否正确应用
bashsudo iptables-save # 查看完整规则集 sudo firewall-cmd --list-all-zones # 查看所有区域配置
7.2 诊断工具
- ping:测试基本网络连通性
- traceroute/mtr:跟踪数据包路径
- telnet/netcat:测试端口连通性bash
telnet <host> <port> nc -zv <host> <port> - tcpdump:捕获和分析网络流量bash
sudo tcpdump -i any port 22 - iptables-save/iptables-restore:保存和恢复完整规则集
8. 总结
Linux 提供了多种强大的防火墙工具,包括传统的 iptables、简化的 ufw、动态的 firewalld 和新一代的 nftables。每种工具都有其适用场景:
- iptables:功能全面,适合需要精确控制的场景,但配置相对复杂
- ufw:简单易用,适合基本防火墙需求,在 Ubuntu/Debian 系统上广泛使用
- firewalld:支持动态更新和网络区域,适合需要频繁修改规则的环境,在 RHEL/CentOS 7+ 上默认使用
- nftables:新一代框架,性能更好,语法更灵活,是未来的发展方向
选择合适的防火墙工具需要考虑系统环境、管理复杂度、性能需求和个人偏好。无论选择哪种工具,实施默认拒绝策略、定期审查规则、记录日志并进行监控,都是确保防火墙有效保护系统安全的关键措施。
随着网络安全威胁的不断演变,保持防火墙规则的更新和完善,是 Linux 系统安全管理中的重要一环。