跳转至

iptables 防火墙

iptables 是 Linux 最经典的防火墙工具,用来控制网络数据包的进出。白话说就是"给服务器装一道门,决定谁能进、谁能出、谁被挡在外面"。

核心知识点

概念说明
表(table)按功能分组的规则集合:filter(过滤)、nat(地址转换)、mangle(修改包)
链(chain)数据包经过的检查点:INPUT(进来)、OUTPUT(出去)、FORWARD(转发)
规则(rule)具体的匹配条件 + 动作(接受/拒绝/丢弃)
ACCEPT允许数据包通过
DROP丢弃数据包(不回应,对方不知道被拒绝了)
REJECT拒绝数据包(回应"不行",对方知道被拒绝了)
默认策略不匹配任何规则时的默认处理(建议 DROP)
数据包流向:
外部 → INPUT 链 → 本机应用(进来的流量)
本机应用 → OUTPUT 链 → 外部(出去的流量)
外部A → FORWARD 链 → 外部B(转发流量,路由器场景)

安装配置

# iptables 是 Linux 内核自带的,通常已预装
which iptables  # 确认命令存在

# Ubuntu/Debian 安装持久化工具
sudo apt install iptables-persistent  # 让规则重启后不丢失

# CentOS 7+ 使用 firewalld,如果想用 iptables:
sudo systemctl stop firewalld    # 停止 firewalld
sudo systemctl disable firewalld # 禁用 firewalld
sudo yum install iptables-services  # 安装 iptables 服务
sudo systemctl enable iptables   # 启用 iptables
sudo systemctl start iptables    # 启动 iptables

基本使用

查看当前规则

# 查看所有规则(最常用)
sudo iptables -L -n -v  # -L 列出 -n 不解析域名 -v 详细模式

# 查看规则并显示行号(方便删除)
sudo iptables -L --line-numbers  # 每条规则前面加编号

# 查看 NAT 表的规则
sudo iptables -t nat -L -n -v  # -t nat 指定 NAT 表

添加规则

# 允许 SSH 连接(端口 22)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# -A INPUT   追加规则到 INPUT 链
# -p tcp     协议为 TCP
# --dport 22 目标端口 22
# -j ACCEPT  动作:允许通过

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

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

# 允许已建立连接的回包(重要!不加这条很多东西会断)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 已建立连接和相关连接的包都允许

# 允许本地回环(localhost)
sudo iptables -A INPUT -i lo -j ACCEPT  # -i lo 指定回环网卡

# 拒绝所有其他入站流量(放在最后)
sudo iptables -A INPUT -j DROP  # 不匹配前面规则的全部丢弃

删除规则

# 按行号删除
sudo iptables -L --line-numbers  # 先看行号
sudo iptables -D INPUT 3  # 删除 INPUT 链的第 3 条规则

# 按规则内容删除
sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT  # 删除允许 80 端口的规则

# 清空所有规则(危险!确保有其他方式连接服务器)
sudo iptables -F  # 清空所有链的规则

高级用法

限制 IP 访问

# 允许指定 IP 访问
sudo iptables -A INPUT -s 192.168.1.100 -j ACCEPT  # 只允许这个 IP

# 拒绝指定 IP
sudo iptables -A INPUT -s 10.0.0.50 -j DROP  # 丢弃这个 IP 的所有包

# 允许指定网段
sudo iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT  # 允许整个子网

# 只允许指定 IP 访问 SSH
sudo iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
# 只有 192.168.1.x 网段能 SSH

端口转发(NAT)

# 开启内核转发
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward  # 临时开启
# 永久开启:编辑 /etc/sysctl.conf 加入 net.ipv4.ip_forward=1

# 端口转发:外部访问 8080 转到内部 80
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80
# 访问本机 8080 端口时,自动转到 80 端口

# DNAT:转发到另一台机器
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.10:80
# 外部访问本机 80 端口,转发到 192.168.1.10 的 80 端口

