iptables的使用以及NAT的原理

    本节我们来讲一讲防火墙的知识。所谓防火墙指的是一个由软件和硬件设备组合而成、在内部网和外部网之间、专用网与公共网之间的界面上构造的保护屏障.是一种获取安全性方法的形象说法,它是一种计算机硬件和软件的结合,使Internet与Intranet之间建立起一个安全网关(Security Gateway),从而保护内部网免受非法用户的侵入。防火墙按照工作在不同TCP/IP层又可以分为网络层防火墙和应用层网关防火墙,二本节我们要讲的内容为网络层防火墙,即iptables,组件为netfilter/iptables。

    netfilter 组件也称为内核空间(kernelspace),是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集。

    iptables 组件是一种工具,也称为用户空间(userspace),它使插入、修改和除去信息包过滤表中的规则变得容易。

    那么下面我们就来讲讲netfilter的组成部分以及iptables命令的使用方法。


netfilter

netfilter由4表5链组成。

5条链即为5个hook function(钩子函数),可以理解为数据包传送到该计算机时的5个检查点。分别为:

PREROUTING:路由前

INPUT:到达本机内部的报文必经之路

FORWARD:由本机转发的报文必经之路

OUTPUT:由本机发出的报文的必经之路

POSTROUTING:路由后

wKiom1P0FxmD7AQbAACe5OxAR-8195.jpg

而4张表(即功能)分别为:raw, mangle, nat, filter。

raw: 目标是关闭nat表上启用的连接追踪功能;

mangle:包重构,把包拆开来打上某些标记再送走

nat: 地址转换,启用connection_track;

SNAT

DNAT

PNAT

filter: 过滤,定义是否允许通过防火墙

注意这4张表是有优先级的概念的,这里我是按照优先级排的。


表和链之间的对应关系。

filter: INPUT, FORWARD, OUTPUT

nat: PREROUTING(DNAT),POSTROUTING(SNAT),OUTPUT

mangle: PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING

raw: PREROUTING, OUTPUT


数据报文流程:如下图所示

跟本机内部进程通信:

进入:PREROUTING, INPUT

出去:OUTPUT, POSTROUTING

由本机转发:

PREROUTING, FORWARD, POSTROUTING

数据报文的流向:

源IP和目标IP由流向决定;

wKiom1P0EpLw5_9sAALLkdGkAPE897.jpg


iptables

当你要写规则时,应该先确定功能(表),确定报文流向,确定要实现的目标,确定匹配件。

iptables规则定义原则:

1、同一类规则,尽量优化条目数量;

2、彼此不相关的规则匹配量大的规则,放在前面,匹配机会较多放在上面;

3、同一类规则,匹配规则更严格放在上面。

必须要注意的是:规则立即生效,所以当你使用iptables时需要先添加放行自己会话的规则,避免自己的会话被拒绝。

规则文件:/etc/sysconfig/iptables

保存启用中的规则于规则文件中:

1、# iptables-save > /etc/sysconfig/iptables

2、# service iptables save


生效规则文件中的规则:

1、# iptables-restore < /etc/sysconfig/iptables

2、# service iptables restart

执行的操作:清空现有规则,读取并生效规则文件中的规则



基本语法:

iptables [-t TABLE] COMMAND CHAIN  CRETIRIA -j TARGET

下面对每一项进行解释:

-t TABLE: 选择哪个表

   nat, mangle, raw, filter

   默认为filter


COMMAND:

链:

-F:flush, 清空规则链;

-N:new, 自建一条链

-X: delete, 删除一条自定义的空链

-Z:zero,计数器归零

-P:policy,设置默认策略,对filter表来讲,默认规则为ACCEPT或DROP;

-E:重命名自定义链


链中的规则:

-A 添加规则

-I 插入规则

-D 删除规则

-R 修改规则


查询:

-L

   -n: 数字格式显示主机地址和端口;

   -v: 详细格式,-vv, -vvv

   -x: exactly,不要对计数器的计数结果做单位换算,而显示其精确值  

   --line-numbers: 显示规则编号

查看后得到的

wKioL1P0HIDAYoOsAACJkGyHUog513.jpg

pkts bytes  target     prot opt in        out         source               destination

包数 字节数 目标       协议  流入的接口  流出的接口   源地址               目标地址


CHAIN:选定哪个链


添加规则

iptables [-t TABLE] -A 链名 匹配条件 -j 处理目标

匹配条件

通用匹配

-s 地址:指定报文源IP地址匹配的范围;可以是IP,也可以是网络地址;可使用!取反;

   --src, --source

-d 地址:指定报文目标IP地址匹配的范围;

   --dst, --destination

