Skip to content

设置 iptables 基础 Linux 防火墙

在这篇文章中

iptables 是 Linux 内核中用于过滤和管理网络流量的内置框架。它允许根据规则灵活控制传入、传出和转发连接。

备注

iptables 几乎预装在所有的 Linux 发行版中。
在较新的系统(RHEL 8+、Ubuntu 20.04+)中,默认可能是 nftablesnft 命令),但 iptables 通过 legacy 接口 iptables-legacy 保持兼容。
对于云服务器或 VPS —— ****配置** iptables 对安全至关重要

核心概念

三条链 (chains)

用途
INPUT 进入 服务器 的流量(SSH、HTTP 等)
OUTPUT 服务器 发出的流量(更新、API 请求)
FORWARD 经过服务器 的流量(仅在进行路由/NAT 时)

备注

小心处理 INPUT
未经授权阻止端口 22 可能会 导致你与服务器断开连接。应用规则前务必仔细检查。

工作原理

  1. 数据包进入相应的链 INPUTOUTPUTFORWARD
  2. 规则按 顺序 评估 —— 一旦找到匹配项,即执行指定的操作。
  3. 如果 未找到匹配项,则应用 默认策略 policy

操作 (targets)

操作 行为 建议
ACCEPT 允许数据包 用于受信任的服务(SSH、HTTP)
DROP 静默丢弃数据包(无回复) ****最佳安全选择**** —— 隐藏端口的存在
REJECT 拒绝并返回 ICMP 错误(例如 port-unreachable 如果需要反馈(例如用于调试)时使用

备注

安全规则
默认 —— 拒绝所有,然后仅允许所需的内容。

基本命令语法

iptables [options] CHAIN [criteria] -j ACTION

主要选项:

选项 用途
-A 将规则 追加到 链的 末尾
-I 在开头 插入规则(或在特定编号处:-I INPUT 1
-D 删除规则(按编号或复制该行)
-L 列出规则
-F 清除链中的所有规则
-P 设置 默认策略 ACCEPTDROP

常用条件:

选项 示例 描述
-p tcp/udp/icmp -p tcp 协议
--dport N --dport 22 目标端口
-s IP/MASK -s 192.168.1.5<br-s 203.0.113.0/24 源(IP 或子网)
-i interface -i eth0 传入接口
-m state --state NEW,ESTABLISHED -m state --state NEW 连接状态
-m connlimit --connlimit-above 5 连接限制

查看和故障排除

显示所有规则(可读格式):

sudo iptables -L -n -v --line-numbers
- -n —— 不解析名称(速度更快); - -v —— 详细输出; - --line-numbers —— 显示规则编号(删除时有用)。

查看默认策略:

sudo iptables -S | grep '^:'
# 或者:
sudo iptables -L | head -3

实用规则示例

1. 安全基础配置(推荐!)

# 1. 允许环回接口上的所有流量
sudo iptables -A INPUT -i lo -j ACCEPT


# 2. 允许已建立的连接(重要!)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


# 3. 允许 SSH(如果更改了端口,请替换 22!)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT


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


# 5. 默认丢弃其他所有流量
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT   # ← 通常允许出站

2. 访问限制

# 仅允许来自一个 IP 的 MySQL (3306) 访问
sudo iptables -A INPUT -s 203.0.113.15 -p tcp --dport 3306 -j ACCEPT


# 阻止来自可疑 IP 的所有流量
sudo iptables -A INPUT -s 198.51.100.77 -j DROP

3. 攻击防护

# 阻止畸形/无效数据包
sudo iptables -A INPUT -m state --state INVALID -j DROP


# 防止 SYN 洪水攻击
sudo iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
sudo iptables -A INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST RST -j DROP


# 限制 HTTP 连接(单个 IP 并发连接不超过 20 个)
sudo iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 32 -j DROP

4. 日志记录

# 记录尝试连接关闭端口的行为(每分钟前 5 次)
sudo iptables -A INPUT -p tcp -m multiport --dports 22,3389,5900 \
  -m limit --limit 5/min -j LOG --log-prefix "PORT-SCAN: " --log-level 4


# 然后丢弃
sudo iptables -A INPUT -p tcp -m multiport --dports 22,3389,5900 -j DROP

重启后保存规则

iptables 规则 不会自动保存 —— 它们仅驻留在内核内存中。

对于 RHEL / CentOS 7 及更早版本:

sudo /sbin/service iptables save
# 或者
sudo iptables-save > /etc/sysconfig/iptables

对于 Debian / Ubuntu:

安装持久化包:

sudo apt update && sudo apt install iptables-persistent
安装期间系统会提示保存当前规则 —— 选择 "Yes"

稍后更新已保存的规则:

sudo netfilter-persistent save
# 或者直接:
sudo iptables-save > /etc/iptables/rules.v4

备注

重启前,请验证规则:

sudo iptables-restore -t < /etc/iptables/rules.v4
-t 标志仅用于语法检查,不会应用规则。

删除规则

按编号删除(参见 --line-numbers):

sudo iptables -D INPUT 3   # 删除 INPUT 链中的第 3 条规则

按精确匹配删除:

sudo iptables -D INPUT -s 198.51.100.77 -j DROP

清除链:

sudo iptables -F INPUT      # 仅 INPUT
sudo iptables -F            # 所有链

重置默认策略:

sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT

信息

  1. 在本地 或通过控制台(而非 SSH!)测试规则,尤其是在更改 INPUT 时。
  2. 使用 screentmux,以免出错时丢失会话。
  3. 考虑迁移到更现代的工具:

    • ufw —— iptables 的简化接口(Ubuntu/Debian);
    • firewalld —— RHEL/CentOS 的动态防火墙;
    • nftables —— Linux 内核的未来(更高效且语法更简洁)。
question_mark
Is there anything I can help you with?
question_mark
AI Assistant ×