iptables

简介

iptables 是 linux 上的一个很强大的工具,通过控制 Linux 内核中的 netfilter 模块,来管理网络数据包的处理和转发。

iptables 有几个基本的概念:

  • 表(table): 每个表都代表了不同的数据处理流程,比如 filter 表通常用来做数据包的过滤,nat 表通常用来对连接做地址转换。

  • 链(chain):链是存在表中的,每个表通过不同链的集合来完成不同的作用。比如 filter 表中有 INPUT,OUTPUT, FORWARD 链。

  • 规则(rule):规则是存在每个链中的,也是 iptables 操作的最小单位。通过对规则的增删改查,我们可以实现很多强大的功能。

表、链、规则

iptables 包含:

  • 四个表:

    • filter:数据包过滤的表,包含的链有:INPUT,FORWARD,OUTPUT

    • nat:网络地址转换的表,包含的链有:PREROUTING,OUTPUT,POSTROUTING(centos7中还有INPUT,centos6中没有)

    • mangle:处理数据包的表,包含的链有:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

    • raw:处理异常的表,包含的链有:PREROUTING,OUTPUT

  • 五条链:

    • PREROUTING:路由前链,在处理路由规则前通过此链,通常用于目的地址转换(DNAT)。

    • INPUT:输入链。发往本机的数据包通过此链。

    • FORWARD:转发链。本机转发的数据包通过此链。

    • OUTPUT:输出链。从本机发出的数据包通过此链。

    • POSTROUTING:路由后链,完成路由规则后通过此链,通常用于源地址转换(SNAT)。

看一张整体的流程图:

每个规则中都会包含一个动作,来表示如果匹配到了,就会执行什么动作,通常用 -j ACTION 来设置。常见的动作有:

  • ACCEPT:接受

  • DROP:丢弃

  • REJECT: 拒绝,和 DROP 不同的是,REJECT 会返回响应。

  • LOG:LOG 会记录匹配的报文日志

  • SNAT:全称是 source network address translation。会修改报文的 src ip。

  • DNAT:全称是 destination network address translation。会修改报文的 dst ip。

  • MASQUERADE:和 SNAT 类型,只不过 SNAT 会将报文的 src ip 修改成设置好的值,而 MASQUERADE 会将报文的 src ip 设置成指定网卡上可用的值。

  • REDIRECT:在本机上进行端口映射。

增删改查

既然要用 iptables,第一步是先了解它的增删查。

# 这里的在向 filter 表中的 OUTPUT 链添加规则。
# -A 是向链尾添加规则,改成 -I 是向链首添加规则。
iptables -t filter -A OUTPUT -d 192.168.50.203 -j DROP

# 查 filter 表的 OUTPUT 链
iptables -t filter -nL OUTPUT

# 删除 filter 表中的 OUTPUT 链的第一条规则
iptables -t filter -D OUTPUT 1

# 删除 filter 表中的所有规则
iptables -t filter -F

实例

下面通过几个常见的例子来展示:

例子一:防火墙

这里我们配置一个只打开 22, 80 和 443 端口的防火墙,同时所有出去的流量都是正常的。因为是防火墙,我们很自然的想到用 filter 表。

# 先允许目标端口是 22 的请求,因为我现在是 ssh 连接的
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT

# 默认是 filter,所以可以不加 -t,修改 INPUT 表的默认 target 是 DROP
iptables -P INPUT DROP
# 允许所有出去的包
iptables -P OUTPUT ACCEPT
# 不允许转发包
iptables -P FORWARD DROP
# 允许从本机出去的流量建立连接
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

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

# 允许 80, 443
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -t filter -A INPUT -p tcp --dport 443 -j ACCEPT

# 允许本地的连接
iptables -A INPUT -i lo -p all -j ACCEPT

# 监听本地80端口,测试 80 是否连通
nc -l 80

# 另外的机器
telnet 192.168.50.200 80

# 只允许特定 IP 的 ssh 连接
iptables -A INPUT -p tcp -s 10.0.2.2,192.168.50.201 --dport 22 -j ACCEPT

# 删除第一条的规则
iptables -D INPUT 1

NAT

Last updated