-p 协议:指定匹配报文的协议类型,一般有三种tcp, udp和icmp;

-i INTERFACE: 数据报文流入的接口;PREROUTING, INPUT, FORWARD

-o INTERFACE: 数据报文流出的接口;OUTPUT, FORWARD, POSTROUITING


扩展匹配:调用netfilter额外模块实现特殊检查机制,(使用到相关功能,要使用iptables命令的-m选项来指定调用哪个模块)


隐式扩展:当使用-p {tcp|udp|icmp}中的一种时,可以直接使用扩展专用选项;

-p tcp:

  --sport PORT[-PORT]: 指定源端口

  --dport PORT[-PORT]: 指定目标端口

  --tcp-flags

 要检查标志位列表(用逗号分隔)  必须为1的标志位列表(逗号分隔)

  --syn

-p udp:

 --sport 

 --dport

-p icmp [-m icmp]

 --icmp-type

  0: echo-reply, ping响应

  8: echo-request, ping请求


显式扩展:必须明确说明使用哪个模块进行扩展,而后才能使用其扩展专用选项;

-m 扩展模块名称


multiport: 多端口匹配

可用于匹配非连续或连续端口;最多指定15个端口;


专用选项:

--source-ports, --sports port[,port,port:port]

--destination-ports, --dports

--ports

例子:开放22,80端口

# iptables -I INPUT -d 172.16.100.7 -p tcp -m multiport --dports 22,80 -j ACCEPT
# iptables -I OUTPUT -s 172.16.100.7 -p tcp -m multiport --sports 22,80 -j ACCEPT


iprange: 匹配指定范围内的地址;

匹配一段连续的地址而非整个网络时有用;

专用选项:

[!] --src-ragne IP[-IP]

[!] --dst-range

例子:限定一段连续地址可以通过telnet连接。

# iptables -A INPUT -d 172.16.100.7 -p tcp --dport 23 -m iprange --src-range 172.16.100.1-172.16.100.100 -j ACCEPT
# iptables -A OUTPUT -s 172.16.100.7 -p tcp --sport 23 -m iprange --dst-range 172.16.100.1-172.16.100.100 -j ACCEPT


string: 字符串匹配,能够检测报文应用层中的字符串

专用选项:

--algo {kmp|bm}  2种不同的算法,选一种

--string "STRING"      STRING为你想要匹配的字符串

--hex-string "HEX_STRING": HEX_STRING为编码成16进制格式的字串;

例子:

# iptables -I OUTPUT -m string --algo kmp --string "sex" -j DROP


time: 基于时间做访问控制

专用选项:

--datestart YYYY[-MM][-DD[Thh[:mm[:ss]]]]

--datestop 


--timestart hh:mm[:ss]

--timestop hh:mm[:ss]


--weekdays day[,day]

Mon, Tue,.....     中间用逗号隔开 

例子:

# iptables -I INPUT -d 172.16.100.7 -p tcp --dport 80 -m time --timestart 08:20 --timestop 18:40 --weekdays Mon,Tue  -j ACCEPT


connlimit: 连接数限制,对每IP所能够发起并发连接数做限制

专用选项:

[!] --connlimit-above [n] 


例子:限制同一IP ssh远程连接数。

#iptables -A INPUT -d 172.16.100.7 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j DROP


limit: 速率限制

专用选项:

--limit n[/second|/minute|/hour|/day]

--limit-burst n  

例子:限制每分钟只能ping20次

# iptables -A INPUT -d 172.16.100.7 -p icmp --icmp-type 8 -m limit --limit 20/minute --limit-burst 5 -j ACCEPT


state: 状态检查

专用选项:

--state 


连接追踪中的状态:

NEW: 新建立一个会话

ESTABLISHED:已建立的连接

RELATED: 有关联关系的连接

INVALID: 无法识别的连接

例子:放行所有已建立连接的数据包。

[root@localhost ~]# iptables -A OUTPUT -m state --state ESTABLISHED -j ACCEPT


处理目标:

1、DROP :  丢弃

2、REJECT: 拒绝

3、ACCEPT: 放行

4、自定义的链 :   根据自定义链中的规则进行匹配

    创建自定义链

iptables [-t table] -N chain

    删除自定义且0引用的空链

iptables [-t table] -X chain

    重命名自定义链:

iptables [-t table] -E old_name new_name

5、DNAT:明确申明要做的是目的地地址转换操作   

6、SNAT:明确申明要做的是源地址转换操作

7、REDIRECT:重定向:主要用于实现端口重定向

8、MARK:打防火墙标记的

