00:00/00:00

章节简述:

红帽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:直接丢弃,不给出任何回应.

其中REJECTDROP的操作都是将数据包拒绝,但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:在进行路由选择后处理数据包

Iptables中的规则表是用于容纳规则链规则表默认是允许状态的,那么规则链就是设置被禁止的规则,而反之如果规则表是禁止状态的,那么规则链就是设置被允许的规则。
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.10: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.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转换。

SNAT拓扑

(多用户局域网共享上网的拓扑)

(因未使用SNAT技术,所以在网站服务器应答后找不到192.168.10.10这台主机,无法正常浏览网页)
(因使用了SNAT地址转换技术,服务器应答后先由网关服务器接收,再分发给内网的用户主机。)
现在需要将"192.168.10.0"网段的内网IP用户经过地址转换技术变成外网IP地址"111.196.211.212",这样一来内网IP用户就都可以通过这个外网IP上网了,使用iptables防火墙即可实现SNAT源地址转换,根据需求命令如下:
SNAT的命令
不知读者有无这种经历,当使用联通或者电信上网的时候,每次拨号都会重新分配新的IP地址,那么若网关IP经常变动怎么办?
这种外网IP地址不稳定的情况即可使用MASQUERADE(动态伪装):能够自动的寻找外网地址并改为当前正确的外网IP地址
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
DNAT目地地址转换技术,则能够让外网IP用户访问局域网内不同的服务器。
DNAT拓扑
(互联网中的客户机访问网站时的拓扑)
DNAT的流程
(DNAT的数据包转换过程)
现在希望互联网中的客户机访问到内网"192.168.10.6"这台提供网站服务的主机,那么只需在网关系统上运行这条命令:

DNAT的命令
出现问题?大胆提问!

因读者们硬件不同或操作错误都可能导致实验配置出错,请耐心再仔细看看操作步骤吧,不要气馁~

Linux技术交流请加A群:560843(),B群:340829(推荐),C群:463590(推荐),点此查看全国群

*本群特色:通过口令验证确保每一个群员都是《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 拒绝流入的数据包,除非与输出流量数据包相关。

简单来讲就是为用户预先准备了几套规则集合,我们可以根据场景的不同选择合适的规矩集合,而默认区域是public
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

端口转发功能可以将原本到某端口的数据包转发到其他端口:

firewall-cmd --permanent --zone=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址>

将访问192.168.10.10主机888端口的请求转发至22端口:

[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-forward-port=port=888:proto=tcp:toport=22:toaddr=192.168.10.10
success

使用客户机的ssh命令访问192.168.10.10主机的888端口:

[root@linuxprobe ~]# ssh -p 888 192.168.10.10
The authenticity of host '[192.168.10.10]:888 ([192.168.10.10]:888)' can't be established.
ECDSA key fingerprint is b8:25:88:89:5c:05:b6:dd:ef:76:63:ff:1a:54:02:1a.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[192.168.10.10]:888' (ECDSA) to the list of known hosts.
root@192.168.10.10's password:
Last login: Sun Jul 19 21:43:48 2015 from 192.168.10.10

 

再次提示:请读者们再仔细琢磨下立即生效重启后依然生效的差别,千万不要修改错了。

模拟实验F:设置富规则,拒绝192.168.10.0/24网段的用户访问ssh服务:

firewalld服务的富规则用于对服务、端口、协议进行更详细的配置,规则的优先级最高

[root@linuxprobe ~]# firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.10.0/24" service name="ssh" reject"
success

 

8.3.3 图形管理工具
执行firewall-config命令即可看到firewalld的防火墙图形化管理工具,真的很强大,可以完成很多复杂的工作。
firewalld防火墙图形化管理工具界面详解:
firewall-config界面

①:选择"立即生效"或"重启后依然生效"配置。
②:区域列表。
③:服务列表。
④:当前选中的区域。
⑤:被选中区域的服务。
⑥:被选中区域的端口。
⑦:被选中区域的伪装。
⑧:被选中区域的端口转发。
⑨:被选中区域的ICMP包。
⑩:被选中区域的富规则。
⑪:被选中区域的网卡设备。
⑫:被选中区域的服务,前面有√的表示允许。
⑬:firewalld防火墙的状态

请注意:firewall-config图形化管理工具中没有保存/完成按钮,只要修改就会生效。
允许其他主机访问http服务,仅当前生效:
允许其他主机访问http服务
允许其他主机访问8080-8088端口且重启后依然生效:
允许其他主机访问8080-8088端口
重启后依然有效
开启伪装功能,重启后依然生效:
firewalld防火墙的伪装功能实际就是SNAT技术,即让内网用户不必在公网中暴露自己的真实IP地址。
开启伪装功能
将向本机888端口的请求转发至本机的22端口且重启后依然生效:

将向本机888端口的请求转发至本机的22端口

过滤所有"echo-reply"的ICMP协议报文数据包,仅当前生效:
ICMP即互联网控制报文协议"Internet Control Message Protocol",归属于TCP/IP协议族,主要用于检测网络间是否可通信、主机是否可达、路由是否可用等网络状态,并不用于传输用户数据。
过滤所有echo-reply的ICMP协议报文数据包
仅允许192.168.10.20主机访问本机的1234端口,仅当前生效:
富规则代表着更细致、更详细的规则策略,针对某个服务、主机地址、端口号等选项的规则策略,优先级最高
仅允许192.168.10.20主机访问本机的1234端口
查看网卡设备信息:
查看网卡设备信息
firewall-config图形管理工具真的非常实用,很多原本复杂的长命令被用图形化按钮替代,设置规则也变得简单了,日常工作中真的非常实用。所以有必要跟读者们讲清配置防火墙的原则——只要能实现需求的功能,无论用文本管理工具还是图形管理工具都是可以的
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网段的主机可以访问本机的sshd服务:

编辑允许规则:

[root@linuxprobe ~]# vim /etc/hosts.allow
sshd:192.168.10.

拒绝其他所有的主机:

[root@linuxprobe ~]# vim /etc/hosts.deny
sshd:*

出现问题?大胆提问!

因读者们硬件不同或操作错误都可能导致实验配置出错,请耐心再仔细看看操作步骤吧,不要气馁~

Linux技术交流请加A群:560843(),B群:340829(推荐),C群:463590(推荐),点此查看全国群

*本群特色:通过口令验证确保每一个群员都是《Linux就该这么学》的读者,答疑更有针对性,不定期免费领取定制礼品。

本章节的复习作业(答案就在问题的下一行哦,用鼠标选中即可看到的~)
1:iptables服务已经被firewalld取代,iptables命令也不能使用了?

答案:错,要区分iptables服务与iptables命令。

2:将iptables的INPUT规则链默认规则设置为REJECT。

答案:iptables -P INPUT REJECT。

3:SNAT与DNAT那个技术能够实现让多个内网用户使用单一IP地址进入公网?

答案:SNAT技术。

4:firewalld防火墙管理工具区域的作用?

答案:我们需要根据不同的场景来调用不同的firewalld区域。

5:使用firewall-cmd查询网卡eno16777728属于那个区域的命令是?

答案:firewall-cmd --get-zone-of-interface=eno16777728

刘遄

刘遄

我们懂得《Linux就该这么学》作为一本Linux入门读物,更加有责任,有必要将文章质量不断提高,知识点不断扩充,让实验更加的实用,不辜负每位读者给予我们的支持,因此我们正在全球各地部署书籍的镜像站点,想用最迅猛的访问速度满足您心中那颗求知的小宇宙,同时,向每位会员承诺,本书可永久免费学习,提供所有所需工具以及在能力范围内的答疑支持。收费培训服务:http://www.linuxprobe.com/training
刘遄