iptables/netfilter介绍、样例实验和配置规则

0x 01 前言

Iptables是运行在用户空间的应用级(Ring3)防火墙软件,通过调用Linux内核的Netfilter模块,进行网络数据包的流动、转送以及修改。iptables是状态防火墙,可以对会话的状态进行跟踪,这点相较于无状态防火墙要方便许多。
Netfilter是由Rusty Russell提出的Linux 2.4.x内核防火墙框架,目前支持的内核包括2.4、2.6及3.0。iptables所设置的规则最终是存放在内核内存中的Xtables(Netfilter的配置表)。Iptables和ip6_tables、arp_tables等Netfilter的项目都是建构在Xtables的架构下。


0x 02 表,链以及规则

1、表(tables)

表是包含了不同默认链的组合,每个表都和数据包的处理有关,iptables共内置了5个表,即filter,nat,mangle,raw,security分别实现数据包过滤、动态网络地址转换,(Network Address Translation,NAT),数据包修改,数据包状态跟踪,以及实现强制访问控制MAC(Mandatory Access Control )和自主访问控制DAC(Discretionary Access Control )等。

2、链(chains)

链是决定数据包是否可以通过的决定因素,每个数据包从进入系统,到离开系统,都至少要通过2条链。
链是Netfilter中的挂载点(Hook Point)在iptables中的体现,共包括5条链,分别为PREROUTING(数据包进入路由表之前),INPUT(通过路由表后目的地为本机),FORWARD(通过路由表后,目的地不为本机),OUTPUT(由本机产生,向外转发),POSTROUTING(发送到网卡接口之前),对应Netfilter中5个挂载点:

NF_INET_PRE_ROUTING,NF_INET_LOCAL_IN,NF_INET_FORWARD,NF_INET_LOCAL_OUT,NF_INET_POST_ROUTING

图1 Netfilter框架

注:挂载点(Hook Point),可以理解为回调函数点,数据包到达这些位置的时候,会主动调用对应的函数,使其在数据包路由的时候可以改变它们的路径以及内容。

3、规则(rules)

规则在链里面决定对数据包的处理动作,存储在内核空间的Xtables中。在这里,可以定义对数据包的具体处理(target)。当数据包穿过一条链的时候,每条规则会依序检查它(包括源目地址,协议等参数),如果没有规则与其相匹配,则数据包会被传递到下一条规则去尝试匹配,当匹配上之后,会按照target中规定的动作对数据包进行梳理。

图2  iptables中表、链以及规则的对应关系


0x 03 利用Iptables进行网络地址转换实例展示

我们经常使用xshell等交互式工具进行端口转发和地址转换,iptables中的地址转换功能对大部分人来说用到不算很多,但是却很有用。以此例来展示iptables的使用。

1、环境:

  • 1台centos7主机作为web主机
ip=192.168.0.10,hostname=webserver
  • 1台Ubuntu 16.04作为iptables所在主机,iptables版本为iptables 1.6.0
ip=192.168.0.5,hostname= IptablesTest
  • 1台Ubuntu 16.04作为client(192.168.0.20)
ip=192.168.0.20,hostname=client

2、需求描述

模仿反向代理的场景,webserver的http流量不能被其他机器直接访问,需要通过IptablesTest作为中转才能到达。

  • 首先在webserver将所有的入流量全部DROP,这样所有的流量都无法进入该机器
         iptables -P INPUT DROP
  • 在webserver上放行IptablesTest的流量以及宿主机(192.168.0.4)的流量
iptables -I INPUT -s 192.168.0.4 -j ACCEPT
iptables -I INPUT -s 192.168.0.5 -j ACCEPT
  • webserver上的iptables配置完成后的filter表如下:

  • 由于Linux默认将路由功能关闭,因此需要在IptablesTest机器上打开Linux路由转发开关功能,具体方法如下:
    编辑/etc/sysctl.conf,并加入如下语句

如果仅希望临时生效,下次开机失效,可以执行如下语句:

echo "1" > /proc/sys/net/ipv4/ip_forward

如果需要永久生效的话,需要修改sysctl.conf:
net.ipv4.ip_forward = 1
执行sysctl -p 立即生效

