firewall: 工作于主机或网络的边缘,对于进出的报文根据事先定义的规则作检查,将那些能够被规则所匹配到的报文作出相应处理的组件。
防火墙可分为:
主机防火墙
网络防火墙
专业的硬件防火墙:
checkpoint,netscreen
iptables: 程序
iptables:规则编写工具
netfilter: 网络过滤器, 内核中工作在TCP/IP网络协议栈上的框架;
hooks function(钩子函数):
prerouting: 进入本机后路由功能发生之前
input:到达本机内部
output: 由本机发出
forward: 由本机转发
postrouting:路由功能发生之后,即将离开本机之前
路由发生的时刻:
报文进入本机后:
判断目标地址
报文离开本机之前:
判断经由哪个接口发出;
报文流向经由的位置:
到本内部:prerouting, input
由本机发出:output, postrouting
由本机转发:prerouting, forward,postrouing
规则的功能:
过滤:firewall,
地址转换:NAT Server
Network Address Translation
mangle:修改报文首部中的某些信息
raw:关闭nat表上启用的连接追踪功能
iptables:每个钩子函数上可放置n条规则;对应于每个钩子上的多条规则就称为一个链(CHAIN)
每个功能有多个链,所以,就称作表;
iptables有四表五链:
四表:filter,nat,mangle,raw
五链:prerouting,input,forward,output,postrouting
每个表一般都只能定义在该存在的链上:
filter:input,forward, output
nat:prerouting,output, postrouting
mangle:prerouting,input, forward, output, postrouting
raw:prerouting,output
链:链上的规则次序即为检查次序,因此有一定的法则
(1) 同类规则,匹配范围小的放上面;
(2) 不同类规则,匹配报文几率较大的放上面;
(3) 应该设置默认策略;
添加规则时的考量点:
(1) 要实现的功能:判断添加在哪个表上;
(2) 报文流向及经由路径:判断添加在哪个链上;
功能的优先级:
由高而低:
raw --> mangle --> nat --> filter
规则的组成部分:
报文的匹配条件, 匹配之后如何处理
匹配条件:基本匹配条件、扩展匹配条件
如何处理:内建处理机制、自定义处理机制(自定义的链)
注意:报文不可能经由自定义链,只有在被内置链上的引用才能生效(即做为自定义目标)
iptables:规则管理工具
自动实现规则的语法检查
规则和链有计数器:
pkts: 由规则或链匹配到的报文的个数;
bytes:由规则或链匹配到的所有报文大小之和;
链:应该有默认策略;
iptables命令生成规则,送往netfilter;
规则通过内核接口直接送至内核,因此,会立即生效。但不会永久有效;
如果期望有永久有效,需要保存至配置文件中,此文件还开机时加载和由用户手工加载;
注意:1.规则的次序非常关键,谁的规则越严格,应该放的越靠前,而检查规则的时候,是按照从上往下的方式进行检查的。
2.经常使用的放在前面,可以省去过多的规则判断对时间的浪费
iptables [-t TABLE] SUBCOMMAND CHAIN CRETERIA -jTARGET
-t TABLE:
默认为filter, 共有filter, nat, mangle,raw四个可用;
例: 显示nat的所有规则
iptables -t nat -L -n -v
显示filter的所有规则
iptables -L -n -v
SUBCOMMAND:
链:
-F:flush,清空指定表的指定链上所有规则;省略链名时,清空表中的所有链;
-N:new, 新建一个用户自定义的链;自定义链只能作为默认链上的跳转对象,即在默认链通过引用来生效自定义链;
-X:drop,删除用户自定义的空链;非空自定义链和内置链无法删除;
-Z:zero,将规则的计数器置0;
-P:policy,设置链的默认处理机制;当所有都无法匹配或有匹配有无法做出有效处理机制时,默认策略即生效;
filter表的可用策略:ACCEPT, DROP, REJECT
-E:rename,重命名自定义链;
注意:被引用中的链,无法删除和改名
例: 清空filter上的INPUT规则
iptables -F INPUT
清空nat上的OUTPUT规则
iptables -t nat -F OUTPUT
规则:
-A:append,在链尾追加一条规则;
-I:insert,在指定位置插入一条规则;
-D:delete,删除指定的规则;
-R:replace,替换指定的规则;
例:替换INPUT第二条规则
iptables -R INPUT 2-s 172.16.37.1 -d 172.16.37.10 -p tcp --dport 22
查看:
-L:list,列出指定链上的所有规则;
-n: numeric,以数字格式显示地址和端口号,即不反解;
-v: verbose,详细格式,显示规则的详细信息,包括规则计数器等;-vv,-vvv
--line-numbers: 显示规则编号;
-x: exactly,显示计数器的精确值;
CRETERIA: 匹配条件
检查IP首部,检查TCP、UDP或ICMP首部;
基于扩展机制,也可以进行额外的检查;如做连接追踪;
注意:可同时指定多个条件,默认多条件要同时被满足;
匹配条件:
通用匹配:
[!] -s, --src, --source IP|Network:检查报文中的源IP地址; ! -s 172.16.100.1表示除了这个IP
-d, --dst, --destination:检查报文中的目标IP地址;
-p, --protocol:检查报文中的协议,即ip首部中的protocols所标识的协议;tcp、udp或icmp三者之一;
-i, --in-interface:数据报文的流入接口;通常只用于PREROUTING, INPUT, FORWARD链上的规则; -i eth0
-o, --out-interface:检查报文的流出接口;通常只用于FORWARD, OUTPUT, POSTROUTING链上的规则;-o eth0
例:本机IP172.16.37.10,仅允许172.16.37.1访问sshd服务,并能效应
# iptables -A INPUT -s 172.16.37.1 -d 172.16.37.10 -p tcp --dport 22 -j ACCEPT
# iptables -A OUTPUT -s 172.16.37.10 -d 172.16.37.1 -p tcp --sport 22 -j ACCEPT
# iptables -P INPUTDROP
# iptables -P OUTPUTDROP
例:本机IP172.16.37.10,允许172.16.37.1访问httpd服务,并能效应
# iptables -A INPUT -s 172.16.37.1 -d 172.16.37.10 -ptcp --dport 80 -j ACCEPT
# iptables -A OUTPUT -s 172.16.37.10 -d 172.16.37.1 -ptcp --sport 80 -j ACCEPT
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
扩展匹配:使用iptables的模块实现扩展性检查机制
隐式扩展:如果在通用匹配上使用-p选项指明了协议的话,则使用-m选项指明对其协议的扩展就变得可有可无了;
tcp:
--dport PORT[-PORT] 目标端口
--sport 来源端口
--tcp-flags LIST1 LIST2
LIST1: 要检查的标志位;
LIST2:在LIST1中出现过的,且必须为1标记位;而余下的则必须为0;
例如:--tcp-flags syn,ack,fin,rst syn
--syn:用于匹配tcp会话三次握手的第一次;
udp:
--sport 目标端口
--dport 来源端口
icmp:
--icmp-types
8:echo request 请求
0:echo reply 回答
例:开放172.16.37.1对本机172.16.37.10的ping响应,和ping请求;注:若默认INPUT/OUPUT为DROP,请求和响应同时开启才能ping通
# iptables -A INPUT -s 172.16.37.1 -d 172.16.37.10 -picmp --icmp-type 8 -j ACCEPT
# iptables -A OUTPUT -s 172.16.37.10 -d 172.16.37.1 -picmp --icmp-type 0 -j ACCEPT
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
显式扩展:必须指明使用的扩展机制;
-m 模块名称
每个模块会引入新的匹配机制;
想知道有哪些模块可用:
rpm-ql iptables
小写字母,以.so结尾;
multiport扩展:以离散定义多端口匹配;最多指定15个端口;
专用选项:
--source-ports, --sports PORT[,PORT,...]
--destination-ports,--dports PORT[,PORT,...]
--portsPORT[,PORT,...]
例:允许172.16.100.11对本机的ssh,http,https访问
iptables -I INPUT 1 -d 172.16.100.11 -p tcp -m multiport --dports 22,80,443 -j ACCEPT
iptables -I OUTPUT 1 -s 172.16.100.11 -p tcp -mmultiport --sports 22,80,443 -j ACCEPT
iprange扩展:指定连续的ip地址范围;在匹配非整个网络地址时使用;
专用选项:
[!] --src-range IP[-IP]
[!] --dst-range IP[-IP]
例:允许172.16.100.1-100对172.16.100.11的telnet23端口访问
iptables -A INPUT -d 172.16.100.11 -p tcp --dport 23 -miprange --src-range172.16.100.1-172.16.100.100 -j ACCEPT
iptables -A OUTPUT -s 172.16.100.11 -p tcp --sport 23-m iprange --dst-range 172.16.100.1-172.16.100.100 -j ACCEPT
string扩展:检查报文中出现的字符串,与给定的字符串作匹配;
字符串匹配检查算法:
kmp,bm
专用选项:
--algo {kmp|bm} :指定算法
--string"STRING":要匹配的字符串,会自动编码
--hex-string"HEX_STRING":HEX_STRING为编码成16进制格式的字串;效率会高
例:检查响应报文中包含sex的字符串,并将其拒绝
iptables -I OUTPUT 1 -s 172.16.100.11 -p tcp --sport80 -m string --string"sex" --algo kmp -j REJECT
time扩展:基于时间区间做访问控制
专用选项:
--datestartYYYY[-MM][-DD][hh[:mm[:ss]]] 开始日期
--dattestop 停止日期
--timestart 开始时间
--timestop 停止时间
--weekdays DAY1[,DAY2,...]
例:在周1,2,4,5的08:30-18:30拒绝172.16.100.11对80端口的访问
iptables -A INPUT -d172.16.100.11 -p tcp --dport 80 -m time --timestart 08:30 --timestop 18:30--weekdays Mon,Tue,Thu,Fri -j REJECT
connlimit扩展:基于连接数作限制;对每个IP能够发起的并发连接数作限制;
专用选项:
--connlimit-above [n] 连接数超过n个
! --connlimit-above[n] 连接不超过n个
例:当连接172.16.100.11的ssh数大于5时[包括5个]拒绝
iptables -I INPUT 2 -d 172.16.100.11 -p tcp --dport 22-m connlimit --connlimit-above 5 -j REJECT
iptables -P INPUT ACCEPT
例:配置本机的telnet服务,要求只允许来自于172.16.0.0/16网络中的主机访问,且只允许工作时间访问,而且,每个来源IP最多的并发连接数不能超过2个;
方法1:iptables -A INPUT -s 172.16.0.0/16-d 172.16.37.10 -p tcp --dport 23 -m time --timestart 01:00 --timestop 20:00 -mconnlimit ! --connlimit-above 2 -j ACCEPT
iptables -P DROP
方法2:先拒绝在允许
iptables -I INPUT 1 -p tcp -dport 23 -m connlimit --connlimit-above 2 -jDROP
iptables -I INPUT 2 -p tcp -dport 23 -j ACCEPT
limit扩展:基于发包速率作限制;
专用选项:令牌桶算法
--limit n[/second|/minit|/hour|/day] 例--limit 10/minit 指明每分钟允许10个数据包
--limit-burst n 峰值为几,即最大突发为几
假设如下的规则:
iptables -A INPUT -p icmp --icmp-type 8-m limit --limit 6/m --limit-burst 5 -j ACCEPT
iptables -P INPUT DROP
然后从另一部主机上ping这部主机,就会发生如下的现象:
首先我们能看到前四个包的回应都非常正常,然后从第五个包开始,我们每10秒能收到一个正常的回应。这是因为我们设定了单位时间(在这里是每分钟)内允许通过的数据包的个数是每分钟6个,也即每10秒钟一个;其次我们又设定了事件触发阀值为5,所以我们的前四个包都是正常的,只是从第五个包开始,限制规则开始生效,故只能每10秒收到一个正常回应。
假设我们停止ping,30秒后又开始ping,这时的现象是:
前两个包是正常的,从第三个包开始丢包,这是因为在这里我的允许一个包通过的周期是10秒,如果在一个周期内系统没有收到符合条件的包,系统的触发值就会恢复1,所以如果我们30秒内没有符合条件的包通过,系统的触发值就会恢复到3,如果5个周期内都没有符合条件的包通过,系统都触发值就会完全恢复。
state扩展:启用连接追踪模板记录连接,并根据连接匹配连接状态的扩展;
启用连接追踪功能之前:简单包过滤防火墙;
启用连接追踪功能:带状态检测的包过滤防火墙;
专用选项:
--state STATE
STATE的种类:
NEW: 新建立的连接,连接追踪模板中无相应的条目时,客户端第一次发出的请求;
ESTABLISHED:NEW状态之后,边距追踪模板中的条目删除之前所进行的通信过程,都称为ESTABLISHED;
RELATED:相关联的连接,如ftp协议的命令连接与数据连接即为相关联的连接;
INVALIED: 无法识别的状态;
例:放行OUTPUT已建立连接的ssh服务
iptables -A OUTPUT -p tcp -sport 22-m --state ESTABLISHED -j ACCEPT
调整连接追踪功能所能容纳的连接的最大数目:
/proc/sys/net/nf_conntrack_max
当前追踪的所有连接:
/proc/net/nf_conntrack
不同协议或连接类型追踪时的时长属性:
/proc/sys/net/netfilter/
如何放行被动模式下的ftp服务:
(1) 装载模块:
#modprobe nf_conntrack_ftp
(2) 放行请求报文
放行入站请求端口为21的请求报文;
放行所有状态为ESTABLISHED和RELATED状态的入站报文;
(3) 放行出站响应报文
放行所有状态为ESTABLISHED的出站报文;
TARGET:
-j: jump,跳转目标
内置目标:
ACCEPT:接受
DROP:丢弃
REJECT:拒绝
SNAT
DNAT
NAT Server: 能根据需要实现所谓的SNAT、DNAT或PNAT;
并非是用户空间运行的进程完成转换功能,靠的是内核中地址转换规则;
SNAT:CIP --> SNAT(PIP) --> SIP
CIP: 本地客户端IP SIP:服务器IP
DNAT: RemoteIP --> DNAT(SIP) --> SIP
RemoteIP:远程客户端地址;
PNAT:端口转换
私有的客户端访问互联网的方法:
(1)SNAT
(2)Proxy
SNAT:主要用于实现让内网客户端访问外部主机时使用;
注意:要定义在POSTROUTING链;也可以在OUTPUT上使用;
定义方法:
iptables -t nat -APOSTROUTING -s 内网网络或主机地址 -j SNAT --to-source NAT服务器上的某外网地址
例:让172.16.0.0/16网络都用192.168.1.1去访问外网
iptables -t nat -APOSTROUTING -s 172.16.0.0/16 -j SNAT --to-source 192.168.1.1
另一个TARGET:
MASQUERADE:地址伪装;能自行判断该转为哪个源地址;但是很消耗资源。
iptables -t nat -APOSTROUTING -s 内网网络或主机地址 -j MASQUERADE
DNAT:主要用于发布内部服务器,让内网中的服务器在外网中可以被访问到;
注意:要定义在PREROUTING链;
iptables -t nat -APREROUTING -d NAT服务器的某外网地址 -p 某协议 --dport 某端口 -j DNAT --to-destination 内网某服务器地址[:PORT]
例:访问172.16.37.10的web服务需经过192.168.1.1
iptables -t nat -APREROUTING -d 192.168.1.1 -p tcp --dport 80 -j DNAT --to-destination172.16.37.10
FULLNAT: 全地址转换
在请求报文到时:既修改源地址,又修改目标地址
NAT实验:
拓扑:
源地址转换:
1.客户机网关设置为191.111
2.启动服务器的web服务,主页注明 is 172.16.36.200
3.现在客户机是ping不通服务器的
4.在NAT主机上添加一条SNAT规则做源地址转换
#iptables -APOSTROUTING -s 192.168.191.0/24 -j SNAT --to-source 172.16.36.1
//将源地址为192.168.191.0网段的地址,不论目标地址和访问的端口是什么,统统将源地址转换为172.16.36.1
5.客户机测试:curl http://172.16.36.200
6.查看服务器web服务的日志:
tail /etc/httpd/logs/access_log
可以看到日志中访问者IP为172.16.36.1 即为我们SNAT配置的地址,访问成功
目标地址转换:
1.将服务器的网关设置为172.16.36.1
2.将web服务的监听端口改为8080
3.在NAT主机上添加一条DNAT规则做目标地址,和目标端口转换。
#iptables -APREROUTING -d 192.168.191.111 -p tcp --dport 80 -j DNAT --to-destination172.16.36.200:8080
//将目标地址为192.168.191.111且TCP端口为80的请求,目标地址改为172.16.36.200,端口改为8080
4.客户机测试:curl http://192.168.191.111
5.查看服务器日志:
可以看到日志中访问者IP为客户机192.168.191.222,访问成功
如何保存及重载规则:
保存:
(1)service iptables save
/etc/sysconfig/iptables文件;
(2) iptables-save> /PATH/TO/SOMEFILE
重载:
(1)service iptables reload
(2)iptables-restore < /PATH/FROM/SOMEFILE