linux netfilter iptables 详解

linux 内核通过 netfilter 模块实现网络访问控制功能,在用户层我们可以通过iptables程序对netfilter进行控制管理。

iptables 命令规则

使用 iptables 命令创建一条规则,一般规则包含以下几个部门:
iptables 【表】【链】【匹配属性】【动作】
iptables -t filter【表】 -A INPUT【链】 -s 192.168.1.1【匹配属性】 -j DROP【动作】

表名包括:

raw:高级功能,如:网址过滤。
mangle:数据包修改(QOS),用于实现服务质量。
nat:地址转换,用于网关路由器。
filter:包过滤,用于防火墙规则。

规则链名包括:

INPUT链:处理输入数据包。
OUTPUT链:处理输出数据包。
PORWARD链:处理转发数据包。
PREROUTING链:用于目标地址转换(DNAT)。
POSTOUTING链:用于源地址转换(SNAT)。

匹配属性:
  • 源IP地址(如:-s 192.168.1.1
  • 目标IP地址(如:-d 10.0.0.0/8
  • 使用接口(如:-i eth0-o eth1
  • 排除参数(如:-s '!' 192.168.1.0/24 所有不来自192.168.1.0/24的ip)
  • 使用协议及端口(TCP、UDP、ICMP等)(如:-p tcp --dport 23-p udp --sport 53-p icmp
动作包括:

ACCEPT:接收数据包。
DROP:丢弃数据包。
REDIRECT:重定向、映射、透明代理。
SNAT:源地址转换。
DNAT:目标地址转换。
MASQUERADE:IP伪装(NAT),用于ADSL。
LOG:日志记录。

选项:
-t<表>:指定要操纵的表;

-A:向规则链中添加条目;
-D:从规则链中删除条目;
-I:向规则链中插入条目;
-R:替换规则链中的条目;
-L:显示规则链中已有的条目;
-F:清楚规则链中已有的条目;
-Z:清空规则链中的数据包计算器和字节计数器;
-N:创建新的用户自定义规则链;
-P:定义规则链中的默认目标;

-h:显示帮助信息;
-p:指定要匹配的数据包协议类型;
-s:指定要匹配的数据包源ip地址;

-j<目标>:指定要跳转的目标;
-i<网络接口>:指定数据包进入本机的网络接口;
-o<网络接口>:指定数据包要离开本机所使用的网络接口。

iptables命令选项输入顺序:

iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作

基本操作

列出现有iptables规则
iptables -L (iptables规则中默认表名是filter,iptables -L 相当于只是iptables -t filter -L,想列nat表中规则,则应iptables -t nat -L其他命令也是一样的,如不指定表名,默认表名是filter

插入一个规则
iptables -I INPUT 3 -p tcp --dport 22 -j ACCEPT (插入到第三个)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

删除一个规则
iptables -D INPUT 3 (删掉第三个)
iptables -D INPUT -p tcp --dport 22 -j ACCEPT
删除所有规则
iptables -F

常用:
限制到本机网路流量

iptables -A INPUT -s 192.168.1.100 -j DROP (丢弃来自ip为192.168.1.100的流量)
iptables -A INPUT -p tcp --dport 80 -j DROP (丢弃访问本机网页服务80端口的流量)
iptables -A INPUT -s 123.45.0.0/16 -p tcp --dport 22 -j DROP (丢弃来自ip 123.45.0.1至123.45.255.254 的ssh连接)
iptables -A INPUT -s 123.45.0.0/16 -p tcp --dport 22 -j DROP (丢弃来自ip 123.45.0.1至123.45.255.254 的ssh连接)

当linux系统作为路由(进行数据转发)设备使用时,可以通过定义forward规则来进行转发控制。

如:
iptables -A FORWARD -s 192.168.1.0/24 -d 10.1.1.0/24 -j DROP (禁止192.168.0.1192.168.0.254到10.1.1.110.1.1.254的流量)

NAT(Network Address Translation)网络地址转换是用来对数据包的IP地址进行修改的机制,NAT分为两种:
  • SNAT 源地址转换,通常用于伪装内部地址(一般意义上的NAT)
  • DNAT 目标地址转换,通常用于跳转

iptables中实现NAT功能的是NAT表
通过NAT进行跳转:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-dest 192.168.1.10
通过NAT对出向数据进行跳转:
iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-dest 192.168.1.100
通过NAT对数据流进行伪装:(一般意思上的NAT,将内部地址全部伪装成一个外部公网ip地址)
iptables -t nat -A POSTROUTING -o ech0 -j MASQUERADE
通过NAT隐藏源IP地址:
iptables -t nat -A POSTROUTING -j SNAT --to-source 1.2.3.4

配置文件

通过iptables命令添加的规则不会永久保存,只存在内存,重启失效。如果需要永久保存规则,则需要将规则保存在 /etc/sysconfig/iptables 配置文件中
通过以下命令将iptables规则写入配置文件
service iptables save 或者 iptables-save > /etc/sysconfig/iptables

保存现有的规则到指定文件,主要是配合iptables-restore命令,iptables-restore命令用来还原iptables-save命令所备份的iptables配置。
iptables-save > iptables.bak

iptables-restor < iptables.bak


参照: http://man.linuxde.net/iptables


底层的原理往下阅读


netfilter钩子(hooks)

在内核协议栈中,有5个跟netfilter有关的钩子,数据包经过每个钩子时,都会检查上面是否注册有函数,如果有的话,就会调用相应的函数处理该数据包。流程:

         |
         | Incoming
         ↓
+-------------------+
| NF_IP_PRE_ROUTING |
+-------------------+
         |
         |
         ↓
+------------------+
|                  |         +----------------+
| routing decision |-------->| NF_IP_LOCAL_IN |
|                  |         +----------------+
+------------------+                 |
         |                           |
         |                           ↓
         |                  +-----------------+
         |                  | local processes |
         |                  +-----------------+
         |                           |
         |                           |
         ↓                           ↓
 +---------------+          +-----------------+
 | NF_IP_FORWARD |          | NF_IP_LOCAL_OUT |
 +---------------+          +-----------------+
         |                           |
         |                           |
         ↓                           |
+------------------+                 |
|                  |                 |
| routing decision |<----------------+
|                  |
+------------------+
         |
         |
         ↓
+--------------------+
| NF_IP_POST_ROUTING |
+--------------------+
         |
         | Outgoing
         ↓
  • NF_IP_PRE_ROUTING: 接收的数据包刚进来,还没有经过路由选择,即还不知道数据包是要发给本机还是其它机器。
  • NF_IP_LOCAL_IN: 已经经过路由选择,并且该数据包的目的IP是本机,进入本地数据包处理流程。
  • NF_IP_FORWARD:已经经过路由选择,但该数据包的目的IP不是本机,而是其它机器,进入forward流程。
  • NF_IP_LOCAL_OUT:本地程序要发出去的数据包刚到IP层,还没进行路由选择。
  • NF_IP_POST_ROUTING:本地程序发出去的数据包,或者转发(forward)的数据包已经经过了路由选择,即将交由下层发送出去。

从上面的流程中,可看出,不考虑特殊情况的话,一个数据包只会经过下面三个路径中的一个:

  • 本机收到目的IP是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_LOCAL_IN
  • 本机收到目的IP不是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_FORWARD -> NF_IP_POST_ROUTING
  • 本机发出去的数据包: NF_IP_LOCAL_OUT -> NF_IP_POST_ROUTING

iptables中的表(tables)

iptables用表(table)来分类管理它的规则(rule),根据rule的作用分成了好几个表,比如用来过滤数据包的rule就会放到filter表中,用于处理地址转换的rule就会放到nat表中,其中rule就是应用在netfilter钩子上的函数,用来修改数据包的内容或过滤数据包。目前iptables支持的表有下面这些:

Filter

从名字就可以看出,这个表里面的rule主要用来过滤数据,用来控制让哪些数据可以通过,哪些数据不能通过,它是最常用的表。

NAT

里面的rule都是用来处理网络地址转换的,控制要不要进行地址转换,以及怎样修改源地址或目的地址,从而影响数据包的路由,达到连通的目的,这是家用路由器必备的功能。

Mangle

里面的rule主要用来修改IP数据包头,比如修改TTL值,同时也用于给数据包添加一些标记,从而便于后续其它模块对数据包进行处理(这里的添加标记是指往内核skb结构中添加标记,而不是往真正的IP数据包上加东西)。

Raw

在netfilter里面有一个叫做connection tracking的功能(后面会介绍到),主要用来追踪所有的连接,而raw表里的rule的功能是给数据包打标记,从而控制哪些数据包不被connection tracking所追踪。

Security

里面的rule跟SELinux有关,主要是在数据包上设置一些SELinux的标记,便于跟SELinux相关的模块来处理该数据包。

iptables的链(chains)

上面我们根据不同功能将rule放到了不同的表里面之后,这些rule会注册到哪些钩子上呢?于是iptables将表中的rule继续分类,让rule属于不同的链(chain),由chain来决定什么时候触发chain上的这些rule。

iptables里面有5个内置的chains,分别对应5个钩子:

  • PREROUTING: 数据包经过NF_IP_PRE_ROUTING时会触发该chain上的rule.
  • INPUT: 数据包经过NF_IP_LOCAL_IN时会触发该chain上的rule.
  • FORWARD: 数据包经过NF_IP_FORWARD时会触发该chain上的rule.
  • OUTPUT: 数据包经过NF_IP_LOCAL_OUT时会触发该chain上的rule.
  • POSTROUTING: 数据包经过NF_IP_POST_ROUTING时会触发该chain上的rule.
netfilter的钩子(hooks) iptables的链(chains)
NF_IP_PRE_ROUTING PREROUTING
NF_IP_LOCAL_IN INPUT
NF_IP_FORWARD FORWARD
NF_IP_LOCAL_OUT OUTPUT
NF_IP_POST_ROUTING POSTROUTING

每个表里面都可以包含多个chains,但并不是每个表都能包含所有的chains,因为某些表在某些chain上没有意义或者有些多余。多个表里面可以包含同样的chain,会涉及到优先级的问题。

netfilter的钩子(hooks) iptables的链(chains) Filter NAT Mangle Raw Security
NF_IP_PRE_ROUTING PREROUTING
NF_IP_LOCAL_IN INPUT
NF_IP_FORWARD FORWARD
NF_IP_LOCAL_OUT OUTPUT
NF_IP_POST_ROUTING POSTROUTING

每个表(table)都包含哪些chain,表之间的优先级

  1. 图中每个钩子关联的表按照优先级高低,从上到下排列;
  2. 图中将nat分成了SNAT和DNAT,便于区分;
  3. 图中标出了connection tracking(可以简单的把connection tracking理解成一个不能配置chain和rule的表,它必须放在指定位置,只能enable和disable)。
                                    |
                                    | Incoming             ++---------------------++
                                    ↓                      || raw                 ||
                           +-------------------+           || connection tracking ||
                           | NF_IP_PRE_ROUTING |= = = = = =|| mangle              ||
                           +-------------------+           || nat (DNAT)          ||
                                    |                      ++---------------------++
                                    |
                                    ↓                                                ++------------++
                           +------------------+                                      || mangle     ||
                           |                  |         +----------------+           || filter     ||
                           | routing decision |-------->| NF_IP_LOCAL_IN |= = = = = =|| security   ||
                           |                  |         +----------------+           || nat (SNAT) ||
                           +------------------+                 |                    ++------------++
                                    |                           |
                                    |                           ↓
                                    |                  +-----------------+
                                    |                  | local processes |
                                    |                  +-----------------+
                                    |                           |
                                    |                           |                    ++---------------------++
 ++------------++                   ↓                           ↓                    || raw                 ||
 || mangle     ||           +---------------+          +-----------------+           || connection tracking ||
 || filter     ||= = = = = =| NF_IP_FORWARD |          | NF_IP_LOCAL_OUT |= = = = = =|| mangle              ||
 || security   ||           +---------------+          +-----------------+           || nat (DNAT)          ||
 ++------------++                   |                           |                    || filter              ||
                                    |                           |                    || security            ||
                                    ↓                           |                    ++---------------------++
                           +------------------+                 |
                           |                  |                 |
                           | routing decision |<----------------+
                           |                  |
                           +------------------+
                                    |
                                    |
                                    ↓
                           +--------------------+           ++------------++
                           | NF_IP_POST_ROUTING |= = = = = =|| mangle     ||
                           +--------------------+           || nat (SNAT) ||
                                    |                       ++------------++
                                    | Outgoing
                                    ↓
  • 以NF_IP_PRE_ROUTING为例,数据包到了这个点之后,会先执行raw表中PREROUTING(chain)里的rule,然后执行connection tracking,接着再执行mangle表中PREROUTING(chain)里的rule,最后执行nat (DNAT)表中PREROUTING(chain)里的rule。
  • 以filter表为例,它只能注册在NF_IP_LOCAL_IN、NF_IP_FORWARD和NF_IP_LOCAL_OUT上,所以它只支持INPUT、FORWARD和OUTPUT这三个chain。
  • 以收到目的IP是本机的数据包为例,它的传输路径为:NF_IP_PRE_ROUTING -> NF_IP_LOCAL_IN,那么它首先要依次经过NF_IP_PRE_ROUTING上注册的raw、connection tracking 、mangle和nat (DNAT),然后经过NF_IP_LOCAL_IN上注册的mangle、filter、security和nat (SNAT)。

iptables中的规则(Rules)

rule存放在特定表的特定chain上,每条rule包含下面两部分信息:

Matching

Matching就是如何匹配一个数据包,匹配条件很多,比如协议类型、源/目的IP、源/目的端口、in/out接口、包头里面的数据以及连接状态等,这些条件可以任意组合从而实现复杂情况下的匹配。
详情请参考Iptables matches https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#MATCHES

Targets

Targets就是找到匹配的数据包之后怎么办,常见的有下面几种:

DROP:直接将数据包丢弃,不再进行后续的处理
RETURN: 跳出当前chain,该chain里后续的rule不再执行
QUEUE: 将数据包放入用户空间的队列,供用户空间的程序处理
ACCEPT: 同意数据包通过,继续执行后续的rule
跳转到其它用户自定义的chain继续执行
当然iptables包含的targets很多很多,但并不是每个表都支持所有的targets,
rule所支持的target由它所在的表和chain以及所开启的扩展功能来决定,
具体每个表支持的targets请参考Iptables targets and jumps https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#TARGETS


原文:https://segmentfault.com/a/1190000009043962

你可能感兴趣的:(linux)