9、RETURN:在自义链中无法匹配报文时,将其返回主链

   

调整连接追踪功能所能容纳的连接的最大数目:

/proc/sys/net/nf_conntrack_max

   当前追踪的所有连接

/proc/net/nf_conntrack

   不同协议或连接类型追踪时的属性:

/proc/sys/net/netfilter目录:

  

下面我们以ftp服务为例:

 放行被动模式下的FTP服务:

1、装载模块/lib/modules/KERNEL_VERSION/kernel/net/netfilter/

模块:nf_conntrack_ftp

          装载命令:modprobe nf_conntrack_ftp

          卸载:modprobe -r nf_conntrack_ftp

2、放行请求报文

         (1) 放行NEW状态对21端口请求的报文;

[root@localhost ~]# iptables -A INPUT -d 172.16.106.1 -p tcp --dport 21 -m state --NEW -j ACCEPT

(2) 放行ESTABLISHED以及RELATED状态的报文

[root@localhost ~]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

3、放行响应报文

放行ESTABLISHED以及RELATED状态的报文

[root@localhost ~]# iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

这样FTP服务就可以运行了。


iptables的路由转发功能

所谓的转发功能就是启用forward功能,并且结合地址转换功能,使得2个属于不同网络的主机或者服务器之间可以进行连接通信。(这里默认INPUT,OUTPUT链的策略为drop)

首先必须在配置文件中将路由转发功能开启:

#vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
#sysctl -p   重读配置文件

上面的启用之后就可以通过iptables命令来进行添加规则了。

下面我们通过下图来解释一下转发时的地址转换原理。


SNAT

wKiom1P0TWXAqqkbAAEhyrbZvJE837.jpg


假设中间的网关主机为B:由2个地址,一个是内网地址172.16.0.1,一个外网地址192.168.1.1
当私网中的主机A想访问公网中的WEB主机时,由于不能直接访问,于是A就通过网关主机的路由发送请求,

假设不进行地址转换,则网关主机允许路由转发,于是请求到达了web主机,然而当web收到请求后,于是返回响应报文,但是WEB发现该请求的源地址是一个私网地址,因此WEB无法将响应报文送回到网关主机B;

因此在网关主机B中必须进行地址转换,在报文将要离开主机B的之前将源地址改为1.1.1.1(注意:在转换完成之后,主机B会自动生成一张表,记录了内网中的那个主机发起哪个请求,因此当该请求的响应报文从远程主机返回之后,主机B会自动根据该表将响应报文中的IP地址改为请求主机的IP),然后再将报文发送给WEB;当WEB收到报文后做出响应,发出响应报文,源地址为2.2.2.2,目标地址问1.1.1.1,因此响应报文发送给了主机B,经过地址转换之后,主机B又将响应报文送回给A,这样才完成了整个通信过程。

由于上述完成的是一个SNAT的过程,即在请求的过程中目标地址始终没变,变的只是源地址,因此在写规则是,写在POSTROUTING链中:

#iptables -t nat -A POSTROUTING -s 172.16.6.2   -j SNAT --to-source 1.1.1.1


DNAT

如果是一个DNAT的过程的话,写规则时的链就不同,应该写在PREROUTING链中:

该过程就可以看成是公网中的主机C来访问B中的web的服务,然而B只是一台代理服务器,它的web服务是他内网中的www服务器提供的,如下图。

wKiom1P0VbmCHrM2AAEu2ifj3yw920.jpg

根据C发出的请求报文应该是,源地址为2.2.2.2,目标地址为1.1.1.1,而到了B主机之后呢?他收到请求之后发现目标地址为自己,然而他请求的是web服务,应该将请求的目标地址改为WWW主机的IP(172.16.6.2),那么在哪个地方改呢?对,他只能在路由决策之前修改,不然的话请求就送给B主机本身处理了,而非转发给内网中的WWW主机。因此,该规则只能在PREROUTING链中写,IP修改完之后才能进行转发(当然和上面一样,修改完之后也会生成一张表,记录相关信息,当该请求的响应返回时,主机B将会自动根据该表将响应报文中的源IP地址改为1.1.1.1),然后再将报文发送给WWW,WWW收到请求后返回响应报文,源地址为172.16.6.2,目标地址为2.2.2.2,当B收到报文后自动将源地址改为1.1.1.1,然后再返回给C主机。这样通信过程才算完成了。

命令:

#iptables -t nat -A PREROUTING -d 1.1.1.1   -j DNAT --to-destination 172.16.6.2

   本节相关的内容就讲到这里,欢迎大家一起交流,讲的不好不对的请批评指正,谢谢!

你可能感兴趣的:(iptables,NAT)