Iptable防火墙介绍:

目前市面上比较常见的有3、4层的防火墙,叫网络层的防火墙,还有7层的防火墙,其实是代理层的网关。

防火墙策略一般分为两种,通策略,默认门是关着的,必须要定义谁能进。堵策略则是,大门是洞开的,但是你必须有身份认证,否则不能进。所以通,是要全通,而堵,则是要选择。

内核空间中常用5个位置,

1.内核空间中:从一个网络接口进来,到另一个网络接口去的

2.数据包从内核流入用户空间的

3.数据包从用户空间流出的

4.进入/离开本机的外网接口

5.进入/离开本机的内网接口

这是NetFilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链。

1.PREROUTING (路由前)、2.INPUT (数据包流入口)、3.FORWARD (转发管卡)、4.OUTPUT(数据包出口)、5.POSTROUTING(路由后)

【多条链整合起来叫做表,因此在编写规则的时候应该先指定表,再指定链】

说明:

input  :负责过滤所有目标地址是本机地址的数据包,就是过滤进入主机的数据包;

forward :负责转发流经主机但不进入本机的数据包,和NAT关系很大;

output  :负责处理源地址的数据包,就是对本机发出的数据包;

表:

filter表:主要和主机自身有关,主要负责防火墙功能 过滤本机流入流出的数据包是默认使用的表;

NAT表:负责网络地址转换,即来源于目的IP地址和端口的转换,一般用于共享上网或特殊端口的转换服务

【snat :地址转换、dnat :标地址转换、pnat :标端口转换】

mangle 表:将报文拆开来并修改报文标志位,最后封装起来

 

表和链的对应关系:

filter:INPUT ,FORWARD ,OUTPUT

nat:PREROUTING ,OUTPUT ,POSTROUTING

而mangle则是5个链都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

注意:规则的次序非常关键,谁的规则越严格,应该放的越靠前,而检查规则的时候,是按照从上往下的方式进行检查的。

 

规则的写法:

格式:iptables [-t table] COMMAND chainCRETIRIA -j ACTION

iptables[-t 表] 大写选项子命令 [规则号] 链名匹配标准 -j 目标(规则)

-t 指定表:3个filter、nat 、mangle

COMMAND:定义如何对规则进行管理

chain:指定你接下来的规则到底是在哪个链上操作的,当定义策略的时候,是可以省略的

CRETIRIA:指定匹配标准

-j ACTION :指定如何进行处理

 

比如:不允许172.16.0.0/24的进行访问。

iptables -t filter -A INPUT -s172.16.0.0/16 -p udp --dport 53 -j DROP

当然你如果想拒绝的更彻底:

iptables -t filter -R INPUT 1 -s172.16.0.0/16 -p udp --dport 53 -j REJECT

iptables -L -n -v         #查看定义规则的详细信息

 

详解COMMAND:

1.链管理命令(这都是立即生效的)

-P :设置默认策略的(设定默认门是关着的DROP还是开着的ACCEPT):iptables -PINPUT (DROP|ACCEPT) 

-F: FLASH,清空规则链的(注意每个链的管理权限)iptables-t nat -F PREROUTING

-N:NEW 支持用户新建一个链:iptables -Ninbound_tcp_web 表示附在tcp表上用于检查web的。

-X: 用于删除用户自定义的空链,使用方法跟-N相同,但是在删除之前必须要将里面的链给清空昂了

-E:用来Rename chain主要是用来给用户自定义的链重命名,-E oldname newname

-Z:计算器清零; iptables -Z :清空

2.规则管理命令

-A:追加,在当前链的最后新增一个规则

-I num : 插入,把当前规则插入为第几条。 -I 3:插入为第三条

-R

-D num:删除,明确指定删除第几条规则

       

3.查看管理命令 “-L”附加子命令

-n:数字格式显示IP和端口。

-v:显示详细信息 -vv、-vvv :越多越详细

-x:在计数器上显示精确值,不做单位换算

--line-numbers : 显示规则的行号

-t nat:显示所有的关卡的信息

 

匹配标准分为两种:

1.通用匹配:源地址目标地址的匹配

