跳转到内容

Linux 防火墙端口开放完全指南 | iptables、firewalld 与 UFW 配置教程

Linux Firewall Port Configuration

为什么需要配置防火墙?

防火墙是 Linux 系统的第一道安全防线,它可以:

  • 🛡️ 阻止未授权访问:只允许必要的端口对外开放
  • 🔒 保护敏感服务:数据库、管理面板等内网服务不暴露公网
  • 📊 监控网络流量:记录和分析进出系统的连接
  • ⚠️ 防止端口扫描:减少被攻击面

常见需要开放的端口:

  • 22 - SSH 远程登录
  • 80 - HTTP Web 服务
  • 443 - HTTPS 加密 Web 服务
  • 3306 - MySQL 数据库(通常仅内网)
  • 6379 - Redis 缓存(通常仅内网)
  • 8080 - 应用服务器/代理

Linux 三大防火墙工具对比

特性iptablesfirewalldUFW
复杂度高(底层)低(最简单)
灵活性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
适用发行版所有 LinuxRHEL/CentOS 7+Ubuntu/Debian
学习曲线陡峭中等平缓
动态更新需重载规则支持热更新需重载
推荐场景高级用户、复杂规则CentOS/RHEL 服务器Ubuntu/Debian 新手

推荐选择:

  • 🟢 Ubuntu/Debian 用户: 使用 UFW(简单直观)
  • 🔵 CentOS/RHEL 用户: 使用 firewalld(系统集成)
  • 🔴 高级用户: 直接使用 iptables(最灵活)

方法一:UFW 防火墙(Ubuntu/Debian 推荐)

1. 安装与启用

bash
# 安装 UFW
sudo apt install ufw -y

# 查看状态
sudo ufw status

# 启用 UFW(会提示可能中断 SSH,输入 y 确认)
sudo ufw enable

# 开机自启
sudo systemctl enable ufw

2. 基本操作

设置默认策略:

bash
# 默认拒绝所有入站连接
sudo ufw default deny incoming

# 默认允许所有出站连接
sudo ufw default allow outgoing

开放端口:

bash
# 开放单个端口(TCP)
sudo ufw allow 80/tcp

# 开放单个端口(UDP)
sudo ufw allow 53/udp

# 开放端口范围
sudo ufw allow 6000:6007/tcp

# 开放特定协议的端口
sudo ufw allow 22/tcp
sudo ufw allow 443/tcp

# 同时开放 TCP 和 UDP
sudo ufw allow 53

开放特定 IP 访问:

bash
# 允许特定 IP 访问所有端口
sudo ufw allow from 192.168.1.100

# 允许特定 IP 访问特定端口
sudo ufw allow from 192.168.1.100 to any port 22

# 允许整个网段
sudo ufw allow from 192.168.1.0/24 to any port 3306

删除规则:

bash
# 查看规则编号
sudo ufw status numbered

# 按编号删除规则
sudo ufw delete 3

# 按规则内容删除
sudo ufw delete allow 80/tcp

禁用/重置:

bash
# 临时禁用防火墙
sudo ufw disable

# 重新启用
sudo ufw enable

# 重置所有规则(恢复默认)
sudo ufw reset

3. 常用服务配置示例

Web 服务器(Nginx/Apache):

bash
sudo ufw allow 'Nginx Full'    # 同时开放 80 和 443
# 或
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

SSH 安全加固:

bash
# 修改 SSH 端口后(如 2222)
sudo ufw allow 2222/tcp

# 限制 SSH 仅允许特定 IP
sudo ufw allow from 203.0.113.50 to any port 22

# 删除默认的 SSH 规则
sudo ufw delete allow 22/tcp

数据库(仅内网访问):

bash
# MySQL
sudo ufw allow from 192.168.1.0/24 to any port 3306

# PostgreSQL
sudo ufw allow from 192.168.1.0/24 to any port 5432

# Redis
sudo ufw allow from 192.168.1.0/24 to any port 6379

Docker 容器:

bash
# Docker 会自动管理 iptables,但可以与 UFW 配合
# 确保 UFW 在 Docker 之后启动
sudo ufw reload

# 或者在 /etc/ufw/before.rules 中添加 Docker 规则

4. 查看与管理

bash
# 查看详细状态
sudo ufw status verbose

# 查看带编号的规则列表
sudo ufw status numbered

# 查看日志
sudo tail -f /var/log/ufw.log

# 启用日志记录
sudo ufw logging on
sudo ufw logging medium  # low, medium, high, full