注:这点很重要,也很容易被忽略

  • 在IptablesTest机器上将所有访问该机器80端口的TCP流量全部做DNAT转换,将目的地址转换为webserver的地址;并将webserver返回的流量使用SNAT转回给client,这里也可以使用路由反向做回的方向实现。
iptables -t  nat -A PREROUTING -d  192.168.0.5/32  -p tcp --dport 80 -j DNAT --to-destination  192.168.0.10:80
iptables -t nat -A POSTROUTING -d  192.168.0.10/32  -p tcp -j SNAT --to  192.168.0.5
  • IptablesTest上iptables配置完成后的filter表如下:

  • 我们发现直接访问webserver地址,发现并不通,而访问IptablesTest的80端口,发现可以打开http服务。说明访问webserver的流量被IptablesTest进行了转换和代理。


0x 04 Iptables常见配置命令和操作

一、链及NAT的基本操作

1、清除所有的规则

清空自定义链、清空规则、清空规则计数器

iptables -X
iptables -F
iptables -Z

清除NAT表规则

iptables -F -t nat

NAT表的显示

iptables -t nat -nL
2、设置链的默认策略。一般有两种方法。

首先允许所有的包,然后再禁止有危险的包通过放火墙。

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

首先禁止所有的包,然后根据需要的服务允许特定的包通过防火墙。

iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
3、列出表/链中的所有规则。默认只列出filter表。
iptables -L
4、向链中添加规则。下面的语句用于开放网络接口:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACEPT
iptables -A OUTPUT -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -j ACCEPT
iptables -A FORWARD -0 eth1 -j ACCEPT

注意:由于本地进程不会经过FORWARD链,因此回环接口lo只在INPUT和OUTPUT两个链上作用。

5、按需自定义链。
iptables -N custom
iptables -A custom -s 0/0 -d 0/0 -p icmp -j DROP
iptables -A INPUT -s 0/0 -d 0/0 -j custom

二、设置基本的规则匹配

1、指定协议匹配。

匹配指定协议。

iptables -A INPUT -p tcp

匹配指定协议之外的所有协议。

iptables -A INPUT -p !tcp
2、指定地址匹配。

指定匹配的主机。

iptables -A INPUT -s 192.168.0.18

指定匹配的网络。

iptables -A INPUT -s 192.168.2.0/24

匹配指定主机之外的地址。

iptables -A FORWARD ! -s 192.168.0.19

匹配指定网络之外的网络。

iptables -A FORWARD ! -s  192.168.3.0/24
3、指定网络接口匹配。

指定单一的网络接口匹配。

iptables -A INPUT -i eth0
iptables -A FORWARD -o eth0

指定同类型的网络接口匹配。

iptables -A FORWARD -o ppp+
4、指定端口匹配。

指定单一端口匹配。

iptables -A INPUT -p tcp --sport www
iptables -A INPUT -p udp --dport 53

匹配指定端口之外的端口。

iptables -A INPUT -p tcp --dport !22

匹配端口范围。

iptables -A INPUT -p tcp --sport 22:80

匹配ICMP端口和ICMP类型。

iptables -A INPUT -p icmp --icmp-type 8

指定ip碎片。

  • 每个网络接口都有一个MTU(最大传输单元),这个参数定义了可以通过的数据包的最大尺寸。如果一个数据包大于这个参数值时,系统会将其划分成更小的数据包(称为ip碎片)来传输,而接受方则对这些ip碎片再进行重组以还原整个包。这样会导致一个问题:当系统将大数据包划分成ip碎片传输时,第一个碎片含有完整的包头信息(IP+TCP、UDP和ICMP),但是后续的碎片只有包头的部分信息(如源地址、目的地址)。因此,检查后面的ip碎片的头部(像有TCP、UDP和ICMP一样)是不可能的。假如有这样的一条规则:
iptables -A FORWARD -p tcp -s 192.168.1.0/24 -d 192.168.2.100 –dport 80 -j ACCEPT
  • 并且这时的FORWARD的policy为DROP时,系统只会让第一个ip碎片通过,而余下的碎片因为包头信息不完整而无法通过。可以通过—fragment/-f 选项来指定第二个及以后的ip碎片解决上述问题。
iptables -A FORWARD -f -s 192.168.1.0/24 -d 192.168.2.100 -j ACCEPT

