防火墙分类:
1:网络防火墙:整个网络的报文入口,出口
2:主机防火墙:单台主机的报文入口,出口
(二)
防火墙入门
前言:
什么是Netfilter
1:Netfilter是Linux
2.4.x引入的一个子系统,可以简单的将其看做内核的一个特殊的功能模块,它作为一个通用的、抽象的框架,提供一整套的hook函数的管理机制,使得诸如数据包过滤、网络地址转换(NAT)和基于协议类型的连接跟踪成为了可能。
2:netfilter的架构就是在整个网络流程的若干位置放置了一些检测点(HOOK),而在每个检测点上登记了一些处理函数进行处理。
3:netfilter的hooks 有
5个,任何报文进入主机必须经过一个钩子函数或多个钩子
刚刚到达本机,没有经过路由的:prerouting
路由完毕之后,要到达本机内部的:input
经由本机转发的,不到本机内部的:forward
由本机内部发出的:output
即将由本机发出的:postrouting
什么是iptables
1:iptables就是在各个钩子上定义的规则,让每一个钩子在处理报文的时候,有不同的处理规则
2:iptables对于运维工程师而言,只是一个写规则的命令行工具
报文进入主机之后,流经的路径
1:流入本机:prerouting –> input –> 用户空间请求报文
2:流出本机:用户空间响应报文 –> output –> postrouting
3:由本机转发的:prerouting –> forward –> postrouting
防火墙规则的分类
(也可以称之为功能表的分类)
1:filter:实现过滤,防火墙(默认)
2:mangle:将报文拆解,修改之后再封包
3:nat:网络地址转换,只拆解修改其地址的那一部分,一般是IP层地址和传输层地址
4:raw:关闭在nat表上启用的连接追踪机制
防火墙链分类
1:内置链 (与netfilter的hooks函数一一对应,每一个内置链对应于一个hooks函数,在内核中直接实现)
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
2:自定义链
对内置链进行扩充的,而定义在自定义链上的规则只有通过内置链的调用才能实现,可以实现更加灵活的规则管理机制
防火墙功能表与防火墙内置链的对应关系
(这里的表就是指下面的四种功能)
1:filter:
INPUT , FORWARD ,
OUTPUT
2:mangle:PREROUTING ,
INPUT , FORWARD ,
OUTPUT , POSTROUTING
3:nat:PREROUTING ,
INPUT,
OUTPUT , POSTROUTING
4:raw:PREROUTING ,
OUTPUT
数据包过滤匹配流程
当报文从一个网络到达本地主机的网卡的时候,以及通过本地网卡需要发送出去的时候,会经过这么几个链
所有的报文到达网卡首先经过的是PREROUTING ,PREROUTING 而对应的会有三种功能,分别是 raw,mangle,nat(从上到下)。经过这三个功能之后,由路由进行选择,要么到达本机内部,要么经过本机转发,如果到达本机内部会到达
INPUT,而
INPUT只能实现两种功能,mangle,filter。如果是经过本机转发的,会到达FORWARD,两种功能,mangle,filter。如果是由本机内部发出,会到达
OUTPUT,四种功能,raw, mangle , nat, filter 。再通过路由选择出去到达
OUTPUT,两种功能mangle, nat 。但是每一个链上的规则可能只有一个或两个
防火墙规则
组成部分:根据规则的匹配条件匹配报文,对应匹配到的报文使用定义的处理动作进行处理匹配条件:基本匹配扩展匹配处理动作:基本的常见的处理动作扩展处理动作自定义处理动作
(三)
TCP三次握手与四次断开
(了解)
前言:
TCP 首部
IP 首部
三次握手和四次断开
三次握手:
1、Client端向服务端发送连接请求报文,
2、Server端接受请求后回复ACK报文,并为这次连接分配资源。
3、Client端接收到ACK报文后也向Server端发送ACK报文,并分配资源,这样TCP连接就建立了,完成三次握手,客户端与服务器开始传送数据。
- 第一次握手:建立连接。客户端发送连接请求报文段,将
SYN
位置为1,Sequence Number
为x;然后,客户端进入SYN_SEND
状态,等待服务器的确认; - 第二次握手:服务器收到
SYN
报文段。服务器收到客户端的SYN
报文段,需要对这个SYN
报文段进行确认,设置Acknowledgment Number
为x+1(Sequence Number
+1);同时,自己自己还要发送SYN
请求信息,将SYN
位置为1,Sequence Number
为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK
报文段)中,一并发送给客户端,此时服务器进入SYN_RECV
状态; - 第三次握手:客户端收到服务器的
SYN+ACK
报文段。然后将Acknowledgment Number
设置为y+1,向服务器发送ACK
报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED
状态,完成TCP三次握手
四次挥手
(1) TCP客户端发送一个FIN,用来关闭客户到服务器的
数据传送。
(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个FIN给客户端。
(4) 客户端发回ACK
报文确认,并将确认序号设置为收到序号加1。
第一次挥手
:主机1向主机2,发送FIN报文段,表示关闭数据传送,并主机1进入FIN_WAIT_1状态,表示没有数据要传输了
第二次挥手 :主机2收到FIN报文段后进入CLOSE_WAIT状态(被动关闭),然后发送ACK确认,表示同意你关闭请求了,主机到主机的数据链路关闭,主机进入FIN_WAIT_2状态
第三次挥手 :主机2等待主机1发送完数据,发送FIN到主机1请求关闭,主机2进入LAST_ACK状态
第四次挥手:主机1收到主机2发送的FIN后,回复ACK确认到主机2,主机1进入TIME_WAIT状态。主机2收到主机1的ACK后就关闭连接了,状态为CLOSED。主机1等待2MSL,仍然没有收到主机2的回复,说明主机2已经正常关闭了,主机1关闭连接。
第二次挥手 :主机2收到FIN报文段后进入CLOSE_WAIT状态(被动关闭),然后发送ACK确认,表示同意你关闭请求了,主机到主机的数据链路关闭,主机进入FIN_WAIT_2状态
第三次挥手 :主机2等待主机1发送完数据,发送FIN到主机1请求关闭,主机2进入LAST_ACK状态
第四次挥手:主机1收到主机2发送的FIN后,回复ACK确认到主机2,主机1进入TIME_WAIT状态。主机2收到主机1的ACK后就关闭连接了,状态为CLOSED。主机1等待2MSL,仍然没有收到主机2的回复,说明主机2已经正常关闭了,主机1关闭连接。
(四)
iptables 工具的使用详解
(掌握)
试验建议:关闭CentOS 7 或 CentOS 6的防火墙 (systemctl stop firewalld ; systemctl disable firewalld 或 service iptables stop ; chkconfig iptables off)
# 在表的对应链上添加规则
iptables [-t
table] {-A|-C|-D} chain
rule-specification
# ipv6
ip6tables [-t
table] {-A|-C|-D} chain
rule-specification
# 在链中插入规则
iptables [-t
table] -I
chain [rulenum] rule-specification
# 修改对应链的规则
iptables [-t
table] -R
chain rulenum rule-specification
# 删除对应链上的规则
iptables [-t
table] -D
chain rulenum
# 显示链上的规则
iptables [-t
table] -S
[chain [rulenum]]
# 将链上的规则全部清除
iptables [-t
table] {-F|-L|-Z} [chain
[rulenum]] [options...]
# 增加一条自定义链
iptables [-t
table] -N
chain
# 删除一条自定义链
iptables [-t
table] -X
[chain]
# 修改链上的默认策略
iptables [-t
table] -P
chain target
# 重命名自定义链
iptables [-t
table] -E
old-chain-name new-chain-name
# 规则的格式
rule-specification = [matches...] [target]
# 匹配的格式
match = -m matchname [per-match-options]
# 处理的格式
target = -j targetname [per-target-options]
iptables命令格式
# -t 指定功能表,SUBCOMMAND其实就是各种选项,作用在哪一条链上 matches表示匹配规则,target表示处理的动作
iptables
[-t table] SUBCOMMAND chain
[matches...]
[ -j target]
将iptables命令逐一拆解分析
1:-t table 指定功能表功能表有:raw , mangle , nat , filter,如果不指定,默认就是filter2:SUBCOMMAND:指定在对应链上的增、删、改、查(1)查看规则-L:表示列出功能表对应链上的所有的规则-n:以数字格式显示地址和端口,如果不加n选项,会反解主机名和端口对应的服务名-v:显示详细格式-x:显示计数器的精确值,每一条规则都有两类计数器,一类用于显示被匹配到的报文的个数,一类用于显示size--line-numbers:显示链上的规则编号(2)规则管理-A :表示append 追加,默认为最后一个-I: 表示insert插入,默认为第一个-D:delete,删除1:rule specification2: rule number-R: replace, 替换-F:flush, 清刷链上的规则-Z:zero,置0-S:显示指定链的所有的规则,以iptables-save命令的格式显示iptables的每一条规则有两类计数器(1)由本规则匹配到的所有的packets(2)由本规则匹配到的所有的bytes(3)链管理-N :新增一条自定义链-X:删除自定义的空链-E:rename,重命名自定义链的未被引用的链(引用计数器为0)例如:iptables -N uplooking例如:iptables -E uplooking mychain例如:iptables -P FORWARD DROP(4)默认策略管理-P:设置默认策略ACCEPT:接受DROP:丢弃REJECT:拒绝例如:iptables -P FORWARD DROP例如:iptables -P INPUT DROP
示例
例如:iptables -vnL --
line-numbers 查看filter表作用的链
例如:iptables -t nat -
nL查看nat表对应的链
例如:iptables -
N uplooking 增加一个自定义链
例如:iptables -
E uplooking mychain 将自定义链 uplooking 改名为 mychain
例如:iptables -X mychain 删除自定义链,注意只有是空的链才能删除
例如:iptables -P FORWARD
DROP 将FARWARD链的默认策略改为
DROP
例如:iptables -P
INPUT
DROP 将
INPUT的默认链改为
DROP,这样的话,报文无法进入内核,不能被用户空间的服务接受,如ssh协议无法实现,远程无法连接
match匹配条件
(实操第一部分:基本匹配)(非常重要)
1:基本匹配:
netfilter的
hooks函数自带的匹配机制
[!]
-s,
--source
address
[/mask]
[,...]: 原地址匹配, ! 表示取反,表示不被匹配之意
[!]
-d,
--destination
address
[/mask]
[,...] :目标地址匹配,! 表示取反,表示不被匹配之意
[!]
-i,
--in-interface
name:限制报文流入的接口匹配(入栈报文),只能由于:
PREROUTING,
INPUT,
FORWARD
[!]
-o,
--out-interface
name:限制报文流出的接口匹配(出栈报文),只能由于:
OUTPUT,
POSTROUTING,
FORWARD
例如:
iptables
-A
INPUT
-s 192
.168
.10
.223
-d 192
.168
.10
.222
-j
DROP 在
INPUT链中添加一个规则,使得192
.168
.10
.223的报文丢弃
例如:
iptables
-A
INPUT
-s 192
.168
.10
.223
-d 192
.168
.10
.222
-j
ACCEPT 将192
.168
.10
.223的报文接受,但是如果对于一个
IP的规则只能做出一个动作,如果想重新设置需要将规则清空,使用
iptables
-F
match匹配条件
(实操第二部分:隐式扩展匹配)(非常重要)
2:扩展匹配:扩展模块匹配引入的匹配机制,-m matchname
隐式扩展:可以不使用-m选项专门的加载相应的模块,但是要加-p选项,指明使用哪种协议
[!] -p {tcp|udp|icmp|icmpv6|esp|ah|sctp|mh|all}:限制协议,就不需要用-m指定加载的扩展模块
例如:iptables -A INPUT -s
192.168.10.223 -d
192.168.10.222 -p tcp -j ACCEPT 表明如果是tcp协议的放行
① tcp:隐含了-m tcp。 有专用选项
[!] --source-port,--sport port
[:port]:匹配报文中的TCP首部的源端口,可以是端口范围
[!] --destination-port,--dport port
[:port]:匹配报文中的TCP首部的目标端口,可以是端口范围
[!] --tcp-flags mask comp: 检查报文中的指明mask的TCP标志位,要这些标志位中comp必须为
1,了解即可
[!] --syn:相当于--tcp-flags syn,fin,ack,rst syn,匹配三次握手的第一次,了解即可
例如: --tcp-flags syn,fin,ack,rst syn:指明这四个标志位中的syn必须为
1,而其他的为
0,也就是TCP的第一次握手
例如:--tcp-flags syn,fin,ack,rst syn,fin:就是四次断开中的第一次
示例
1:指明开放tcp协议的
80端口,也就是web服务
iptables -A INPUT -s
0/
0 -d
192.168.10.222 -p tcp --dport
80 -j ACCEPT
iptables -A OUTPUT -s
192.168.10.222 -d
0/
0 -p tcp --sport
80 -j ACCEPT
示例
2:指明开放TCP的
22端口,也就是ssh服务
iptables -A INPUT -s
0/
0 -d
192.168.10.222 -p tcp --dport
22 -j ACCEPT
iptables -A OUTPUT -s
192.168.10.222 -d
0/
0 -p tcp --sport
22 -j ACCEPT
② udp:隐含了-m udp。有专用选项
[!] --source-port,--sport port
[:port] :匹配报文中的udp首部的源端口,可以是端口范围
[!] --destination-port,--dport port
[:port]:匹配报文中的udp首部的目标端口,可以是端口范围
③ icmp:隐含指明了”-m icmp”。有专用选项
[!] --icmp-type {type
[/code]|typename}
type/code有两种类型:
0/
0 :echo reply 指明应答的类型
8/
0:echo request 指明请求的类型
示例
1:开放别人可以ping自己
iptables -A INPUT -d
192.168.10.222 -p icmp --icmp-type
8 -j ACCEPT
iptables -A OUTPUT -s
192.168.10.222 -p icmp --icmp-type
0 -j ACCEPT
示例
2:开放自己可以ping别人
iptables -A INPUT -d
192.168.10.222 -p icmp --icmp-type
0 -j ACCEPT
iptables -A OUTPUT -s
192.168.10.222 -p icmp --icmp-type
8 -j ACCEPT
match匹配条件
(实操第三部分:显示扩展匹配)(非常重要)
显示扩展:必须使用-m加载扩展模块
1:multiport :多端口匹配,离散的方式定义的多端口匹配,最多可以指定
15个端口
[!] --source-ports,--sports port[,port|,port:port]...:指定源端口
[!] --destination-ports,--dports port[,port|,port:port]...:指定目标端口
[!] --ports port[,port|,port:port]...:可以指定源端口和目标端口
例如:同时开放
22和
80端口
iptables -I INPUT -s
0/
0 -d
192.168
.10
.222 -p tcp -m multiport --dports
22,
80 -j ACCEPT
iptables -I OUTPUT -s
192.168
.10
.222 -d
0/
0 -p tcp -m multiport --sports
22,
80 -j ACCEPT
2:iprange :指明一段连续的
IP地址范围,作为源地址或目标地址的匹配
[!] --src-range from[-to]:指定源地址范围
[!] --dst-range from[-to]:指定目标地址范围
例如:指定客户端
ip在
192.168
.10
.1-
192.168
.10
.254范围内的才能访问telnet服务
iptables -A INPUT -d
192.168
.10
.222 -p tcp --dport
23 -m iprange --src-range
192.168
.10
.1-
192.168
.10
.254 -j ACCEPT
iptables -A OUTPUT -s
192.168
.10
.222 -p tcp --sport
23 -m iprange --dst-range
192.168
.10
.1-
192.168
.10
.254 -j ACCEPT
3:string:对报文中的应用层数据做字符串匹配检测
--algo {bm|kmp}
[!] --string pattern :给定要检查的字符串模式
[!] --hex-string pattern:给定要检查的字符串模式,十六进制编码
例如:只要页面中包含admin的页面都不能访问
iptables -I OUTPUT -s
192.168
.10
.222 -d
0/
0 -p tcp --sport
80 -m string --algo bm --string
"admin" -j REJECT
4:time:收到报文的时间/日期与指定到的时间/日期做匹配
--datestart YYYY[-MM[-
DD[Thh[:mm[:
ss]]]]]:起始日期时间
--datestop YYYY[-MM[-
DD[Thh[:mm[:
ss]]]]]:结束日期时间
--timestart hh:mm[:
ss]:以天为单位的起始时间
--timestop hh:mm[:
ss]:以天为单位的起始时间
[!] --monthdays day[,day...]:匹配一个月中的哪天
[!] --weekdays day[,day...]:匹配一个周中的哪天
例如:指定客户端
IP范围和访问时间才能访问
iptables -I INPUT -d
192.168
.10
.222 -p tcp --dport
23 -m iprange --src-range
192.168
.10
.1-
192.168
.10
.254 -m time --timestart
08:
00:
00 --timestop
018:
00:
00 -j ACCEPT
5:connlimit:根据每个客户端主机做并发并发连接数量限制,就是每个客户端最多发起的连接数量
--connlimit-upto n:连接数量小于等于n,则匹配
--connlimit-above n:连接数量大于n,则匹配
例如:
iptables -A INPUT -s
0/
0 -d
192.168
.10
.222 -p tcp --dport
23 -m connlimit --connlimit-upto
2 -j ACCEPT
iptables -A OUTPUT -s
192.168
.10
.222 -d
0/
0 -p tcp --sport
23 -m connlimit --connlimit-upto
2 -j ACCEPT
6:limit:基于令牌桶算法对报文的速率做匹配。
--limit rate[/second|/minute|/hour|/day] :限制等待的速率, 也就是接受或响应数据包的速率
--limit-burst number:第一次可以有多少个不需要等待的
例如:这里是限制每分钟只能入栈
20个icmp的报文,并且第一次入栈允许
5个不需要等待,后续的报文每次需要等待
2秒
iptables -A INPUT -d
192.168
.10
.222 -p icmp --icmp-type
8 -m limit --limit
30/minute --limit-burst
5 -j ACCEPT
iptables -A OUTPUT -s
192.168
.10
.222 -p icmp --icmp-type
0 -j ACCEPT
7:state:用于对报文状态判断
[!] --state state:匹配报文的状态
INVALID :无法识别的连接
ESTABLISHED:连接追踪模块中存在记录的连接
NEW:连接追踪模板当中不存在的连接请求
RELATED:相关联的连接
UNTRACKED:未追踪的连接
例如
1:允许自己ping别人
iptables -A OUTPUT -s
192.168
.10
.222 -p icmp --icmp-type
8 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -d
192.168
.10
.222 -p icmp --icmp-type
0 -m state --state ESTABLISHED -j ACCEPT
例如
2:允许别人ping自己
iptables -A INPUT -d
192.168
.10
.222 -p icmp --icmp-type
8 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s
192.168
.10
.222 -p icmp --icmp-type
0 -m state --state ESTABLISHED -j ACCEPT
8:对于连接追踪还需了解的知识
已经追踪到的并记录下来的连接保存在 /proc/net/nf_conntrack里面
如果追踪的记录满载了,就会显示连接超时
连接追踪功能所能够记录的最大连接数量保存在 (可调整)/proc/sys/net/nf_conntrack_max
这里可以通过命令调节内核中的参数
sysctl -w net.nf_conntrack_max=
300000 将最大的追踪记录调节到
300000个
conntrack所能追踪的连接数量的最大值取决于/proc/sys/net/nf_conntrack_max的设定,已经追踪的连接位于/proc/net/nf_conntrack文件中,超时的连接会被删除,当模板满载,后续的新连接有可能会超时。解决办法:
(
1)加大nf_conntrack_max的值
(
2)降低nf_conntrack条目的超时时长
不同协议的连接追踪时长定义在/proc/sys/net/netfilter下
target处理动作
(实操第四部分:处理动作)(非常重要)
-j
ACTION [per-
target-options]
ACCETP , DROP , REJECT
RETURN :返回调用的链
REDIRECT:端口重定向
LOG:日志
MARK:防火墙标记
DNAT:目标地址转换
SNAT:原地址转换
MASQUERADE:地址伪装