iptables:包过滤型的防火墙
Firewall:防火墙,隔离工具;工作于主机或网络边缘,对于进出本主机或本网络的报文根据事先定义的检查规则作匹配检测,对于能够被规则匹配到的报文做出相应处理的组件;
主机防火墙
网络防火墙
软件防火墙(软件逻辑)
硬件防火墙(硬件和软件逻辑)
ipfw(firewall framework)
ipchains(firewall framework)
iptables(netfilter)
netfilter:kernel
iptables:rules until
hook function:
input
output
forward
prerouting
postrouting
链(内置):
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
功能:
filter:过滤,防火墙;
nat:network address translation;用于修改源ip或者目标ip,也可以改端口;
mangle:拆解报文,做出修改,并重新封装起来;
raw:关闭nat表上启用的连接追踪机制;
功能<-> 链
raw:PREROUTING, OUTPUT
mangle:PREROUTING , INPUT , FORWARD,OUTPUT ,POSTROUTING
nat:PREROUTING, [INPUT], OUTPUT, POSTROUTING
filter:INPUT , FORWARD , OUTPUT
报文流向:
流入本机:PREROUTING à INPUT
由本机流出:OUTPUT à POSTROUTING
转发:PREROUTING à FORWARD à POSTROUTING
路由功能发生时刻:
报文进入本机后;
判断目标主机是?
报文离开主机前:
判断由哪个接口送往下一站?
Iptables/netfileter
规则:
组成部分:根据规则匹配条件来尝试匹配报文,一旦匹配成功,就由规则定义的处理动作;
匹配条件:
基本匹配条件
扩展匹配条件
处理动作:
基本处理动作
扩展处理动作
自定义处理机制
iptables的链:内置链和自定义链
内置链:对应于hook function
自定义链接:用于内置链的扩展和补充,可实现更灵活的规则管理机制;
添加规则时的考量点:
1) 要实现哪种功能:判断添加到哪个表上;
2) 报文流经的路径:判断添加到哪个链上;
链:链上的规则次序,即为检查的次序;因此,隐含一定的应用法则;
1) 同类规则(访问同一应用),匹配范围小的放上面;
2) 不同类的规则(访问不同应用),匹配范围小的放上面;
3) 将那些可由一条规则描述的多个规则合并起来;
4) 设置默认策略;
iptables命令:
iptables [-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 table] COMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]
-t table :
raw,mangle,nat ,[filter]
COMMAND:
链管理:
-N:new,自定义一条新的规则链;
-X:delete,删除自定义的规则链;
-P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:
ACCEPT:接受;
DROP:丢弃
REJECT:拒绝
-E:重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除;
规则管理:
为了掩饰方便我们设默认策略为DROP;
-A:append,追加;
-I:insert,插入,要指明位置,省略时表示第一条;
-R:replace,替换指定链上的指定规则;
-D:delete,删除:
1) 指明规则序号;
2) 指明规则本身;
-F:flush,清空指定的规则链;
-Z:zero,置零;
iptables的每条规则都由两个计数器;
1) 匹配到的报文的个数;
2) 匹配到的所有报文大小之和;
查看:
-L:list,列出指定链上的所有规则;
-n:numberic,以数字格式显示地址和端口号;
-v:verbose,详细信息;
-vv,-vvv
-x:exactly,显示计数器结果的精确值;
--line-numbers:显示规则的序号;
chain:
PREROUTING , INPUT , FORWARD , OUTPUT , POSTROUTING
匹配条件:
基本匹配条件:无需加载任何模块,由iptables/netfilter
[!] –s,--source address[/mask][,…]:检查报文中的源ip地址是否符合此处指定的地址或范围;
[!] –d ,--destination address [/mask][,…]:检查报文中的目标地址是否符合此处指定的地址或范围;
[!] –p,--protocol PROTOCOL
PROTOCOL:tcp,udp,udplite,icmp,icmpv6,esp,ah,sctp,mh or “all”
{tcp|udp|icmp}
[!] – i,--in-interface name:数据报文流入的接口:只能应用于数据报文流入的环节,只能应用于PREROUTING,INPUT和FORWARD链;
[!] – 0,--out-interface name:数据报文流出的接口;只能应用于数据报文流出的环节,智能应用于FORWARD,OUTPUT和POSTROUTING链;
扩展匹配条件:需要加载扩展模块,方可生效;
隐式扩展:不需要手动加载扩展模块;因为他们是对协议的扩展,所以,但凡使用-p指明了协议,就表示已经指明了要扩展的模块;
tcp:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围;
[!] --tcp-flages mask comp
mask is the flags which we should examine, written as a comma-separated list,例如 SYN,ACK,FIN,RST
comp is a comma-separated list of flags which must be set,例如SYN
例如:“--tcp-flags SYN,ACK,FIN,RST SYN”表示,要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0;
[!] --syn:用于匹配第一次握手,相当于“--tcp-flags SYN,ACK,FIN,RST SYN”
udp
[!] --source-port , --sport port[:port]:匹配报文的源端口;可以是端口范围;
icmp
[!] --icmp-type {type[/code]|typename}
echo-request:8
echo-reply:0
显示扩展:必须要手动加载扩展模块,[-m matchname [per-match-options]];
处理动作:
-j targetname [per-target-options]
ACCEPT
DROP
REJECT
RETURN:返回调用链;
REDIRECT:端口重定向;
LOG:记录日志;
MARK:做防火墙标记;
DNAT:目标地址转换;
SNAT:源地址转换;
MASQUERADE:地址伪装;
…
自定义链;
防火墙(服务):
Centos6:
service iptables {start|stop|restart|status}
start:读取实现保存的规则,并应用到netfilter上;
stop:清空netfilter上的规则,以及还原默认策略等;
status:显示生效的规则;
restart:清空netfilter上的规则,再读取事先保存的规则,并应用到netfilter上;
默认的规则文件:/etc/sysconfig/iptables
Centos7:
systemctl start|stop|restart|status firewalld.service
systemctl disable firewalld.service 设置iptables开机不自启;
systemctl stop firewalld.service
iptables(2)
显示扩展:必须显示地指明使用的扩展模块进行的扩展;
使用帮助:
Centos6:man iptables
Centos7:man iptables-extensions
1. multiport扩展;
以离散方式定义多端口匹配;最多指定5个端口;
[!] --source-ports,--sports port[,port|,port:port]…:指定多个源端口;
[!] --destination-ports,--dports port[,port|,port:port]…多个目标端口;
[!] --ports port[,port|,port:port]…多个端口;
2. iprange扩展
指明连续的(但一般不包整个网络)ip地址范围;
[!] --src-range from[-to]:源ip地址;
[!] --dst-range from[-to]:目标ip地址;
3. string扩展
对报文中的应用层数据做字符串模式匹配检测;
--algo {bm|kmp}:字符串匹配检测算法;
bm:Boyer-Moore
kmp:Knuth-Pratt-Morris
[!] --string pattern:要检测的字符串模式;
[!] --hex-string pattern:腰间的字符串模式,16进制格式;
4. time扩展
根据将报文到达的时间与指定的时间范围进行匹配;
--datastart 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...]
--kerneltz:使用内核上的时区,而非默认的UTC;
5. connlimit扩展;
根据每客户端IP做并发连接数数量匹配;
--connlimit-upto n :连接数量小于或等于n时匹配;
--connlimit-above n:连接的数量大于n时匹配;
6. limit扩展;
基于收发报文的速率做匹配;
令牌通过过滤器;
--limit rate[/second|/minute|/hour|/day]
--limit-burst number
7. state扩展
根据“连接追踪机制”去检查连接的状态;
Conntrack机制:追踪本机上的请求和响应之间的关系;状态有如下几种;
NEW:新发出的请求;连接追踪模板中不存在此链接的相关信息条目,因此,将其识别为第一次发出的请求;
ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信状态;
RELATED:相关联的连接;如ftp协议中的数据连接与命令连接之间的关系;
INVALID:无效的连接;
UNTRACKED:未进行追踪的连接;
[!] --state state
调整连接追踪功能所能够容纳的最大连接数量;
/proc/sys/net/nf_contrack_max
已经追踪到的并记录下的连接;
/proc/net/nf_conntrack
不同的协议的连接追踪时长;
/proc/sys/net/netfilter/
Note:iptables的连接跟踪表最大容量为/proc/sys/net/ipv4/ip_conntrack_max,链接碰到各种状态的超时后就会从表中删除;当模板满载时,后续的连接可能会超时;
解决方法一般有两个:
1) 加大nf_conntrack_max的值
vim /etc/sysctl.conf
net.ipv4.nf_conntrack_max = 393216
net.ipv4.netfilter.nf_conntrack_max = 393216
2) 降低nf_conntrack timeout时间;
vim /etc/sysctl.conf
net.ipv4.netfilter.nf_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
问题:如何开放被动模式的ftp服务?(server地址为192.168.19.130)
1) 装载ftp连接追踪的专用模块;
~]# modproble nf_conntrack_ftp
2) 放行命令连接
~]# iptables -A INPUT -d 192.168.19.130 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
~]# iptables -A OUTPUT -s 192.168.19.130 -p tcp --sport 21 -m state --state ESTABLISHED -j ACCEPT
3) 放行数据连接;
~]# iptables -A INPUT -d 192.168.19.130 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
~]# iptables -I OUTPUT -s 192.168.19.130 -m state --state ESTABLISHED -j ACCEPT
规则优化:
服务器端规则设定:任何不允许的访问,应该在请求到达时给予拒绝;
1) 可安全放行所有入栈的状态为ESTABLISHED的状态的连接;
2) 可安全放行所有出站状态为ESTABLISHED状态的连接;
3) 谨慎放行入栈的心情求;
4) 有特殊目的限制访问功能,要于放行规则之前加以拒绝;
如何使用自定义链:
自定义链:需要被调用才能生效;自定义链最后需要定义返回规则;
返回规则使用的target叫做RETURN
规则的有效期限:
使用iptables命令定义的规则,手动删除之前,其生效期限为kernel存活期限;
保存规则:
保存规则至指定的文件中:
Centos6:
service iptables save:将规则保存至/etc/sysconfig/iptables文件中;
iptables-save > /path/ro/some_rules_file:将规则保存指定的文件中;
centos7:
iptables-save > /path/to/some_rules_file:
重新载入预存规则文件中的规则:
iptables-restore < /path/from/some_rules_file
Centos6:
Service iptables restart
自动生效规则文件中的规则;
1) 用脚本保存各iptables命令:让此脚本开机后自动运行;
/etc/rc.d/rc.local文件添加脚本路径;
/path/to/some_script_file
2) 用规则文件保存各规则,开机时自动载入此规则文件中的规则;
/etc/rc.d/rc.local文件添加;
Iptables-restore < /path/from/iptables_rules_file
CentOS 7:
引入了新的iptables前端管理工具firewalld,其管理工个有:firewalld-cmd, firewalld-config
网络防火墙:
netfilter在INPUT和OUTPUT链上表现其作为主机防火墙的角色,而其在FORWARD链上则表现是作为网络防火墙的角色;
下面通过实例演示网络防火墙:
centos7主机有两块网卡,并且这两块网卡的地址位于不同的网络中,地址分别为192.168.19.130和172.16.23.1;centos6test作为服务器,地址为172.16.23.2;centos6作为客户端,地址为192.168.19.134;
要求:通过centos7主机扮演网络防火墙,在FORWARD链上生成过滤规则,规则要求如下;
1) 放行客户端对服务器端的ftp服务的访问;
2) 放行客户端对服务器端的远程连接ssh服务;
3) 放行客户端对服务器端的web服务的访问;
4) 放行客户端对服务器端的ping操作;
Centos7主机上;
1. 开启转发功能;
2. 设置ip地址为如下地址;
3. 清空规则链,新建规则;
Centos6test主机上:
1. 设置其ip地址为如下地址;
2. 设置路由指向centos7主机;
Centos6主机上:
1. 设置ip地址为如下;
2. 删除原有的路由,设置新的路由指向centos7主机;
iptables(3)之nat
netfilter:nat table
nat:network address translation
snat:source nat
dnat:destination nat
pnat:port nat
snat:POSTROUTING , OUTPUT
让本地网络中的主机用过某一特定地地址访问外部网络时,
dnat:PREROUTING
把本地网络中的某一主机上的某服务开放给外部网络中的用户访问时,
nat表的target
SNAT
--to-source [ipaddr [-ipaddr]][:port[-port]]
DNAT
--to-destination [ipaddr[-ipaddr]][:port[-port]]
MASQUERADE
--to-ports port[-port]
--random
SNAT示例:
1. 在上面的网络防火墙示例中,用centos6主机访问centos6test主机的web服务并做ping操作;
2. 在centos6test主机上使用tcpdump命令抓包,并且查看httpd的访问日志,可以发现地址都是192.168.19.134;
3. 在网络防火墙centos7主机上添加net规则;
4. 再一次重复第1步,第2步操作,测试,发现抓包的地址和日志文件中地址都变成了192.168.115.32;
DNAT示例:
1. 添加规则;
2. 在centos6主机上再次访问centos6test的web服务,发现访问的是centos7主机的web,这里的目的地址发现了转换;
3. 当然也可以在转换目的地址的同时转换端口;
MASQUERADE示例:地址伪装
1. 添加规则;
2. 在centos6主机上对centos6test作ping操作;
3. 在centos6test主机抓包测试;
REDIRECT:端口重定向;
Web:8080
80 —> 8080
1. 将centos6test主机的httpd服务监听端口改为8080;
2. 在centos6test主机上添加规则;
3. 此时通过centos6主机访问centos6test主机的httpd服务;
Note:必须要加端口访问,访问80端口,自动重定向为8080端口;
补充:利用iptables的recent模块来抵御DOS攻击: 22,建立一个列表,保存有所有访问过指定的服务的客户端IP
以ssh( 远程连接)为例:
1. 利用connlimit模块将单IP的并发设置为3;会误杀使用NAT上网的用户,可以根据实际情况增大该值;
iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
2. 利用recent和state模块限制单IP在300s内只能与本机建立2个新连接。被限制五分钟后即可恢复访问。
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
下面对最后两句做一个说明:
1.第二句是记录访问tcp 22端口的新连接,记录名称为SSH
--set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目
2.第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
--update 是指每次建立连接都更新列表;
--seconds必须与--rcheck或者--update同时使用
--hitcount必须与--rcheck或者--update同时使用
3.iptables的记录:/proc/net/xt_recent/SSH
也可以使用下面的这句记录日志:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"