-s:指定作为源地址匹配,这里必须是IP,而且地址可以取反加!:IP | IP/MASK| 0.0.0.0/0.0.0.0

-d:表示匹配目标地址

-p:用于匹配协议的(这里的协议通常有3种,TCP/UDP/ICMP)

-i eth0:从这块网卡流入的数据【流入一般用在INPUT和PREROUTING上】

-o eth0:从这块网卡流出的数据【流出一般在OUTPUT和POSTROUTING上】

说明:iptables –L –n –v

pkts:被本机报文所匹配的个数、bytes:报文所有大小记起来之和、opt:额外的选项,--表示没有、target:处理机制、prot:放行哪种协议、source:源地址、destination:目标地址

 

2.扩展匹配

对协议的扩展

-p tcp :TCP协议的扩展。一般有三种扩展

--dport 21 或者 --dport 21-23 (此时表示端口21,22,23)

例:放行本机对web的访问:iptables -A INPUT -d 10.0.10.62 -ptcp --dport 80 -j ACCEPT

--sport:指定源端口

--tcp-fiags:TCP检测报文中的标志位(SYN,ACK,FIN,RST)

--tcpflags syn,ack,fin,rst syn :表示检查这4个位,这4个位中syn必须为1,其他的必须为0。所以这个意思就是用于检测三次握手的第一次包的。对于这种专门匹配第一包的SYN为1的包,还有一种简写方式,叫做--syn

-p udp:UDP协议的扩展【--dport、--sport】

-p icmp:icmp数据报文的扩展:--icmp-type:

echo-request(请求回显),一般用8 来表示,所以--icmp-type 8 匹配请求回显数据包

echo-reply (响应的数据包)一般用0来表示                 

显式扩展(-m)

扩展各种模块:-m multiport:表示启用多端口扩展,之后我们就可以启用比如 --dports 21,23,80

                          

详解-j ACTION【常用的目标:ACTION:】

DROP:丢弃

REJECT:拒绝

ACCEPT:接受

RETURN:返回主链继续匹配

REDIRECT:端口重定向

MASQUERADE:地址伪装

DNAT : 目标地址转换

SNAT :源地址转换

MARK :打防火墙标记的

 

四种状态:NEW、ESTABLISHED、RELATED及INVALID

在iptalbes中数据包和被跟踪连接的4种不同状态相关联,这四种状态分别是NEW、ESTABLISHED、RELATED及INVALID,除了本机产生的数据包由NAT表的OUTPUT链处理外,所有连接跟踪都是在NAT表的PREROUTING链中进行处理的,也就是说iptables在NAT表的PREROUTING链里从新计算所有数据包的状态。如果发送一个流的初始化数据包,状态就会在NAT表的OUTPUT链里被设置为NEW,当收到回应的数据包时,状态就会在NAT表的PREROUTING链里被设置为ESTABLISHED,如果第一个数据包不是本机生成的,那就回在NAT表PREROUTING链里被设置为NEW状态,所以所有状态的改变和计算都是在NAT表中的表链和OUTPUT链里完成的。

使用-m来指定其状态并赋予匹配规则,语法如下-mstate --state 状态【NEW、ESTABLISHED、RELATED、INVALID】

NEW:NEW状态的数据包说明这个数据包是收到的第一个数据包。

ESTABLISHED:只要发送并接到应答,一个数据连接就从NEW变为ESTABLISHED,而且该状态会继续匹配这个连接后继数据包。

RELATED:当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED,也就是说,一个连接想要是RELATED的,首先要有个ESTABLISHED的连接,这个ESTABLISHED连接再产生一个主连接之外的连接,这个新的连接就是RELATED。

INVALID:说明数据包不能被识别属于哪个连接或没有任何状态。

 

例:对本机22端口做状态监测:

进来的请求状态为new,而出去的状态则为ESTABLISHED,如果自动连接别人状态肯定为NEW,如果正常去响应别人那么状态肯定是ESTABLISHED

iptables -I INPUT -s 10.0.10.0/24 -d10.0.10.62 -p tcp --dport 22 -m state--state NEW,ESTABLISHED -j ACCEPT