方法二:firewalld 防火墙(CentOS/RHEL 推荐)

1. 安装与启用

bash
# CentOS 7+ 默认已安装
# 如果没有,安装 firewalld
sudo yum install firewalld -y

# 启动服务
sudo systemctl start firewalld

# 开机自启
sudo systemctl enable firewalld

# 查看状态
sudo systemctl status firewalld

2. 基本概念

Zone(区域):

  • public - 公共网络(默认)
  • internal - 内部网络
  • dmz - DMZ 区域
  • drop - 丢弃所有连接
  • block - 拒绝所有连接

Service(服务): 预定义的服务集合,如 ssh, http, https, mysql 等。

3. 基本操作

查看当前配置:

bash
# 查看所有区域
sudo firewall-cmd --get-zones

# 查看默认区域
sudo firewall-cmd --get-default-zone

# 查看当前区域的规则
sudo firewall-cmd --list-all

# 查看所有区域的详细配置
sudo firewall-cmd --list-all-zones

开放端口:

bash
# 开放单个端口(永久生效)
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent

# 开放多个端口
sudo firewall-cmd --zone=public --add-port=80/tcp --add-port=443/tcp --permanent

# 开放端口范围
sudo firewall-cmd --zone=public --add-port=6000-6010/tcp --permanent

# 重新加载使配置生效
sudo firewall-cmd --reload

使用服务名称:

bash
# 添加预定义服务
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --zone=public --add-service=ssh --permanent

# 查看可用服务
sudo firewall-cmd --get-services

# 重新加载
sudo firewall-cmd --reload

限制来源 IP:

bash
# 允许特定 IP 访问 SSH
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.50" service name="ssh" accept'

# 允许网段访问 MySQL
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept'

# 重新加载
sudo firewall-cmd --reload

删除规则:

bash
# 删除端口
sudo firewall-cmd --zone=public --remove-port=80/tcp --permanent

# 删除服务
sudo firewall-cmd --zone=public --remove-service=http --permanent

# 删除富规则
sudo firewall-cmd --permanent --zone=public --remove-rich-rule='rule family="ipv4" source address="203.0.113.50" service name="ssh" accept'

# 重新加载
sudo firewall-cmd --reload

临时规则(重启后失效):

bash
# 不加 --permanent 参数即为临时规则
sudo firewall-cmd --zone=public --add-port=8080/tcp

# 查看临时规则
sudo firewall-cmd --zone=public --list-ports

4. 高级配置

端口转发:

bash
# 将 80 端口转发到 8080
sudo firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toport=8080

# 转发到其他 IP
sudo firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.100:toport=80

sudo firewall-cmd --reload

伪装(NAT):

bash
# 启用 IP 伪装
sudo firewall-cmd --permanent --zone=public --add-masquerade

# 端口转发到外部服务器
sudo firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toaddr=203.0.113.100:toport=80

sudo firewall-cmd --reload

自定义服务:

bash
# 创建自定义服务配置文件
sudo nano /etc/firewalld/services/myapp.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>My Application</short>
  <description>Custom application service</description>
  <port protocol="tcp" port="8080"/>
  <port protocol="tcp" port="8443"/>
</service>
bash
# 重新加载
sudo firewall-cmd --reload

# 使用自定义服务
sudo firewall-cmd --permanent --add-service=myapp
sudo firewall-cmd --reload

方法三:iptables 防火墙(通用底层工具)

1. 基本概念

表(Tables):

  • filter - 过滤数据包(默认表)
  • nat - 网络地址转换
  • mangle - 修改数据包头部
  • raw - 连接跟踪之前处理

链(Chains):

  • INPUT - 进入本机的数据包
  • OUTPUT - 从本机发出的数据包
  • FORWARD - 经过本机转发的数据包
  • PREROUTING - 路由前处理
  • POSTROUTING - 路由后处理

2. 基本操作

查看规则:

bash
# 查看 filter 表规则
sudo iptables -L -n -v

# 查看 nat 表规则
sudo iptables -t nat -L -n -v

# 显示行号
sudo iptables -L -n --line-numbers

设置默认策略:

bash
# 默认拒绝所有入站
sudo iptables -P INPUT DROP

# 默认允许出站
sudo iptables -P OUTPUT ACCEPT

# 默认拒绝转发
sudo iptables -P FORWARD DROP

⚠️ 警告: 执行上述命令前,务必先允许 SSH 端口,否则会立即断开连接!

允许已建立的连接:

bash
# 允许已建立和相关连接(重要!)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

开放端口:

bash
# 允许 SSH(必须先执行!)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 允许 HTTP
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# 允许 HTTPS
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# 允许 ICMP(ping)
sudo iptables -A INPUT -p icmp -j ACCEPT

# 允许本地回环
sudo iptables -A INPUT -i lo -j ACCEPT

限制来源 IP:

bash
# 允许特定 IP 访问 SSH
sudo iptables -A INPUT -p tcp -s 203.0.113.50 --dport 22 -j ACCEPT

# 拒绝特定 IP
sudo iptables -A INPUT -s 192.168.1.100 -j DROP

# 允许网段访问 MySQL
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 3306 -j ACCEPT

删除规则:

bash
# 查看行号
sudo iptables -L INPUT -n --line-numbers

# 按行号删除
sudo iptables -D INPUT 3

# 按规则内容删除
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT

清空规则:

bash
# 清空所有规则
sudo iptables -F

# 清空特定链
sudo iptables -F INPUT

# 重置默认策略
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

3. NAT 与端口转发

SNAT(源地址转换):

bash
# 启用 IP 转发
echo 1 > /proc/sys/net/ipv4/ip_forward

# 配置 SNAT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

DNAT(目标地址转换/端口转发):

bash
# 将公网 80 端口转发到内网 192.168.1.100:8080
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:8080

# 允许转发
sudo iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 8080 -j ACCEPT

4. 保存与恢复规则

Debian/Ubuntu:

bash
# 安装持久化工具
sudo apt install iptables-persistent -y

# 保存当前规则
sudo netfilter-persistent save

# 规则保存在:
# /etc/iptables/rules.v4
# /etc/iptables/rules.v6

CentOS/RHEL:

bash
# 保存规则
sudo service iptables save

# 或使用
sudo iptables-save > /etc/sysconfig/iptables

# 恢复规则
sudo iptables-restore < /etc/sysconfig/iptables

手动保存/恢复:

bash
# 保存到文件
sudo iptables-save > /root/iptables-backup.txt

# 从文件恢复
sudo iptables-restore < /root/iptables-backup.txt

常用端口参考表

Web 服务

端口协议服务说明
80TCPHTTPWeb 服务
443TCPHTTPS加密 Web 服务
8080TCPHTTP-Alt备用 Web/代理
8443TCPHTTPS-Alt备用加密 Web

数据库

端口协议服务建议
3306TCPMySQL/MariaDB仅内网
5432TCPPostgreSQL仅内网
6379TCPRedis仅内网+密码
27017TCPMongoDB仅内网+认证

邮件服务

端口协议服务
25TCPSMTP
110TCPPOP3
143TCPIMAP
465TCPSMTPS
993TCPIMAPS
995TCPPOP3S

其他常用

端口协议服务
22TCPSSH
21TCPFTP
53TCP/UDPDNS
123UDPNTP
3389TCPRDP
5900TCPVNC
8888TCP1Panel/BT面板

安全最佳实践

1. 最小权限原则

只开放必要的端口:

bash
# 错误做法:开放所有端口
sudo ufw allow all

# 正确做法:按需开放
sudo ufw allow 22/tcp   # SSH
sudo ufw allow 80/tcp   # HTTP
sudo ufw allow 443/tcp  # HTTPS

2. 限制来源 IP

敏感服务仅允许信任 IP:

bash
# 数据库仅允许应用服务器访问
sudo ufw allow from 192.168.1.10 to any port 3306

# SSH 仅允许管理 IP
sudo ufw allow from 203.0.113.50 to any port 22

3. 修改默认端口

避免使用知名端口:

bash
# SSH 改为 2222
sudo nano /etc/ssh/sshd_config
# Port 2222

# 防火墙同步修改
sudo ufw allow 2222/tcp
sudo ufw delete allow 22/tcp

4. 定期审计规则

bash
# 每周检查防火墙规则
sudo ufw status verbose

# 清理无用规则
sudo ufw status numbered
sudo ufw delete [编号]

# 查看被阻止的连接日志
sudo grep "UFW BLOCK" /var/log/syslog | tail -20

5. 备份规则

bash
# 定期备份防火墙规则
sudo cp /etc/ufw/user.rules /backup/ufw-rules-$(date +%Y%m%d).bak

# 或使用脚本自动化
#!/bin/bash
BACKUP_DIR="/backup/firewall"
mkdir -p $BACKUP_DIR
iptables-save > $BACKUP_DIR/iptables-$(date +%Y%m%d).txt
ufw status verbose > $BACKUP_DIR/ufw-status-$(date +%Y%m%d).txt