# SNAT:内网机器通过本机上网
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
# 192.168.1.x 网段通过 eth0 网卡上网(动态 IP 用 MASQUERADE)

防暴力破解(限速)

# 限制 SSH 连接频率(防止暴力破解)
sudo iptables -A INPUT -p tcp --dport 22 -m recent --set --name ssh_brute
sudo iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --name ssh_brute -j DROP
# 60 秒内超过 4 次连接尝试就封掉

# 使用 limit 模块限速
sudo iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
# 每分钟最多 25 个新连接,突发最多 100 个

保存和恢复规则

# Ubuntu/Debian:保存规则
sudo iptables-save > /etc/iptables/rules.v4  # 保存到文件
sudo ip6tables-save > /etc/iptables/rules.v6  # IPv6 规则

# Ubuntu/Debian:恢复规则
sudo iptables-restore < /etc/iptables/rules.v4  # 从文件恢复

# CentOS/RHEL:保存规则
sudo service iptables save  # 保存到 /etc/sysconfig/iptables

# 或者手动
sudo iptables-save > /etc/sysconfig/iptables  # 保存
sudo iptables-restore < /etc/sysconfig/iptables  # 恢复

实用服务器规则模板

#!/bin/bash
# 服务器基础防火墙脚本

# 清空所有规则
iptables -F  # 清空 filter 表
iptables -t nat -F  # 清空 nat 表
iptables -X  # 删除自定义链

# 设置默认策略:拒绝所有入站,允许所有出站
iptables -P INPUT DROP    # 默认拒绝入站
iptables -P FORWARD DROP  # 默认拒绝转发
iptables -P OUTPUT ACCEPT # 默认允许出站

# 允许回环
iptables -A INPUT -i lo -j ACCEPT  # 本地通信必须放行

# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 允许 SSH(可以限制来源 IP)
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

# 允许 ping(可选)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# 记录被拒绝的包(方便排查问题)
iptables -A INPUT -j LOG --log-prefix "IPTables-DROP: " --log-level 4

echo "防火墙规则已设置完成"

常见报错

问题原因解决
SSH 连不上了设置了 DROP 默认策略但没放行 22 端口通过控制台登录,加规则 iptables -I INPUT -p tcp --dport 22 -j ACCEPT
规则重启后消失没有保存规则安装 iptables-persistent 或手动 iptables-save
服务器上不了网OUTPUT 链被限制了iptables -P OUTPUT ACCEPT
规则顺序导致不生效iptables 从上到下匹配,先匹配的优先-I INPUT 1 插入到最前面
iptables: No chain/target/match内核模块没加载modprobe ip_tables

速查表

# === 查看规则 ===
sudo iptables -L -n -v                # 查看所有规则
sudo iptables -L --line-numbers       # 带行号
sudo iptables -t nat -L -n            # 查看 NAT 规则

# === 添加规则 ===
iptables -A INPUT -p tcp --dport 端口 -j ACCEPT   # 允许端口
iptables -A INPUT -s IP地址 -j DROP                # 封禁 IP
iptables -I INPUT 1 -p tcp --dport 端口 -j ACCEPT  # 插入到最前面

# === 删除规则 ===
iptables -D INPUT 行号              # 按行号删除
iptables -D INPUT -p tcp --dport 端口 -j ACCEPT  # 按内容删除
iptables -F                          # 清空所有规则

# === 默认策略 ===
iptables -P INPUT DROP     # 默认拒绝入站
iptables -P OUTPUT ACCEPT  # 默认允许出站
iptables -P FORWARD DROP   # 默认拒绝转发

# === 保存恢复 ===
iptables-save > 文件       # 保存规则
iptables-restore < 文件    # 恢复规则

# === 常用动作 ===
-j ACCEPT    # 允许
-j DROP      # 丢弃(对方不知道)
-j REJECT    # 拒绝(对方知道)
-j LOG       # 记录日志