注意现在有许多进行ip碎片的实例,如DoS,因此允许ip碎片通过是有安全隐患的,对于这一点可以采用iptables的匹配扩展来进行限制。

三、设置扩展的规则匹配(举例已忽略目标动作)

1、多端口匹配。

匹配多个源端口。

iptables -A INPUT -p tcp -m multiport --sport 22,53,80,110

匹配多个目的端口。

iptables -A INPUT -p tcp -m multiport --dpoort 22,53,80

匹配多端口(无论是源端口还是目的端口)

iptables -A INPUT -p tcp -m multiport --port 22,53,80,110
2、指定TCP匹配扩展

使用 –tcp-flags 选项可以根据tcp包的标志位进行过滤。

iptables -A INPUT -p tcp --tcp-flags SYN,FIN,ACK SYN
iptables -A FROWARD -p tcp --tcp-flags ALL SYN,ACK

上实例中第一个表示SYN、ACK、FIN的标志都检查,但是只有SYN匹配。第二个表示ALL(SYN,ACK,FIN,RST,URG,PSH)的标志都检查,但是只有设置了SYN和ACK的匹配。

iptables -A FORWARD -p tcp --syn

选项—syn相当于”–tcp-flags SYN,RST,ACK SYN”的简写。

3、limit速率匹配扩展。

指定单位时间内允许通过的数据包个数,单位时间可以是/second、/minute、/hour、/day或使用第一个子母。

iptables -A INPUT -m limit --limit 300/hour

指定触发事件的阀值。

iptables -A INPUT -m limit --limit-burst 10 

用来比对一次同时涌入的封包是否超过10个,超过此上限的包将直接丢弃。

同时指定速率限制和触发阀值。

iptables -A INPUT -p icmp -m limit –-limit 3/m --limit-burst 3

表示每分钟允许的最大包数量为限制速率(本例为3)加上当前的触发阀值burst数。任何情况下,都可保证3个数据包通过,触发阀值burst相当于允许额外的包数量。

基于状态的匹配扩展(连接跟踪)

每个网络连接包括以下信息:源地址、目标地址、源端口、目的端口,称为套接字对(socket pairs);协议类型、连接状态(TCP协议)和超时时间等。防火墙把这些信息称为状态(stateful)。状态包过滤防火墙能在内存中维护一个跟踪状态的表,比简单包过滤防火墙具有更大的安全性,命令格式如下:

iptables -m state –-state [!]state [,state,state,state]

其中,state表是一个逗号分割的列表,用来指定连接状态,4种:

NEW: 该包想要开始一个新的连接(重新连接或连接重定向)
RELATED:该包是属于某个已经建立的连接所建立的新连接。举例:
FTP的数据传输连接和控制连接之间就是RELATED关系。
ESTABLISHED:该包属于某个已经建立的连接。
INVALID:该包不匹配于任何连接,通常这些包被DROP。

例如:
(1)在INPUT链添加一条规则,匹配已经建立的连接或由已经建立的连接所建立的新连接。即匹配所有的TCP回应包。

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

(2)在INPUT链链添加一条规则,匹配所有从非eth0接口来的连接请求包。

iptables -A INPUT -m state -–state NEW -i !eth0

又如,对于ftp连接可以使用下面的连接跟踪:
(3)被动(Passive)ftp连接模式。

iptables -A INPUT -p tcp --sport 1024: --dport 1024: -m state –-state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport 1024: --dport 1024: -m 
state -–state ESTABLISHED,RELATED -j ACCEPT

(4)主动(Active)ftp连接模式

iptables -A INNPUT -p tcp --sport 20 -m state –-state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -p tcp –dport 20 -m state --state ESTABLISHED -j ACCEPT

参考:

https://zh.wikipedia.org/wiki/Iptables

http://www.cnblogs.com/LittleHann/p/3708222.html

https://blog.csdn.net/sealyao/article/details/5934268

https://www.frozentux.net/iptables-tutorial/cn/iptables-tutorial-cn-1.1.19.html

http://zh.wikipedia.org/wiki/Netfilter

http://www.netfilter.org/projects/iptables/

http://linux.vbird.org/linux_server/0250simple_firewall.php

http://www.vpser.net/security/linux-iptables.html

http://blog.51cto.com/xjsunjie/1902993

http://blog.51cto.com/qujunorz/1884459

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章