出口的响应都必须是ESTABLISHED

iptables -A OUTPUT -s 10.0.10.62 -d10.0.10.0/24 -p tcp --dport 22 -m state--state ESTABLISHED -j ACCEPT

 

多端口规则匹配

使用参数-m multiport 可以指定15个以内的非连续端口,比如21-22,80、-m mulitport  【--src-prots、--dst-ports、--prots】

例:对多端口进行匹配,只要匹配以下端口,则全部放行

iptables -A INPUT  -s 10.0.10.0/24 -d10.0.10.62 -p tcp -m state--state NEW  -m mulitport-- -ports21,22,80 -j ACCEPT

 

多IP匹配,指定匹配的IP地址范围:-miprange【--src-range、--dst-range】

指定匹配的连续ip段:【iptables -A INPUT -s  -miprange --src-range 10.0.10.100-10.0.10.200】

指定速率匹配:

默认为每秒匹配3个报文,基于令牌桶算法

-mlimit【--limit  #NUMBER,表示允许收集多少个空闲令牌、--limit-burst  #RATE,允许放行多少个报文】

比如:ssh一分钟之内只能建立20个链接,平均5秒一个,而一次性只能放行2个空闲令牌

【--limit 20/min、--limit-burst 2】

只有在大量空闲令牌存储的情况下,才可有limit-burst控制

 

例:控制NEW状态的请求: iptables -A INPUT -s 10.0.10.0/24 -d 10.0.10.62 -m state --state NEW-mlimit --limit 12/min --limit 12/min --limit-burst 2 -j ACCEPT

例2:每次只允许2个ping包进来

iptables -F

iptables -A INPUT -s 10.0.10.0/24 -d10.0.10.62 -p icmp --icmp-type 8 -mlimit --limit 20/min --limit-burst 5 -jACCEPT

 

对应用层进行匹配

对应用层编码字符串做相似匹配,常用算法使用--alog来指定,一般来讲算法一般为bm和kmp

-msrting 【--string ""、--algo {bm|kmp}】

例:

假如我们期望web站点页面中任何包含"hello"的字符串的页面,则禁止访问,其他则放行

请求报文中不会包含hello,一般来讲只包含访问某个页面,那么请求内容无非包含了请求某个链接而已

响应报文中会封装页面的内容信息,因此会出现在响应报文中,而不是请求报文

启动httpd服务:/etc/init.d/httpd start

在web站点新建页面1.html,内容为"hello" , 2.html内容为"word"【echo hello > 1.html、echo word > 2.html】

在iptables的允许放行规则前面加一条更严谨的禁止规则:

 iptables -A OUTPUT -s 10.0.10.62 -p tcp--sport 80 -m string --string"hello" --algo kmp -j REJECT

再次访问:curl -dump http://10.0.10.62/2.html【结果:word】

curl -dump http://10.0.10.62/1html

#请求已发出去但是一直没有反应,我们来看一下防火墙规则是否被匹配到【iptables -L -nv】

 

基于时间限定:【m time】

#指定日期起止范围【--datestart、--datestop】

#指定时间的起止范围【--timestart、--timestop】

#指定星期x范围【--weekdays】、#指定月份【--monthdays】

 

练习:只要是来自于172.16.0.0/16网段的都允许访问我本机的172.16.100.1的SSHD服务

  分析:首先肯定是在允许表中定义的。因为不需要做NAT地址转换之类的,然后查看我们SSHD服务,在22号端口上,处理机制是接受,对于这个表,需要有一来一回两个规则,如果我们允许也好,拒绝也好,对于访问本机服务,我们最好是定义在INPUT链上,而OUTPUT再予以定义就好。(会话的初始端先定义),所以加规则就是:

定义进来的: iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.1 -p tcp--dport 22 -j ACCEPT

定义出去的: iptables -t filter -A OUTPUT -s 172.16.100.1 -d 172.16.0.0/16 -ptcp --dport 22 -j ACCEPT

将默认策略改成DROP:【iptables -P INPUT DROP、iptables -P OUTPUT DROP、iptables -P FORWARDDROP】

 

