iptables用法

一、底层基础:Netfilter & iptables

1、Netfilter:Linux 内核内置网络防火墙框架,提供 5 个数据包拦截钩子点(五链),真正处理数据包

2、iptables:用户态命令行工具,用来给 Netfilter 配置规则,只是配置入口

3、三层结构:表 (table) → 链 (chain) → 规则 (rule)

  • 表:按功能分类规则集合
  • 链:数据包必经的拦截点(钩子)
  • 规则:匹配条件 + 执行动作,从上到下逐条匹配,匹配即终止;无匹配走链默认策略

iptables 里面有两个概念容易混淆:

  • 表(table):负责不同类型的数据包处理功能
  • 链(chain):数据包经过的处理节点

iptables 五张表:

表(table)作用常用场景
filter过滤数据包(允许/拒绝)防火墙规则
nat地址转换SNAT、DNAT、端口转发
mangle修改数据包修改标记、TTL、QoS
raw优先级最高,绕过连接跟踪NOTRACK
securitySELinux 安全策略SELinux

iptables 五条内置链:

方向作用
PREROUTING进入本机之前路由判断前
INPUT进入本机本机接收
FORWARD经过本机转发路由转发
OUTPUT本机产生本机发出
POSTROUTING离开本机之前路由之后

严格来说: 五条链属于不同表的组合,不是每张表都有五条

二、各表有哪些链?

1、filter 表(默认表),负责防火墙

filter
 ├── INPUT
 ├── FORWARD
 └── OUTPUT

例如: 放行SSH端口

iptables -A INPUT -p tcp --dport 22 -j ACCEPT

2、nat 表(Network Address Translation,网络地址转换表)

nat
 ├── PREROUTING
 ├── INPUT
 ├── OUTPUT
 └── POSTROUTING
  • PREROUTING:数据包进入路由决策之前处理,常用于 DNAT(目的地址转换)、端口映射
  • INPUT:进入本机进程的数据包(nat 表中用得很少,某些特殊场景才会用到)
  • OUTPUT:本机发出的数据包,在路由前处理,常用于对本机访问外网的 DNAT
  • POSTROUTING:数据包离开本机前、路由决策之后处理,最常用,用于 SNAT(源地址转换)、MASQUERADE(如上网 NAT)

例如:DNAT(目标地址转换),外部IP:8080 => 内网:80

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
  • -i eth0:指定外网入网卡
  • --dport 9090:对外暴露的公网端口
  • –to-destination 内网IP:内网端口

SNAT(源地址转换),内网访问公网:

iptables -t nat -A POSTROUTING -d 192.168.1.100 -p tcp --dport 80 -j SNAT --to-source 203.0.113.100

3、mangle表:专门用来修改 / 标记数据包本身属性的表,可以改写数据包头部信息、打连接标记,用于路由、QoS、流量控制、策略路由、优化网络参数等场景,不是做常规防火墙放行 / 阻断,也不是做地址 NAT 转换

mangle
 ├── PREROUTING
 ├── INPUT
 ├── FORWARD
 ├── OUTPUT
 └── POSTROUTING

修改数据包 TTL(生存时间),--ttl-set / --ttl-dec / --ttl-inc,统一 TTL 值、防止运营商检测 / 限制共享上网

iptables -t mangle -A POSTROUTING -o eth0 -j TTL --ttl-set 64

修改数据包 DSCP 值,区分语音 / 视频 / 普通数据,配合 tc 流量限速、带宽优先级

iptables -t mangle -A PREROUTING -p udp --dport 5060 -j DSCP --set-dscp 46

MARK 打数据包标记,使用-j MARK --set-mark 数值 ,标记本身不会改数据包原始报文,仅在内核里做内存标记

iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 10

修改 TCP 选项、MSS(最大分段大小)

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

日常需求:开放端口、防扫描、基础防护、简单端口映射→ 只用 filter + nat 表就足够,如果是网关 / 软路由 / 多线服务器 / 做精细流量管控:高频使用

4、raw表

raw
 ├── PREROUTING
 └── OUTPUT
  • 普通单网卡 Web / 数据库服务器:默认空 raw 表即可,日常基本不用
  • 网关、软路由、高并发流量服务器:很常用,用来做性能优化

5、security表,平时很少直接操作

security
 ├── INPUT
 ├── FORWARD
 └── OUTPUT

三、数据包经过顺序,假设外部访问你的Linux服务器

            Linux网卡
             |
            ↓
       PREROUTING
             |
        路由判断
          /    \
         /      \
     本机       转发
      |          |
     ↓         ↓
   INPUT      FORWARD
      |
   应用程序
      |
   OUTPUT
      |
 POSTROUTING
      |
     ↓
     网卡

