防火墙概念
从逻辑上讲,防火墙可以答题分为主机防火墙和网络防火墙
主机防火墙: 针对于单个主机进行防护。
网络防火墙:往往处于网络入口或边缘,针对于网路入口进行防护,服务于防火墙背后的本地局域网。
网络防火墙和主机防火墙并不冲突,可以理解为 网络防火墙主外(集体), 主机防火墙主内(个人)。
从物理上讲,防火墙可以分为硬件防火墙和软件防火墙。
硬件防火墙:在硬件级别实现部分防火墙功能,另一部分功能基于软件实现,性能高,成本高。
软件防火墙:应用软件处理逻辑运行于通用硬件 平台之上的防火墙,性能低,成本低。
iptables
简介
iptables 其实不是真正的防火墙,我们可以把它理解为一个客户端代理,用户通过iptables 这个代理,将用户的安全设定执行到对应的“安全框架”中, 这个“安全框架” 才是真正的防火墙,这个框架的名字是netfilter
netfilter是linux操作系统核心层内部的一个数据包处理模块,它具有如下功能:
网络地址转换--NAT
数据包内容修改
数据包过滤的防火墙功能
所以说 虽然我们使用service iptables start 启动服务 ,但其实准确来说,iptables 并没有一个守护进程,所以并不能算是真正意义上的服务,而应该算是内核提供的功能。
iptables基础
当客户端访问服务器的web服务时,客户端发送报文到网卡上,而tcp/ip 协议栈是属于内核的一部分,所以客户端的信息回通过内核的TCP 协议传输到用户空间中的web服务中,而此时客户端报文的目标终点为web服务所监听的套接字(IP : Port)上,当web服务需要相应客户端请求时,web服务发送的响应报文的目标终点则为客户端,这个时候。web服务所监听的IP 与端口反而变成了原 ;我们说过 netfilter 才是真正的防火墙,它是内核的一部分,所以 如果我们想要防火墙能够达到 “防火”的目的,则需要在内核中设置关卡,所有进出的报文都要通过这些关卡,经过检查后,符合放行条件的才能放行,符合阻拦条件的需要被阻挡,于是就出现了input 和 output 关卡, 而这些 关卡 在iptables 中 被称为 “链”
我们上面描述的 并不完善,因为客户端发来的报文访问的目标地址可能并不是本机,而是其他服务器,当本机的内核支持IP_FORWARD时, 我们可以将报文转发给其他服务器,所以 这个时候,我们就会用到 “关卡”,也就是“链”,他们就是“路由前”、“转发”、“路由后”、,他们的英文名是PREROUTING、FORWARD、POSTROUTING
也就是说,当我们启用了防火墙功能时,报文需要经过如下关卡, 要根据实际情况不同,报文经过的“链”可能不同。如果报文需要转发,那么报文则不会经过input 链发往用户空间,而是直接在内核空间中经过forward链和 postrouting 链转发出去的
根据上图,我们能够总结出 报文流向的三种场景
1、到本机进程的报文:PREROUTING---> INPUT
2、由本机转发的报文:PREROUTING --> FORWARD -->POSTROUTING
3、由本机的某进程发出报文(通常为响应报文) :OUTPUT --> POSTROUTING
链
我们知道,防火墙的作用就在于对经过的报文匹配“规则”,然后执行对应的“动作”,所以当报文经过这些关卡的时候,必须匹配到这个关卡上的规则,但是这个关卡上可能不止有一条规则,而是有很多条规则,当我们把这些规则串到一个链条上的时候,就形成了“链”, 所以我们把每一个关卡想象成如下图 所示的模样,这样来说,把他们称为“链” 更为合适,每个经过这个“关卡”的报文, 都要讲这条“链”上所有的规则匹配一遍, 如果有符合条件的规则, 则执行规则对应的动作。
表
我们把相同功能的规则集合叫做“表”,所以说不同功能的规则,我们可以放置在不同的表中济宁管理,而iptables 已经为我们定义了4种表,每种表对应了不同的功能,二我们定义的规则也都逃脱不了这4种功能范围,所以学习iptables 之前 ,我们要搞明白每种表的作用。
iptables 为我们提供了如下规则的分类, 或者说 iptables 为我们提供了如下“表”
filter表:负责过滤功能,防火墙;内核模块:iptables_filter
nat表:network address translation ,网络地址转换功能;内核模块:iptable_nat
mangle表 :拆解报文,做出修改,并重新封装的功能; iptable_mangle
raw表:关闭nat表上启用的连接追踪机制; iptable_raw
也就是说,我们自定义的所有规则,都是这四种分类中的规则,或者说 所有规则都存在于这4张表中
iptables规则管理
iptables -F :清除所有规则
iptables -F INPUT: 清除 INPUT 里所有规则
iptables -nvL INPUT : 查看规则的详细信息,包括端口,IP地址
添加规则
ACCEPT 表示允许
REJECT 表示拒绝
DROP 表示删除
-A 表示在链的尾部 追加规则
- I 表示在在链的首部插入规则
iptables --line -vnL INPUT : 列出规则序号
示例:
[root@centos7 ~]#iptables -I INPUT -s 192.168.95.5 -j REJECT #拒绝95.5的计算机访问
[root@localhost ~]# ping 192.168.95.2
PING 192.168.95.2 (192.168.95.2) 56(84) bytes of data.
From 192.168.95.2 icmp_seq=1 Destination Port Unreachable #访问被拒绝
From 192.168.95.2 icmp_seq=2 Destination Port Unreachable
[root@centos7 ~]#iptables -vnL INPUT
Chain INPUT (policy ACCEPT 32 packets, 4904 bytes)
pkts bytes target prot opt in out source destination
5 420 REJECT all -- * * 192.168.95.5 0.0.0.0/0 #显示被拒绝的主机信息
[root@centos7 ~]#iptables -t filter -I INPUT -s 192.168.95.5 -j DROP #插入一条拒绝规则 [root@centos7 ~]#iptables -vnL Chain INPUT (policy ACCEPT 48 packets, 3168 bytes) pkts bytes target prot opt in out source destination 0 0 DROP all -- * * 192.168.95.5 0.0.0.0/0 #顺序在最上面 0 0 REJECT all -- * * 192.168.95.5 0.0.0.0/0 [root@localhost ~]# ping 192.168.95.2 PING 192.168.95.2 (192.168.95.2) 56(84) bytes of data. #访问被拒绝,ping不通
看来 规则顺序很重要,如果报文已经被前面的规则匹配到,iptables则会对报文习性对应的动作,即使后面的规则也能匹配到 也没有机会再对报文执行相应的动作了。
我们也可以在添加规则时,指定新增规则的序号,这样我们就能在任意位置插入规则了
[root@centos7 ~]#iptables -t filter -I INPUT 3 -s 192.168.95.5 -j ACCEPT #指定规则的序号为3
[root@centos7 ~]#iptables --line -vnL INPUT
Chain INPUT (policy ACCEPT 38 packets, 6438 bytes)
num pkts bytes target prot opt in out source destination
1 6 504 DROP all -- * * 192.168.95.5 0.0.0.0/0
2 0 0 REJECT all -- * * 192.168.95.5 0.0.0.0/0 reject-with icmp-port-unreachable
3 0 0 ACCEPT all -- * * 192.168.95.5 0.0.0.0/0
删除规则
方法一:根据规则的编号去删除
方法二:根据具体的匹配条件与动作删除
方法一
[root@centos7 ~]#iptables -t filter -D INPUT 3
方法二
[root@centos7 ~]#iptables -D INPUT -s 192.168.95.5 -j ACCEPT
修改规则
[root@centos7 ~]#iptables -t filter -R INPUT 3 -s 192.168.95.5 -j DROP
这里要说明一下,-R 选项表示修改指定的链, INPUT 第3条规则,-j DROP 表示将即原来的动作改为 DROP; 而 -s 选项以及对应的源地址不可以省略 ,即使我们指定了规则编号 也不行,否则修改完成后,规则中的源地址会自动变成 0.0.0.0/0
保存规则
centos6 :service iptables save 默认保存在/etc/sysconfig/iptables
centos7:已经不再使用init风格的脚本启动服务,而是使用unit文件,所以不能使用类似centos6的命令了,下面是 centos7 的 保存规则步骤
上述配置过程只需一次,以后即可在centos7 中 使用 service iptables save 命令保存 iptables规则了
匹配条件
[!] -s, --source address[/mask][,...]:源IP地址或范围
[root@centos7 ~]# iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT [root@centos7 ~]# iptables -A INPUT -j DROP
[!] -d, --destination address[/mask][,...]:目标IP地址或范围
[root@centos7 ~]# iptables -A OUTPUT -d 192.168.0.0/24 -j ACCEPT [root@centos7 ~]# iptables -A OUTPUT -j DROP
[!] -p, --protocol protocol:指定协议portocol:tcp、udp、icmp,参考/etc/protocols
[root@centos7 ~]# iptables -A INPUT -p tcp -j ACCEPT
[!] -i, --in-interface name:报文流入的接口;只能应用于数据报文流入环节,只应用于INPUT、FORWARD、PREROUTING链
[root@centos7 ~]# iptables -A INPUT -i lo -j ACCEPT
[!] -o, --out-interface name:报文流出的接口;只能应用于数据报文流出的环节,只应用于FORWARD、OUTPUT、POSTROUTING链
[root@centos7 ~]# iptables -A OUTPUT -o lo -j ACCEPT
4.2) 扩展匹配条件:需要加载扩展模块/usr/lib64/xtables/*.so
,查看帮助man iptables-extensions
4.2.1)隐式扩展:在使用-p选项指明了特定的协议时,无需再用-m选项指明扩展模块的扩展机制,不需要手动加载扩展模块
tcp协议的扩展选项:
[!] --source-port, --sport port[:port]:匹配报文源端口,可为端口范围
[root@centos7 ~]# iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT [root@centos7 ~]# iptables -A OUTPUT -j DROP
[!] --destination-port,--dport port[:port]:匹配报文目标端口,可为范围
[root@centos7 ~]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT [root@centos7 ~]# iptables -A INPUT -j DROP
[!] --tcp-flags mask comp:mask 需检查的标志位列表,用,分隔,例如 SYN,ACK,FIN,RST;comp 在mask列表中必须为1的标志位列表,无指定则必须为0,用,分隔
[root@centos7 ~]# iptables -I INPUT -p tcp --tcp-flags SYN,ACK,FIN,RST SYN -j ACCEPT
[!] --syn:用于匹配第一次握手,相当于:--tcp-flags SYN,ACK,FIN,RST SYN
[root@centos7 ~]# iptables -I INPUT -p tcp --syn -j ACCEPT
udp协议的扩展选项:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围
icmp协议的扩展选项:
[!] --icmp-type {type[/code]|typename}:0:icmp应答;8:icmp请求
[root@centos7 ~]# iptables -A INPUT -p icmp --icmp-type 8 -j DROP #不接受ping请求 [root@centos7 ~]# iptables -A OUTPUT -p icmp --icmp-type 0 -j ACCEPT
4.2.2)显式扩展:必须使用 -m 选项指明要调用的扩展模块的扩展机制,要手动加载扩展模块
使用帮助:
CentOS 6: man iptables
CentOS 7: man iptables-extensions
multiport:以离散方式定义多端口匹配,最多指定15个端口
[!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口
[!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口
[!] --ports port[,port|,port:port]...:多个源或目标端口
[root@centos7 ~]# iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
iprange:指明连续的(但一般不是整个网络)ip地址范围
[!] --src-range from[-to]:源IP地址范围
[!] --dst-range from[-to]:目标IP地址范围
[root@centos7 ~]# iptables -A INPUT -m iprange --src-range 192.168.0.100-192.168.0.200 -j REJECT
mac:指明源MAC地址,适用于:PREROUTING,FORWARD,INPUT
[!] --mac-source XX:XX:XX:XX:XX:XX
string:对报文中的应用层数据做字符串模式匹配检测
--algo {bm|kmp}:字符串匹配检测算法
--from offset 开始偏移
--to offset 结束偏移
[!] --string pattern:要检测的字符串模式
[!] --hex-string pattern:要检测字符串模式,16进制格式
[root@centos7 ~]# echo "www.baidu.com" > /var/www/html/f1.txt [root@centos7 ~]# echo "www.google.com" > /var/www/html/f2.txt [root@centos7 ~]# systemctl start httpd [root@centos6 ~]# curl 192.168.0.7/f1.txt www.baidu.com [root@centos6 ~]# curl 192.168.0.7/f2.txt #加规则之前正常访问 www.google.com [root@centos7 ~]# iptables -A OUTPUT -m string --algo bm --string google -j REJECT #在OUTPUT链上加字符串匹配规则 [root@centos6 ~]# curl 192.168.0.7/f1.txt #baidu正常访问 www.baidu.com [root@centos6 ~]# curl 192.168.0.7/f2.txt #google无法访问
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...]
--kerneltz:内核时区,CentOS7系统默认为UTC;CentOS6不支持kerneltz,默认使用--localtz:指定本地时区
[root@centos7 ~]# iptables -A INPUT -d 192.168.0.7 -p tcp --dport 80 -m time --timestart 1:00 --timestop 4:00 --weekdays 1,3,5 --kerneltz -j DROP
connlimit:根据每客户端IP做并发连接数数量匹配,通常分别与默认的拒绝或允许策略配合使用
--connlimit-upto n:连接的数量小于等于n时匹配
--connlimit-above n:连接的数量大于n时匹配
[root@centos7 ~]# iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
limit:基于收发报文的速率做匹配,令牌桶过滤器
--limit rate[/second|/minute|/hour|/day] 每多长时间接收rate个包
--limit-burst number 第一次允许流入多少个包
[root@centos7 ~]# iptables -A INPUT -p icmp --icmp-type 8 -m limit --limit 10/minute --limit-burst 5 -j ACCEPT [root@centos7 ~]# iptables -A INPUT -p icmp -j REJECT
state:根据”连接追踪机制“去检查连接的状态
conntrack机制:追踪本机上的请求和响应之间的关系;
modprobe nf_conntrack
状态有如下几种:
- NEW:新发出请求;连接追踪信息库中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求
- ESTABLISHED:NEW状态之后,连接追踪信息库中为其建立的条目失效之前期间内所进行的通信状态
- RELATED:新发起的但与已有连接相关联的连接,如:ftp协议中的数据连接与命令连接之间的关系
- INVALID:无效的连接,如flag标记不正确
- UNTRACKED:未进行追踪的连接,如raw表中关闭追踪
[!] --state {NEW,ESTABLISHED,RELATED,INVALID,UNTRACKED}
[root@centos7 ~]# iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT [root@centos7 ~]# iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -m state --state NEW -j ACCEPT[root@centos7 ~]# iptables -A INPUT -j DROP
已经追踪到的并记录下来的连接信息库/proc/net/nf_conntrack
调整连接追踪功能所能够容纳的最大连接数量/proc/sys/net/nf_conntrack_max
不同的协议的连接追踪时长/proc/sys/net/netfilter/
iptables的链接跟踪表最大容量为/proc/sys/net/nf_conntrack_max
,各种状态的超时链接会从表中删除;当模板满载时,后续连接可能会超时
解决方法两个: (1) 加大 nf_conntrack_max 值 vi /etc/sysctl.conf net.nf_conntrack_max = 393216 net.netfilter.nf_conntrack_max = 393216 (2) 降低 nf_conntrack timeout 时间 vi /etc/sysctl.conf net.netfilter.nf_conntrack_tcp_timeout_established = 300 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
5、-j target:处理动作
5.1)简单:
- ACCEPT
- DROP
5.2)扩展:
- REJECT:--reject-with:icmp-port-unreachable默认
- RETURN:返回调用链
- REDIRECT:端口重定向
- MARK:做防火墙标记
- DNAT:目标地址转换
- SNAT:源地址转换
- MASQUERADE:地址伪装
- 自定义链
- LOG:记录日志
LOG:非中断target,本身不拒绝和允许,放在拒绝和允许规则前并将日志记录在/var/log/messages系统日志中
- --log-level level:日志级别: emerg, alert, crit, error, warning, notice, info or debug
- --log-prefix prefix:日志前缀,用于区别不同的日志,最多29个字符
[root@centos7 ~]# iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j LOG --log-prefix "new ssh connections" [root@centos7 ~]# tail -f /var/log/messages
三、规则优化、保存与恢复
- 安全放行所有入站和出站的状态为ESTABLISHED状态连接
- 谨慎放行入站的新请求
- 有特殊目的限制访问功能,要在放行规则之前加以拒绝
- 同类规则(访问同一应用),匹配范围小的放在前面,用于特殊处理
- 不同类的规则(访问不同应用),匹配范围大的放在前面
- 应该将那些可由一条规则能够描述的多个规则合并为一条
- 设置默认策略,建议白名单(只放行特定连接) , 建议在规则的最后定义规则做为默认策略
保存规则:iptables-save > /PATH/TO/SOME_RULES_FILE
载入规则:iptables-restore < /PATH/FROM/SOME_RULES_FILE
-n, --noflush:不清除原有规则
-t, --test:仅分析生成规则集,但不提交
四、开放被动模式的ftp服务
1)装载ftp连接追踪的专用模块:
[root@centos7 ~]# vim /etc/sysconfig/iptables-config IPTABLES_MODULES="nf_conntrack_ftp" [root@centos7 ~]# modprobe nf_conntrack_ftp
2)放行请求/响应报文
命令连接:NEW, ESTABLISHED
数据连接:RELATED, ESTABLISHED
[root@centos7 ~]# iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT [root@centos7 ~]# iptables -A INPUT -p tcp --dport 21 -m state --state NEW -j ACCEPT [root@centos7 ~]# iptables -A INPUT -j DROP [root@centos7 ~]# iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT [root@centos7 ~]# iptables -A OUTPUT -j DROP
五、NAT:network address translation
1、SNAT
请求报文的源地址转换,让本地网络中的主机通过某一特定地址访问外部网络,实现地址伪装
route:
# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf # sysctl -p # iptables -t nat -A POSTROUTING -s 192.168.0.0/24 ! -d 192.168.0.0/24 -j SNAT --to-source 10.0.0.254
动态转换:
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 ! -d 192.168.0.0/24 -j MASQUERADE
2、DNAT
请求报文的目标地址转换,把本地网络中的主机上的某服务开放给外部网络访问,发布服务和端口映射,隐藏真实IP
route:
# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf # sysctl -p # iptables -t nat -A PREROUTING -d 10.0.0.254 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.6:80
3、PNAT
端口和IP都进行转换
六、端口转发
配置于NAT表的 PREROUTING OUTPUT 链,通过改变目标IP和端口,将接受的包转发至不同端口
# iptables -t nat -A PREROUTING -d 192.168.0.6 -p tcp --dport 80 -j REDIRECT --to-ports 8080