所以我们对于刚才的练习题,可以增加状态检测。比如进来的只允许状态为NEW和ESTABLISHED的进来,出去只允许ESTABLISHED的状态出去,这就可以将比较常见的反弹式木马有很好的控制机制。

进来的拒绝出去的允许,进来的只允许ESTABLISHED进来,出去只允许ESTABLISHED出去。默认规则都使用拒绝

iptables -L -n --line-number  :查看之前的规则位于第几行

改写INPUT:iptables -R INPUT 2 -s 172.16.0.0/16 -d 172.16.100.1 -p tcp --dport22 -m state --state NEW,ESTABLISHED -j ACCEPT

         iptables -R OUTPUT 1 -m state --state ESTABLISHED -j ACCEPT

 

此时如果想再放行一个80端口如何放行呢?

iptables -A INPUT -d 172.16.100.1 -p tcp--dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -R INPUT 1 -d 172.16.100.1 -p udp--dport 53 -j ACCEPT

 

练习题2:

假如我们允许自己ping别人,但是别人ping自己ping不通如何实现呢?

分析:对于ping这个协议,进来的为8(ping),出去的为0(响应).我们为了达到目的,需要8出去,允许0进来

在出去的端口上:iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT

在进来的端口上:iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT

 

小扩展:对于127.0.0.1比较特殊,我们需要明确定义它

                            iptables-A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT

                            iptables-A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT

 

SNAT和DNAT的实现

考虑场景:为解决IP地址不足,所以用NAT功能来实现成本节约

1.SNAT基于原地址的转换:一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将我们内网的地址转换为一个外网的IP,我们就可以实现连接其他外网IP的功能。

所以我们在iptables中就要定义到底如何转换:

SNAT:源地址转换(代理内部客户端访问外部网络)在POSTROUTING或OUTPUT链上来做规则限制

参数选项:【-j SNAT --to-source IP、-j MASQUERADE】

定义的样式:比如我们现在要将所有192.168.10.0网段的IP在经过的时候全都转换成172.16.100.1这个假设出来的外网地址:

iptables -t nat -A POSTROUTING -s192.168.10.0/24 -j SNAT --to-source 172.16.100.1

这样,只要是来自本地网络的试图通过网卡访问网络的,都会被统统转换成172.16.100.1这个IP.

那么,如果172.16.100.1不是固定的怎么办?

我们都知道当我们使用联通或者电信上网的时候,一般它都会在每次你开机的时候随机生成一个外网的IP,意思就是外网地址是动态变换的。这时我们就要将外网地址换成 MASQUERADE(动态伪装):它可以实现自动寻找到外网地址,而自动将其改为正确的外网地址。所以,我们就需要这样设置:

iptables -t nat -A POSTROUTING -s 192.168.10.0/24-j MASQUERADE

这里要注意:地址伪装并不适用于所有的地方。

 

2.DNAT目标地址转换:数据流向是从外向内的,外面的是客户端,里面的是服务器端通过目标地址转换,我们可以让外面的ip通过我们对外的外网ip来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上。

DNAT :目标地址转换(将内部服务器公开至外部网络)需在PREROUTING做限制

参数选项:-j DNAT --to-destination IP:prot

如何做目标地址转换呢?:iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp --dport 80 -jDNAT --todestination 172.16.100.2

目标地址转换要做在到达网卡之前进行转换,所以要做在PREROUTING这个位置上

 

控制规则的存放以及开启

注意:你所定义的所有内容,当你重启的时候都会失效,要想我们能够生效,需要使用一个命令将它保存起来

1.service iptables save 命令,它会保存在/etc/sysconfig/iptables这个文件中

2.iptables-save 命令,iptables-save> /etc/sysconfig/iptables

3.iptables-restore 命令:开机的时候,它会自动加载/etc/sysconfig/iptabels,如果开机不能加载或者没有加载,而你想让一个自己写的配置文件(假设为iptables.2)手动生效的话:iptables-restore < /etc/sysconfig/iptables.2,则完成了将iptables中定义的规则手动生效