iptables 在哪一层
应用前端:ufw / firewalld(高层封装)
↓ 生成规则
iptables(用户态工具)
↓ 操作
netfilter(内核里的钩子)
新 Linux 内核也支持 nftables(iptables 接班人)—— 但 iptables 命令仍然广泛使用,多数发行版默认兼容。
概念:表 / 链 / 规则
表 (table):filter / nat / mangle / raw
↓ 内含多个
链 (chain):INPUT / OUTPUT / FORWARD / PREROUTING / POSTROUTING
↓ 内含多条
规则 (rule):匹配条件 + 动作
最常用:filter 表(包过滤),关心三条链:
INPUT— 入站到本机OUTPUT— 本机出站FORWARD— 经本机转发(路由器场景)
看现有规则
sudo iptables -L -n -v
sudo iptables -L INPUT -n -v --line-numbers
-n 不解析名字(更快);-v 显示包数 / 字节数。
基础规则
# 允许已建立的连接(保留正在用的)
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 允许回环(本机自己通信)
sudo iptables -A INPUT -i lo -j ACCEPT
# 允许 SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 HTTP/HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 限制 SSH 暴破(每 IP 每分钟 4 次新连接)
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --set --name SSH
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
# 默认丢弃入站
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
# 出站不限
sudo iptables -P OUTPUT ACCEPT
⚠ 改 INPUT 默认策略前先确认 SSH 已允许——否则你下一秒就 SSH 失联。强烈建议在 KVM / VNC 能进的机器上练。
常用动作
| 动作 | 含义 |
|---|---|
ACCEPT |
放行 |
DROP |
默默丢(对方等超时) |
REJECT |
主动拒绝(返回 RST 或 ICMP) |
LOG |
记日志(之后规则继续) |
RETURN |
跳出当前链 |
<chain> |
跳到自定义链 |
DROP vs REJECT:
- DROP:对外看像"机器不在",扫描者不知道有没机器
- REJECT:明确告诉"被拒"
服务器一般 DROP;交互式调试可以 REJECT。
看规则匹配的包数
sudo iptables -L INPUT -n -v --line-numbers
# Chain INPUT (policy DROP 0 packets, 0 bytes)
# num pkts bytes target prot opt in out source destination
# 1 1234 5678 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
pkts / bytes 显示规则的命中次数——0 的规则可能是没用上 / 顺序不对。
删除规则
# 按行号
sudo iptables -D INPUT 3
# 完整命令(必须和加规则时完全一致)
sudo iptables -D INPUT -p tcp --dport 22 -j ACCEPT
持久化
iptables 规则重启就丢——必须持久化。
# Debian/Ubuntu
sudo apt install iptables-persistent
sudo netfilter-persistent save
# RHEL/CentOS
sudo systemctl enable iptables
sudo service iptables save
或手动:
sudo iptables-save > /etc/iptables/rules.v4
# 开机时
sudo iptables-restore < /etc/iptables/rules.v4
NAT 配置(路由场景)
让内网机器经本机出公网:
# 1. 开启内核转发
sudo sysctl -w net.ipv4.ip_forward=1
# 永久:写进 /etc/sysctl.conf
# 2. NAT 出方向
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# 3. 允许 FORWARD
sudo iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
端口转发
把入站 8080 转到 192.168.1.50:80:
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to 192.168.1.50:80
sudo iptables -A FORWARD -p tcp -d 192.168.1.50 --dport 80 -j ACCEPT
一份生产级模板
#!/bin/bash
set -e
# 清空
iptables -F
iptables -X
# 默认
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 已建立
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 回环
iptables -A INPUT -i lo -j ACCEPT
# SSH(带防暴破)
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Web
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# ICMP(ping)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/second -j ACCEPT
# 拒绝其他都 LOG 再 DROP
iptables -A INPUT -j LOG --log-prefix "iptables-dropped: "
iptables -A INPUT -j DROP
# 保存
iptables-save > /etc/iptables/rules.v4
下一篇:SELinux 基础。