本节我们来讲一讲防火墙的知识。所谓防火墙指的是一个由软件和硬件设备组合而成、在内部网和外部网之间、专用网与公共网之间的界面上构造的保护屏障.是一种获取安全性方法的形象说法,它是一种计算机硬件和软件的结合,使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:路由后
而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由流向决定;
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: 显示规则编号
查看后得到的
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
假设中间的网关主机为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服务器提供的,如下图。
根据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
本节相关的内容就讲到这里,欢迎大家一起交流,讲的不好不对的请批评指正,谢谢!