说明:假如服务器公网个IP为: 34.100.5.68,外部程序访问34.100.5.68:8080,流程如下:

  • 外部程序请求到达网卡,比如eth0,此时数据包还没到iptables规则
  • 到达PREROUTING:执行DNAT,将34.100.5.68:8080 变成内网:80,通过iptables -t nat 实现
  • 到达路由判断:判断目标数据包是不是给本机,如果是给本机,直接走INPUT
  • 判断目标IP地址不是本机,走FORWARD链进行转发
  • OUTPUT:用于本机服务器请求外面的数据,不经过PREROUTING,但是出去之前要经过POSTROUTING
  • POSTROUTING: 常用于SNAT,比如我的内网机器要访问互联网的8.8.8.8,出去之前POSTROUTING把内网IP变为公网IP,然后通过这个公网IP去外面请求,规则可以配置动态地址伪装静态源地址转换,如下

MASQUERADE(动态地址伪装):

iptables -t nat -A POSTROUTING \
  -s 192.168.1.0/24 \
  -o eth0 \
  -j MASQUERADE
  • 每次发包都 查当前出口网卡的 IP
  • 不关心 IP 是多少,自动用“现在的那个”
  • 适合:IP 可能变、懒得维护规则

特点:配置简单、拔线重连 / IP 变了也不用改规则内核要多做一次地址查找(性能略低,但一般感知不到)

SNAT(静态源地址转换):

iptables -t nat -A POSTROUTING \
  -s 192.168.1.0/24 \
  -o eth0 \
  -j SNAT --to-source  34.100.5.68
  • 明确写死转换后的源 IP
  • 内核直接替换,不走动态查询

特点:性能最好行为确定,适合生产环境、大流量、公网 IP 一变,规则就失效,必须手动改

总结:

  • 出口 IP 会变(DHCP / PPPoE / 云主机弹性 IP)→ 用 MASQUERADE
  • 出口 IP 固定(IDC 静态公网 IP)→ 用 SNAT

常用iptables规则

1、查看默认filter表

iptables -t filter -L -n
iptables -L -n -v --line-number   #增强版

2、查看所有表:

iptables -t filter -L -n    #filter表
iptables -t nat -L -n       #nat表
iptables -t mangle -L -n    #mangle表
iptables -t raw -L -n       #raw表

3、查看规则编号,非常常用,删除的时候需要编号,下方删除规则里有删除用法

iptables -L INPUT -n --line-number

4、查看规则统计,看命中次数,流量大小,判断规则是否生效

iptables -L -v -n

例如:

pkts bytes
1000 2M

5、链默认策略

iptables -S

6、设置默认策略

iptables -P INPUT ACCEPT     #允许
iptables -P INPUT DROP       #拒绝

生产环境常见策略:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

7、清空规则

iptables -F                 #清空filter链
iptables -F INPUT           #清空指定链
iptables -X                 #删除自定义链
iptables -t nat -F          #清空nat

清空所有规则:

iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

8、开放端口(最常用)

iptables -A INPUT -p tcp --dport 22 -j ACCEPT        #开放22端口
iptables -A INPUT -p tcp -dport 80 -j ACCEPT         #开放http
iptables -A INPUT -p tcp --dport 443 -j ACCEPT       #开放https
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT #开放多个端口

9、限制来源IP

只允许192.168.51.100执行SSH连接到本机

iptables -A INPUT -s 192.168.51.100 -p tcp --dport 22 -j ACCEPT
iptables -P INPUT DROP

禁止某IP

iptables -A INPUT -s 1.2.3.4 -j DROP

禁止网段

iptables -A INPUT -s 10.0.0.0/8 -j DROP

10、允许已建立连接(生产必备)

已经建立的TCP连接继续允许,比如SSH登录后,不会因为后面的DROP被断开

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

11、允许本机localhost访问

iptables -A INPUT -i lo -j ACCEPT

12、Ping控制

iptables -A INPUT -p icmp -j ACCEPT        #允许ping
iptables -A INPUT -p icmp -j DROP          #禁止ping

13、日志记录

iptables -A INPUT -j LOG --log-prefix "iptables-drop:"     #记录丢弃包
dmesg | grep iptables 或 journalctl -k                     #查看日志

14、NAT常用

SNAT:内网访问公网

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE   #动态地址转换
或
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 公网IP  #静态源地址转换

DNAT:端口转发,公网:8080 ==> 内网:80

iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80

本机端口转发,本机:8080 ==> 本机:80

iptables -t nat -A OUTPUT -p tcp --dport 8080 -j REDIRECT --to-port 80

15、限制连接数量

限制SSH数量为5,最多只有5个连接

iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 5 -j DROP

16、防SYN Flood

iptables -A INPUT -p tcp --syn -m limit --limit 10/s -j ACCEPT

17、删除规则, 先查看

iptables -L INPUT -n --line-number    #可以获取到编号

例如:

1 ACCEPT tcp dpt:22
2 DROP tcp dpt:80

删除:

iptables -D INPUT 2

18、保存规则,ubuntu系统为例子

iptables-save > /etc/iptables/rules.v4        #保存
iptables-restore < /etc/iptables/rules.v4     #恢复

标签