常见问题排查

Q1: 配置防火墙后无法 SSH 连接?

紧急救援:

bash
# 通过 VNC 控制台登录

# 检查 UFW 状态
sudo ufw status

# 临时禁用测试
sudo ufw disable

# 如果恢复连接,检查规则
sudo ufw status numbered

# 确保 SSH 端口已开放
sudo ufw allow 22/tcp
# 或自定义端口
sudo ufw allow 2222/tcp

# 重新启用
sudo ufw enable

预防措施:

  • 配置前先允许 SSH 端口
  • 使用 ufw allow 而不是直接修改默认策略
  • 保留 VNC 控制台访问权限

Q2: 端口已开放但仍无法访问?

排查步骤:

  1. 检查防火墙规则
bash
sudo ufw status
# 或
sudo iptables -L -n
  1. 检查服务是否监听
bash
# 查看端口监听状态
sudo ss -tuln | grep 80
# 或
sudo netstat -tuln | grep 80
  1. 检查云服务商安全组
  • AWS EC2 Security Group
  • 阿里云安全组
  • 腾讯云安全组
  • Oracle Cloud VCN 规则
  1. 测试本地访问
bash
# 在服务器上测试
curl http://localhost:80

# 从外部测试
telnet your_server_ip 80
  1. 检查 SELinux(CentOS/RHEL)
bash
# 查看 SELinux 状态
sestatus

# 临时禁用测试
sudo setenforce 0

# 如果解决问题,配置 SELinux 规则
sudo semanage port -a -t http_port_t -p tcp 8080

Q3: 如何查看被防火墙阻止的连接?

UFW 日志:

bash
# 启用日志
sudo ufw logging medium

# 查看日志
sudo tail -f /var/log/ufw.log

# 统计被阻止的 IP
grep "UFW BLOCK" /var/log/ufw.log | awk '{print $12}' | sort | uniq -c | sort -rn | head -10

iptables 日志:

bash
# 添加日志规则
sudo iptables -A INPUT -j LOG --log-prefix "IPTABLES_DROP: " --log-level 4

# 查看日志
sudo tail -f /var/log/syslog | grep "IPTABLES_DROP"

Q4: Docker 容器端口无法访问?

解决方案:

  1. 检查 Docker 是否正确配置 iptables
bash
# 查看 Docker 链
sudo iptables -L DOCKER -n -v
  1. 确保 UFW 在 Docker 之后启动
bash
# 重启 UFW
sudo ufw disable
sudo ufw enable
  1. 或在 UFW 配置中允许 Docker
bash
# 编辑 /etc/ufw/before.rules
# 在 *filter 之前添加:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
COMMIT
  1. 重新加载 UFW
bash
sudo ufw reload

Q5: 如何临时开放端口进行测试?

UFW 临时规则:

bash
# 开放端口
sudo ufw allow 8080/tcp

# 测试完成后删除
sudo ufw delete allow 8080/tcp

iptables 临时规则(重启失效):

bash
# 添加规则(不加保存)
sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT

# 测试后删除
sudo iptables -D INPUT -p tcp --dport 8080 -j ACCEPT

完整配置示例

Ubuntu Web 服务器防火墙配置

bash
#!/bin/bash
# ubuntu-firewall-setup.sh

# 重置 UFW
sudo ufw reset

# 设置默认策略
sudo ufw default deny incoming
sudo ufw default allow outgoing

# 允许 SSH(如果使用非标准端口,修改为对应端口)
sudo ufw allow 22/tcp

# 允许 Web 服务
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# 允许 ping
sudo ufw allow in proto icmp

# 启用 UFW
sudo ufw --force enable

# 验证配置
sudo ufw status verbose

echo "防火墙配置完成!"

CentOS Web 服务器防火墙配置

bash
#!/bin/bash
# centos-firewall-setup.sh

# 启动 firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld

# 设置默认区域
sudo firewall-cmd --set-default-zone=public

# 允许 SSH
sudo firewall-cmd --permanent --add-service=ssh

# 允许 Web 服务
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

# 允许 ping
sudo firewall-cmd --permanent --add-protocol=icmp

# 重新加载
sudo firewall-cmd --reload

# 验证配置
sudo firewall-cmd --list-all

echo "防火墙配置完成!"

相关教程推荐

通过合理配置防火墙,你可以有效控制服务器的网络访问权限,大幅提升系统安全性!🔒✨


免责声明

本文仅供技术交流和学习参考,请遵守当地法律法规,合理合法使用网络服务。