防火墙在计算机语言中的理解:
工作于主机或者网络边缘,对于进出的报文根据定义的规则做出检查,进而对被规则匹配到的报文作出相应处理的套件。
防火墙和杀毒软件的概念区别:防火墙是在病毒没有进入前做出了规则判断和处理,杀毒软件是对本机内部的病毒进行扫描和处理。这个可以形象的理解为:防火墙是拒人于千里之外,杀毒软件就是瓮中捉鳖。
防火墙的分类:
按照实施的方式分为:
软件防火墙
硬件防火墙
按照应用范围的大小可以分为:
主机防火墙:工作在内核的TCP/IP协议栈的。这是应用于一个单独的主机。
网络防火墙:作用于一个区域的防火墙,对其内部的各主机实现保护作用。
按照TCP/IP七层模型防火墙分为:
网络层防火墙:作用网络层只是通过源地址和目标地址来检查,效率高安全性不够。
应用层网关防火墙:这是对于真实的传输内容,以及源地址目标地址的全部检查。 效果好,效率低。又由于我们网络地址的访问都是通过防火墙控制的接口来访问的,如果效率不高会导致我们的服务器出现堵塞,因此一个防火墙应用的不好,将是访问流量的一个瓶颈。实际上这两种,一般是结合起来一起使用的:网络层防火墙—->应用层网关防火墙—–>目标主机
iptables/netfilter
在防火墙的使用中需要注意的是,我们经常使用的工具iptables,不是防火墙。它只是一个用于防火墙写规则的工具,iptables写好规则之后发给netfilter,之后在内核中立即生效。 那么既然iptables只是一个写规则的工具,那怎么不直接把规则写在netfilter?试想netfilter是在内核中的,如果直接对内核写操作,内核的稳定性就堪忧了。
几个相关名词:IDS、IPC
IDS(Intrusion Detect System) 入侵检测系统
IPS(Intrusion Protect System ) 入侵保护系统
iptables的前身叫ipfirewall,起初它的工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。当内核发展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则。通过将他们组合起来共同实现结果。之后就是现在的iptables它可以将规则组成一个列表,实现详细的访问控制功能。
iptables发展以来都是工作在用户空间中,用于定义规则的工具,本身并不算是防火墙。它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)
iptables的作者在网络必然经过的地方,选取了5个位置,来作为控制的地方。这五个位置也被称为五个钩子函数(hook functions),也叫五个规则链。这五个位置分别是:1.PREROUTING (路由前)2.INPUT (流入) 3.FORWARD (转发关卡) 4.OUTPUT(流出) 5.POSTROUTING(路由后)。很明显在路由前和路由后由于没有经过路由决策不会发生过滤作用的,而且我们的(INPUTFORWORDOUTPUT)已经可以基本是实现路径的全部封锁控制了。那我们为什么还要放置他们呢?这个主要是因为我们在做NAT和DNAT的时候,目标地址转换必须在路由之前转换,这即是他们存在的意义。
防火墙策略一般分为两种:
一种叫“通”策略,一种叫“堵”策略,通策略其实就是白名单,默认端口是关着的,必须要自己指定用户的才能进来。堵策略可以理解是黑名单,规定范围的人不可以进来。那里但是你必须有身份认证,否则不能进。为了让这些功能交替工作,我们制定出了“表”这个定义,来定义、区分各种不同的工作功能和处理方式。
我们现在用的比较多个功能有3个
1.filter 定义过滤条件的
2.nat 定义地址转换的
3.mangle 修改报文原数据
我们修改报文原数据就是来修改TTL(time to live)的。能够实现将数据包的元数据拆开,在里面做标记/修改内容的。而防火墙标记,其实就是靠mangle来实现的。
对于filter来讲一般只能做在3个链上:INPUT ,FORWARD ,OUTPUT
对于nat来讲一般也只能做在3个链上:PREROUTING ,OUTPUT ,POSTROUTING
而mangle则是5个链都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
iptables/netfilter 是工作在用户空间的,它可以让规则进行生效的,本身不是一种服务,而且规则是立即生效的。而我们iptables现在被做成了一个服务,可以进行启动,停止的。启动,表示规则直接生效。停止,将规则撤销。
iptables还支持自己定义链。但是自己定义的链,需要经过主链的跳转。当有数据处理的时候,会到我们定义的链来处理,当那个链处理完之后,再返回主链。接着在特定的链中继续检查。
规则的写法:
iptables定义规则的方式:
格式:iptables [-t table] COMMAND chain CRETIRIA -j ACTION
-t 指定表,这里表可以省略,如果省略默认是filter。
COMMAND:定义如何对规则进行管理:比如增加,插入,删除等
chain:指定你接下来的规则到底是在哪个链上操作的{INPUT|OUPUT…}
CRETIRIA:指定匹配标准(对什么服务?什么端口?)
-j ACTION :指定如何进行处理{ACCEPT|DROP|REJECT}
比如:不允许172.16.0.0/16的进行访问。
iptables -A INPUT -s 172.16.0.0/16 -p udp –dport 53 -j DROP
iptables -L -n -v #查看定义规则的详细信息
注意:规则的次序非常关键,谁的规则越严格,应该放的越靠前,而检查规则的时候,是按照从上往下的方式进行检查的。
-P :设置默认策略的(设定默认门是关着的还是开着的)
默认策略一般只有两种
iptables -P INPUT (DROP|ACCEPT) 默认是关的/默认是开的
比如:
iptables -P INPUT DROP 这就把默认规则给拒绝了。并且没有定义哪个动作,所以关于外界连接的所有规则包括Xshell连接之类的,远程连接都被拒绝了。
-F: FLASH,清空规则链的(注意每个链的管理权限)
iptables -t nat -F PREROUTING 清空路有前链
iptables -t nat -F 清空nat表的所有链
-N:NEW 支持用户新建一个链
iptables -N inbound_tcp_web 表示附在tcp表上用于检查web的。
-X: 用于删除用户自定义的空链
使用方法跟-N相同,但是在删除之前必须要将里面的链给清空了
-E:用来Rename chain主要是用来给用户自定义的链重命名
-E oldname newname
-Z:清空链,及链中默认规则的计数器的(有两个计数器,被匹配到多少个数据包,多少个字节)
-A:追加,在当前链的最后新增一个规则
-I num : 插入,把当前规则插入为第几条。例如:-I 3 :插入为第三条
-R num:Replays替换/修改第几条规则 格式:iptables -R 3 …………
-D num:删除,明确指定删除第几条规则
-L 后面可以有很多子命令:
-n:以数字的方式显示,如果不加-n,则会将ip反向解析成主机名。
-v:显示详细信息
-vvv :v 越多越详细
-x:在计数器上显示精确值,不做单位换算。
–line-numbers : 显示规则的行号
-t nat:显示所有的关卡的信息
-s:指定作为源地址匹配,后面跟的必须是IP,加一个“!”地址可以取反,表示此IP之外。
-d:表示匹配目标地址
-p:用于匹配协议的(这里的协议通常有3种,TCP/UDP/ICMP)
-i eth#:从这那块网卡流入的数据,流入一般用在INPUT和PREROUTING上
-o eth#:从这块网卡流出的数据, 流出一般在OUTPUT和POSTROUTING上
-p tcp :TCP协议的扩展。一般有三种扩展
–dport:指定目标端口 , –dport 21
–sport:指定源端口
–tcp-fiags:TCP的标志位(SYN,ACK,FIN,PSH,RST,URG)
–tcpflags syn,ack,fin,rst syn (syn,ack,fin,rst)表示检查这4个位,这4个位中syn必须为1,其他的必须为0
或者等价于syn,ack,fin,rst syn = –syn
-p udp:UDP协议的扩展
–dport
–sport
-p icmp:icmp数据报文的扩展
–icmp-type:
echo-request(请求回显),一般用8 来表示
所以 –icmp-type 8 匹配请求回显数据包
echo-reply (响应的数据包)一般用0来表示
扩展各种模块
multiport:多端口匹配
-m multiport:表示启用多端口扩展
–dports 21,23,80 表示启用这多个端口。
–ports :表示不分辨目标端口和源端口启用。
port如果是多个,逗号分隔,表示端口是离散的,22,80。如果是冒号分隔,表示连续的 22:23
另外如果 在选项前面加! 还可以取反。这种情况可是使用在多个模块中
iprange:匹配指定范围内的地址
–src-range ip1-ip2表示这两个源IP之间的范围。
–dst-range ip1-ip2表示这里俩个目标IP之间的范围。
例如:iptables -A INPUT -d 172.16.100.10 -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.10 -p tcp –sport 23 -m iprange –drc-range 172.16.100.1-172.16.100.100 -j ACCEPT
String:字符串匹配
能够检测报文应用层中的字符串。能够起到指定字符无法访问的方式。
字符匹配检查使用的高效算法:
kmp ,bm
专用选项:
–algo {kmp|bm} 这里的两个算法随机选择一个,为了字符查找时候,能实现高效查找的。
–string “STRING” 指定要匹配的字符,但是这种匹配效率比较低,建议使用16进制的转换,也就是下面的这种写法:两种指定方式任选其一。
–hex-string “HEX_STRING”:HEX_STRING
限制固定字眼的访问,比如我们要限制对于网页的特殊字眼的访问。规则要写在web规则的前面,不然因为优先级无法生效。
Time :基于时间做访问控制
专用选项 -m time
–timestart hh:mm[:ss]指定限制的起始时间
–timestop hh:mm[:ss]指定限制的末尾时间
–weekdays Mon .Tue….限制的周几
例如:iptables -I INPUT -d 172.16.100.7 -p tcp –dport 80 -m time –timestart 08:20 –timestop 17:30 –weekdays Mon,Tue,Wen,Thu,Fri -j REJECT
Limit:用于速率限制,防止一个某个单独的占用宽带。
按照指定的速率发放通行证。有同通行证,就可以发放报文。但是对于长期没有发放报文的,允许将通行证放置于令牌桶中积累闲置个数。
专用选项-m limit
–limit n [/second|/minute/|/hour|/day] 限制多久传送一次报文
–limit-burst 允许的空闲令牌个数
例如:iptables -A INPUT -d 172.16.100.7 -p icmp –icmp-type 8 -m limit –limit 20/minute –limit-burst 5 -j ACCEPT
State:状态检查
启用了链接追踪功能,就是当一个客户端在连接时,会被记录在自己的连接会话表中。下次一旦连接会识别这个客户端来过。就会给予放行。
这种链接追中有四种状态:
NEW:第一次过来,还未建立链接 在三次握手的第一个阶段。
ESTABLISHED:已建立的链接 在三次握手的第二三阶段。
RELATED:有关联关系的链接 这个体现在FTP 20和21端口,比如:链接我们21端口的链接,可以使用我们的20这个端口发送数据。
INVALID:无法链接 例如:链接状态是syn=1 ,ack=1 ,rst=1 ,这种状态是无法识别的。就是INVALID状态。
例如:iptables -A INPUT -d 172.16.100.7 -p tcp -m multiport –dports 22,80 -m start –state NEW -j ACCEPT
iptables -I INPUT -d 172.16.100.7 -m start –state ESTABLISHED -j ACCEPT
iptables -I OUTPUT -s 172.16.100.7 -m state –state ESTABLISHED -j ACCEPT
iptables -P OUTPUT DROP
状态检测的意义:为了防止反弹木马,在自己的服务器建立反弹控制。因此我们设置状态控制,只对进来的那个客户端,做出响应。使用上,ESTABLED 建立在NEW之前。
-j ACTION
常用的ACTION:
DROP:委婉的拒绝,一般我们多用DROP来隐藏我们的身份,以及隐藏我们的链表。
REJECT:明示拒绝
ACCEPT:接受
custom_chain:转向一个自定义的链
DNAT
SNAT
MASQUERADE:源地址伪装
REDIRECT:重定向:主要用于实现端口重定向
MARK:打防火墙标记的
RETURN:返回。在自定义链执行完毕后使用返回,来返回原规则链。
SNAT基于源地址转换
这种模型就是将自己一方作为客户端而且是认为是私网地址,需要通过一个公网接口去访问外部网站。这是就需要一个源地址转换了。
源地址转换定义的样式:
比如我们现在要将所有192.168.10.0网段的IP在经过的时候全都转换成172.16.100.7这个假设出来的外网地址:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT –to-source 172.16.100.7
这样,只要是来自本地网络的试图通过网卡访问网络的,都会被统统转换成172.16.100.1这个IP.但是有时候我们的上网往往是拨号上网,IP地址是不固定的。这时我们就要将外网地址换成 MASQUERADE(动态伪装):它可以实现自动寻找到外网地址,而自动将其改为正确的外网地址。所以,我们就需要这样设置:
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
这里要注意:此处没有省略-t
DNAT基于源地址转换
对于目标地址转换,外面的是客户端,我们自己的一方是服务器端,外面的ip通过我们对外的外网ip来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上。这样也就是伪装了我们的服务器。
目标地址转换的格式:
iptables -t nat -A PREROUTING -d 192.168.10.2 -p tcp –dport 80 -j DNAT –todestination 172.16.100.7
因为定义的所有内容是立即生效而且是临时的,当重启的时候都会失效,要想我们能够下次开机生效,需要使用一个命令将它保存起来
service iptables save
它会保存在/etc/sysconfig/iptables这个文件中
iptables-save
iptables-save > /etc/sysconfig/iptables
iptables-restore
开机的时候,它会自动加载/etc/sysconfig/iptabels
如果开机不能加载或者没有加载,而你想让一个自己写的配置文件手动生效的话:
iptables-restore < /etc/sysconfig/iptables.test
则完成了将iptables中定义的规则手动生效