第8章 Iptables与Firewalld防火墙
章节简述:
红帽RHEL7系统已经用firewalld服务替代了iptables服务,新的防火墙管理命令firewall-cmd与图形化工具firewall-config。
本章节基于数十个防火墙需求,使用规则策略完整演示对数据包的过滤、SNAT/SDAT技术、端口转发以及负载均衡等实验。
不光光学习iptables命令与firewalld服务,还新增了Tcp_wrappers防火墙服务小节,简单配置即可保证系统与服务的安全。
本章目录结构 [收起]
8.1 了解防火墙管理工具
防火墙虽有软件或硬件之分但主要功能还是依据策略对外部请求进行过滤,成为公网与内网之间的保护屏障,防火墙会监控每一个数据包并判断是否有相应的匹配策略规则,直到满足其中一条策略规则为止,而防火墙规则策略可以是基于来源地址、请求动作或协议来定制的,最终仅让合法的用户请求流入到内网中,其余的均被丢弃。
在红帽RHEL7系统中firewalld服务取代了iptables服务,但依然可以使用iptables命令来管理内核的netfilter。这对于接触Linux系统比较早或学习过红帽RHEL6系统的读者来讲,突然接触firewalld服务会比较抵触,可能会觉得新增Firewalld服务是一次不小的改变,其实这样讲也是有道理的。但其实Iptables服务与Firewalld服务都不是真正的防火墙,它们都只是用来定义防火墙规则功能的“防火墙管理工具”,将定义好的规则交由内核中的netfilter即网络过滤器来读取,从而真正实现防火墙功能,所以其实在配置规则的思路上是完全一致的,而我会在本章中将iptables命令与firewalld服务的使用方法都教授给你们,坦白讲日常工作无论用那种都是可行的。
8.2 Iptables命令
iptables命令用于创建数据过滤与NAT规则,主流的Linux系统都会默认启用iptables命令,但其参数较多且规则策略相对比较复杂。
8.2.1 规则链与策略
在iptables命令中设置数据过滤或处理数据包的策略叫做规则,将多个规则合成一个链。
举例来说:小区门卫有两条的规则,将这两个规则可以合成一个规则链:
遇到外来车辆需要登记。
严禁快递小哥进入社区。
但是光有策略还不能保证社区的安全,我们需要告诉门卫(iptables)这个策略(规则链)是作用于哪里的,并赋予安保人员可能的操作有这些,如:“允许”,“登记”,“拒绝”,“不理他”,对应到iptables命令中则常见的控制类型有:
ACCEPT:允许通过.
LOG:记录日志信息,然后传给下一条规则继续匹配.
REJECT:拒绝通过,必要时会给出提示.
DROP:直接丢弃,不给出任何回应.
其中REJECT和DROP的操作都是将数据包拒绝,但REJECT会再回复一条“您的信息我已收到,但被扔掉了”。
通过ping命令测试REJECT情况会是这样的:
[root@localhost ~]# ping -c 4 192.168.10.10 PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data. From 192.168.10.10 icmp_seq=1 Destination Port Unreachable From 192.168.10.10 icmp_seq=2 Destination Port Unreachable From 192.168.10.10 icmp_seq=3 Destination Port Unreachable From 192.168.10.10 icmp_seq=4 Destination Port Unreachable --- 192.168.10.10 ping statistics --- 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3002ms
但如果是DROP则不予响应:
[root@localhost ~]# ping -c 4 192.168.10.10 PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data. --- 192.168.10.10 ping statistics --- 4 packets transmitted, 0 received, 100% packet loss, time 3000ms
而规则链则依据处理数据包的位置不同而进行分类:
PREROUTING:在进行路由选择前处理数据包
INPUT:处理入站的数据包
OUTPUT:处理出站的数据包
FORWARD:处理转发的数据包
POSTROUTING:在进行路由选择后处理数据包
raw表:确定是否对该数据包进行状态跟踪mangle表:为数据包设置标记nat表:修改数据包中的源、目标IP地址或端口filter表:确定是否放行该数据包(过滤)
规则表的先后顺序:raw→mangle→nat→filter
规则链的先后顺序:
入站顺序:PREROUTING→INPUT
出站顺序:OUTPUT→POSTROUTING
转发顺序:PREROUTING→FORWARD→POSTROUTING
还有三点注意事项:
1.没有指定规则表则默认指filter表。
2.不指定规则链则指表内所有的规则链。
3.在规则链中匹配规则时会依次检查,匹配即停止(LOG规则例外),若没匹配项则按链的默认状态处理。
8.2.2 基本的命令参数
iptables命令用于管理防火墙的规则策略,格式为:“iptables [-t 表名] 选项 [链名] [条件] [-j 控制类型]”。
表格为读者总结了几乎所有常用的iptables参数,如果记不住也没关系,用时来查就行,看完后来学习下如何组合并使用吧:
参数 | 作用 |
-P | 设置默认策略:iptables -P INPUT (DROP|ACCEPT) |
-F | 清空规则链 |
-L | 查看规则链 |
-A | 在规则链的末尾加入新规则 |
-I num | 在规则链的头部加入新规则 |
-D num | 删除某一条规则 |
-s | 匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。 |
-d | 匹配目标地址 |
-i 网卡名称 | 匹配从这块网卡流入的数据 |
-o 网卡名称 | 匹配从这块网卡流出的数据 |
-p | 匹配协议,如tcp,udp,icmp |
--dport num | 匹配目标端口号 |
--sport num | 匹配来源端口号 |
查看已有的规则:
[root@linuxprobe ~]# iptables -L
清空已有的规则:
[root@linuxprobe ~]# iptables -F
将INPUT链的默认策略设置为拒绝:
当INPUT链默认规则设置为拒绝时,我们需要写入允许的规则策略。
这个动作的目地是当接收到数据包时,按顺序匹配所有的允许规则策略,当全部规则都不匹配时,拒绝这个数据包。
[root@linuxprobe ~]# iptables -P INPUT DROP
允许所有的ping操作:
[root@linuxprobe ~]# iptables -I INPUT -p icmp -j ACCEPT
在INPUT链的末尾加入一条规则,允许所有未被其他规则匹配上的数据包:
因为默认规则表就是filter,所以其中的"-t filter"一般省略不写,效果是一样的。
[root@linuxprobe ~]# iptables -t filter -A INPUT -j ACCEPT
删除上面的那条规则:
[root@linuxprobe ~]# iptables -D INPUT 2
既然读者已经掌握了iptables命令的基本参数,那么来尝试解决模拟训练吧:
模拟训练A:仅允许来自于192.168.10.0/24域的用户连接本机的ssh服务。
Iptables防火墙会按照顺序匹配规则,请一定要保证“允许”规则是在“拒绝”规则的上面。
[root@linuxprobe ~]# iptables -I INPUT -s 192.168.10.0/24 -p tcp --dport 22 -j ACCEPT [root@linuxprobe ~]# iptables -A INPUT -p tcp --dport 22 -j REJECT
模拟训练B:不允许任何用户访问本机的12345端口。
[root@linuxprobe ~]# iptables -I INPUT -p tcp --dport 12345 -j REJECT [root@linuxprobe ~]# iptables -I INPUT -p udp --dport 12345 -j REJECT
模拟实验C(答案模式):拒绝其他用户从"eno16777736"网卡访问本机http服务的数据包。
答案:[rootlinuxprobe ~]# iptables -I INPUT -i eno16777736 -p tcp --dport 80 -j REJECT
模拟训练D:禁止用户访问www.my133t.org。
[root@linuxprobe ~]# iptables -I FORWARD -d www.my133t.org -j DROP
模拟训练E:禁止IP地址是192.168.10.10的用户上网
[root@linuxprobe ~]# iptables -I FORWARD -s 192.168.10.10 -j DROP
iptables命令执行后的规则策略仅当前生效,若想重启后依然保存规则需执行"service iptables save"。
另外流量均衡技术也是常用的技术,比如将一台主机作为网站的前端服务器,将访问流量分流至内网中3台不同的主机上。
iptables -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.10.11:80
iptables -A PREROUTING -i eth0 -p tcp --dport 80 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.10.12:80
8.2.3 SNAT与DNAT
SNAT即源地址转换技术,能够让多个内网用户通过一个外网地址上网,解决了IP资源匮乏的问题,确实很实用。
例如读者们来访问《Linux就该这么学》的网页,则就是通过家中的网关设备(您的无线路由器)进行的SNAT转换。
(多用户局域网共享上网的拓扑)
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
出现问题?大胆提问!
因读者们硬件不同或操作错误都可能导致实验配置出错,请耐心再仔细看看操作步骤吧,不要气馁~
Linux技术交流请加A群:560843(满),B群:340829(推荐),点此查看全国群。
*本群特色:通过口令验证确保每一个群员都是《Linux就该这么学》的读者,答疑更有针对性,不定期免费领取定制礼品。
8.3 Firewalld防火墙
Firewalld服务是红帽RHEL7系统中默认的防火墙管理工具,特点是拥有运行时配置与永久配置选项且能够支持动态更新以及"zone"的区域功能概念,使用图形化工具firewall-config或文本管理工具firewall-cmd,下面实验中会讲到~
8.3.1 区域概念与作用
防火墙的网络区域定义了网络连接的可信等级,我们可以根据不同场景来调用不同的firewalld区域,区域规则有:
区域 | 默认规则策略 |
trusted | 允许所有的数据包。 |
home | 拒绝流入的数据包,除非与输出流量数据包相关或是ssh,mdns,ipp-client,samba-client与dhcpv6-client服务则允许。 |
internal | 等同于home区域 |
work | 拒绝流入的数据包,除非与输出流量数据包相关或是ssh,ipp-client与dhcpv6-client服务则允许。 |
public | 拒绝流入的数据包,除非与输出流量数据包相关或是ssh,dhcpv6-client服务则允许。 |
external | 拒绝流入的数据包,除非与输出流量数据包相关或是ssh服务则允许。 |
dmz | 拒绝流入的数据包,除非与输出流量数据包相关或是ssh服务则允许。 |
block | 拒绝流入的数据包,除非与输出流量数据包相关。 |
drop | 拒绝流入的数据包,除非与输出流量数据包相关。 |
8.3.2 字符管理工具
如果想要更高效的配置妥当防火墙,那么就一定要学习字符管理工具firewall-cmd命令,命令参数有:
参数 | 作用 |
--get-default-zone | 查询默认的区域名称。 |
--set-default-zone=<区域名称> | 设置默认的区域,永久生效。 |
--get-zones | 显示可用的区域。 |
--get-services | 显示预先定义的服务。 |
--get-active-zones | 显示当前正在使用的区域与网卡名称。 |
--add-source= | 将来源于此IP或子网的流量导向指定的区域。 |
--remove-source= | 不再将此IP或子网的流量导向某个指定区域。 |
--add-interface=<网卡名称> | 将来自于该网卡的所有流量都导向某个指定区域。 |
--change-interface=<网卡名称> | 将某个网卡与区域做关联。 |
--list-all | 显示当前区域的网卡配置参数,资源,端口以及服务等信息。 |
--list-all-zones | 显示所有区域的网卡配置参数,资源,端口以及服务等信息。 |
--add-service=<服务名> | 设置默认区域允许该服务的流量。 |
--add-port=<端口号/协议> | 允许默认区域允许该端口的流量。 |
--remove-service=<服务名> | 设置默认区域不再允许该服务的流量。 |
--remove-port=<端口号/协议> | 允许默认区域不再允许该端口的流量。 |
--reload | 让“永久生效”的配置规则立即生效,覆盖当前的。 |
特别需要注意的是firewalld服务有两份规则策略配置记录,必需要能够区分:
RunTime:当前正在生效的。
Permanent:永久生效的。
当下面实验修改的是永久生效的策略记录时,必须执行"--reload"参数后才能立即生效,否则要重启后再生效。
查看当前的区域:
[root@linuxprobe ~]# firewall-cmd --get-default-zone public
查询eno16777728网卡的区域:
[root@linuxprobe ~]# firewall-cmd --get-zone-of-interface=eno16777728 public
在public中分别查询ssh与http服务是否被允许:
[root@linuxprobe ~]# firewall-cmd --zone=public --query-service=ssh yes [root@linuxprobe ~]# firewall-cmd --zone=public --query-service=http no
设置默认规则为dmz:
[root@linuxprobe ~]# firewall-cmd --set-default-zone=dmz
让“永久生效”的配置文件立即生效:
[root@linuxprobe ~]# firewall-cmd --reload success
启动/关闭应急状况模式,阻断所有网络连接:
应急状况模式启动后会禁止所有的网络连接,一切服务的请求也都会被拒绝,当心,请慎用。
[root@linuxprobe ~]# firewall-cmd --panic-on success [root@linuxprobe ~]# firewall-cmd --panic-off success
如果您已经能够完全理解上面练习中firewall-cmd命令的参数作用,不妨来尝试完成下面的模拟训练吧:
模拟训练A:允许https服务流量通过public区域,要求立即生效且永久有效:
方法一:分别设置当前生效与永久有效的规则记录:
[root@linuxprobe ~]# firewall-cmd --zone=public --add-service=https [root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-service=https
方法二:设置永久生效的规则记录后读取记录:
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-service=https [root@linuxprobe ~]# firewall-cmd --reload
模拟训练B:不再允许http服务流量通过public区域,要求立即生效且永久生效:
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --remove-service=http success
使用参数"--reload"让永久生效的配置文件立即生效:
[root@linuxprobe ~]# firewall-cmd --reload success
模拟训练C:允许8080与8081端口流量通过public区域,立即生效且永久生效:
[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-port=8080-8081/tcp [root@linuxprobe ~]# firewall-cmd --reload
模拟训练D:查看模拟实验C中要求加入的端口操作是否成功:
[root@linuxprobe ~]# firewall-cmd --zone=public --list-ports 8080-8081/tcp [root@linuxprobe ~]# firewall-cmd --permanent --zone=public --list-ports 8080-8081/tcp
模拟实验E:将eno16777728网卡的区域修改为external,重启后生效:
[root@linuxprobe ~]# firewall-cmd --permanent --zone=external --change-interface=eno16777728 success [root@linuxprobe ~]# firewall-cmd --get-zone-of-interface=eno16777728 public
①:选择"立即生效"或"重启后依然生效"配置。
②:区域列表。
③:服务列表。
④:当前选中的区域。
⑤:被选中区域的服务。
⑥:被选中区域的端口。
⑦:被选中区域的伪装。
⑧:被选中区域的端口转发。
⑨:被选中区域的ICMP包。
⑩:被选中区域的富规则。
⑪:被选中区域的网卡设备。
⑫:被选中区域的服务,前面有√的表示允许。
⑬:firewalld防火墙的状态
8.4 服务的访问控制列表
Tcp_wrappers(即Transmission Control Protocol(TCP)Wrappers)是一款基于IP层的ACL访问控制列表流量监控程序,它能够根据来访主机地址与本机目标服务程序做允许或拒绝规则,控制列表修改后会立即生效,系统将会先检查允许规则,如果匹配允许则直接放行流量,若拒绝规则中匹配则直接拒绝,都不匹配默认也会放行。
允许名单:/etc/hosts.allow
拒绝名单:/etc/hosts.deny
指定客户端的规则如下:
客户端类型 | 示例 | 满足示例的客户端列表 |
单一主机 | 192.168.10.10 | IP地址为192.168.10.10的主机。 |
指定网段 | 192.168.10. | IP段为192.168.10.0/24的主机。 |
指定网段 | 192.168.10.0/255.255.255.0 | IP段为192.168.10.0/24的主机。 |
指定DNS后缀 | .linuxprobe.com | 所有DNS后缀为.linuxprobe.com的主机 |
指定主机名称 | boss.linuxprobe.com | 主机名称为boss.linuxprobe.com的主机。 |
指定所有客户端 | ALL | 所有主机全部包括在内。 |
限制只有192.168.10.0/24网段的主机可以访问本机的httpd服务:
编辑允许规则:
[root@linuxprobe ~]# vim /etc/hosts.allow httpd:192.168.10.
拒绝其他所有的主机:
[root@linuxprobe ~]# vim /etc/hosts.deny httpd:*