第7章 使用RAID与LVM磁盘阵列技术
7.1 RAID磁盘冗余阵列
RAID(Redundant Array of Independent Disks,独立冗余磁盘阵列)技术通过把多个硬盘设备组合成一个容量更大、安全性更好的磁盘阵列,并把数据切割成多个区段后分别存放在各个不同的物理硬盘设备上,然后利用分散读写技术来提升磁盘阵列整体的性能,同时把多个重要数据的副本同步到不同的物理硬盘设备上,从而起到了非常好的数据冗余备份效果。
目前已有的RAID磁盘阵列的方案至少有十几种,而接下来会详细讲解RAID 0、RAID 1、RAID 5与RAID 10这4种最常见的方案。
1. RAID 0
RAID 0技术把多块物理硬盘设备(至少两块)通过硬件或软件的方式串联在一起,组成一个大的卷组,并将数据依次写入到各个物理硬盘中。在最理想的状态下,硬盘设备的读写性能会提升数倍,但是若任意一块硬盘发生故障将导致整个系统的数据都受到破坏。通俗来说,RAID 0技术能够有效地提升硬盘数据的吞吐速度,但是不具备数据备份和错误修复能力。如图7-1所示,数据被分别写入到不同的硬盘设备中,即disk1和disk2硬盘设备会分别保存数据资料,最终实现提升读取、写入速度的效果。
2. RAID 1
尽管RAID 0技术提升了硬盘设备的读写速度,但是它是将数据依次写入到各个物理硬盘中,也就是说,它的数据是分开存放的,其中任何一块硬盘发生故障都会损坏整个系统的数据。因此,如果生产环境对硬盘设备的读写速度没有要求,而是希望增加数据的安全性时,就需要用到RAID 1技术了。
在图7-2所示的RAID 1技术示意图中可以看到,它是把两块以上的硬盘设备进行绑定,在写入数据时,是将数据同时写入到多块硬盘设备上(可以将其视为数据的镜像或备份)。当其中某一块硬盘发生故障后,一般会立即自动以热交换的方式来恢复数据的正常使用。
RAID 1技术虽然十分注重数据的安全性,但是因为是在多块硬盘设备中写入了相同的数据,因此硬盘设备的利用率得以下降,从理论上来说,图7-2所示的硬盘空间的真实可用率只有50%,由三块硬盘设备组成的RAID 1磁盘阵列的可用率只有33%左右,以此类推。而且,由于需要把数据同时写入到两块以上的硬盘设备,这无疑也在一定程度上增大了系统计算功能的负载。
那么,有没有一种RAID方案既考虑到了硬盘设备的读写速度和数据安全性,还兼顾了成本问题呢?实际上,单从数据安全和成本问题上来讲,就不可能在保持原有硬盘设备的利用率且还不增加新设备的情况下,能大幅提升数据的安全性。下面将要讲解的RAID 5技术虽然在理论上兼顾了三者(读写速度、数据安全性、成本),但实际上更像是对这三者的“相互妥协”。
3. RAID 5
如图7-3所示,RAID5技术是把硬盘设备的数据奇偶校验信息保存到其他硬盘设备中。RAID 5磁盘阵列组中数据的奇偶校验信息并不是单独保存到某一块硬盘设备中,而是存储到除自身以外的其他每一块硬盘设备上,这样的好处是其中任何一设备损坏后不至于出现致命缺陷;图7-3中parity部分存放的就是数据的奇偶校验信息,换句话说,就是RAID 5技术实际上没有备份硬盘中的真实数据信息,而是当硬盘设备出现问题后通过奇偶校验信息来尝试重建损坏的数据。RAID这样的技术特性“妥协”地兼顾了硬盘设备的读写速度、数据安全性与存储成本问题。
4. RAID 10
鉴于RAID 5技术是因为硬盘设备的成本问题对读写速度和数据的安全性能而有了一定的妥协,但是大部分企业更在乎的是数据本身的价值而非硬盘价格,因此生产环境中主要使用RAID 10技术。
顾名思义,RAID 10技术是RAID 1+RAID 0技术的一个“组合体”。如图7-4所示,RAID 10技术需要至少4块硬盘来组建,其中先分别两两制作成RAID 1磁盘阵列,以保证数据的安全性;然后再对两个RAID 1磁盘阵列实施RAID 0技术,进一步提高硬盘设备的读写速度。这样从理论上来讲,只要坏的不是同一组中的所有硬盘,那么最多可以损坏50%的硬盘设备而不丢失数据。由于RAID 10技术继承了RAID 0的高读写速度和RAID 1的数据安全性,在不考虑成本的情况下RAID 10的性能都超过了RAID 5,因此当前成为广泛使用的一种存储技术。
7.1.1 部署磁盘阵列
mdadm命令用于管理Linux系统中的软件RAID硬盘阵列,格式为“mdadm [模式] <RAID设备名称> [选项] [成员设备名称]”。
mdadm命令的常用参数以及作用如表7-1所示:
接下来,使用mdadm命令创建RAID 10,名称为“/dev/md0”。
第6章中讲到,udev是Linux系统内核中用来给硬件命名的服务,其命名规则也非常简单。我们可以通过命名规则猜测到第二个SCSI存储设备的名称会是/dev/sdb,然后依此类推。使用硬盘设备来部署RAID磁盘阵列很像是将几位同学组成一个班级,但总不能将班级命名为/dev/sdbcde吧。尽管这样可以一眼看出它是由哪些元素组成的,但是并不利于我们的记忆和阅读。更何况如果我们是使用10、50、100个硬盘来部署RAID磁盘阵列呢?
此时,就需要使用mdadm中的参数了。其中,-C参数代表创建一个RAID阵列卡;-v参数显示创建的过程,同时在后面追加一个设备名称/dev/md0,这样/dev/md0就是创建后的RAID磁盘阵列的名称;-a yes参数代表自动创建设备文件;-n 4参数代表使用4块硬盘来部署这个RAID磁盘阵列;而-l 10参数则代表RAID 10方案;最后再加上4块硬盘设备的名称就搞定了。
其次,把制作好的RAID磁盘阵列格式化为ext4格式。
再次,创建挂载点然后把硬盘设备进行挂载操作。挂载成功后可看到可用空间为40GB。
最后,查看/dev/md0磁盘阵列的详细信息,并把挂载信息写入到配置文件中,使其永久生效。
7.1.2 损坏磁盘阵列及修复
在生产环境中部署RAID10磁盘阵列组目的就是为了提高存储设备的IO读写速度及数据的安全性,但因为这次是在本机电脑上模拟出来的硬盘设备所以对于读写速度的改善可能并不直观,RAID磁盘阵列组损坏后的处理方法:首先确认有一块物理硬盘设备出现损坏不能再继续正常使用后,应该使用mdadm命令来予以移除之后查看下RAID磁盘阵列组的状态已经被改变:
在RAID 10级别的磁盘阵列中,当RAID 1磁盘阵列中存在一个故障盘时并不影响RAID 10磁盘阵列的使用。当购买了新的硬盘设备后再使用mdadm命令来予以替换即可,在此期间我们可以在/RAID目录中正常地创建或删除文件。由于我们是在虚拟机中模拟硬盘,所以先重启系统,然后再把新的硬盘添加到RAID磁盘阵列中。
7.1.3 磁盘阵列+备份盘
RAID 10磁盘阵列中最多允许50%的硬盘设备发生故障,但是存在这样一种极端情况,即同一RAID 1磁盘阵列中的硬盘设备若全部损坏,也会导致数据丢失。换句话说,在RAID 10磁盘阵列中,如果RAID 1中的某一块硬盘出现了故障,而我们正在前往修复的路上,恰巧该RAID1磁盘阵列中的另一块硬盘设备也出现故障,那么数据就被彻底丢失了。
在这样的情况下,该怎么办呢?其实,我们完全可以使用RAID备份盘技术来预防这类事故。该技术的核心理念就是准备一块足够大的硬盘,这块硬盘平时处于闲置状态,一旦RAID磁盘阵列中有硬盘出现故障后则会马上自动顶替上去。
为了避免多个实验之间相互发生冲突,我们需要保证每个实验的相对独立性,为此需要大家自行将虚拟机还原到初始状态。另外,由于刚才已经演示了RAID 10磁盘阵列的部署方法,我们现在来看一下RAID 5的部署效果。部署RAID 5磁盘阵列时,至少需要用到3块硬盘,还需要再加一块备份硬盘,所以总计需要在虚拟机中模拟4块硬盘设备,如图7-6所示。
现在创建一个RAID 5磁盘阵列+备份盘。在下面的命令中,参数-n 3代表创建这个RAID 5磁盘阵列所需的硬盘数,参数-l 5代表RAID的级别,而参数-x 1则代表有一块备份盘。当查看/dev/md0(即RAID 5磁盘阵列的名称)磁盘阵列的时候就能看到有一块备份盘在等待中了。
现在将部署好的RAID 5磁盘阵列格式化为ext4文件格式,然后挂载到目录上,之后就可以使用了。
最后是见证奇迹的时刻!我们再次把硬盘设备/dev/sdb移出磁盘阵列,然后迅速查看/dev/md0磁盘阵列的状态,就会发现备份盘已经被自动顶替上去并开始了数据同步。RAID中的这种备份盘技术非常实用,可以在保证RAID磁盘阵列数据安全性的基础上进一步提高数据可靠性,所以,如果公司不差钱的话还是再买上一块备份盘以防万一。
7.2 LVM逻辑卷管理器
LVM可以允许用户对硬盘资源进行动态调整。逻辑卷管理器是Linux系统用于对硬盘分区进行管理的一种机制,理论性较强,其创建初衷是为了解决硬盘设备在创建分区后不易修改分区大小的缺陷。尽管对传统的硬盘分区进行强制扩容或缩容从理论上来讲是可行的,但是却可能造成数据的丢失。而LVM技术是在硬盘分区和文件系统之间添加了一个逻辑层,它提供了一个抽象的卷组,可以把多块硬盘进行卷组合并。这样一来,用户不必关心物理硬盘设备的底层架构和布局,就可以实现对硬盘分区的动态调整。LVM的技术架构如图7-7所示。
为了帮助大家理解,举一个吃货的例子。比如小明家里想吃馒头但是面粉不够了,于是妈妈从隔壁老王家、老李家、老张家分别借来一些面粉,准备蒸馒头吃。首先需要把这些面粉(物理卷[PV,Physical Volume])揉成一个大面团(卷组[VG,Volume Group]),然后再把这个大面团分割成一个个小馒头(逻辑卷[LV,Logical Volume]),而且每个小馒头的重量必须是每勺面粉(基本单元[PE,Physical Extent])的倍数。
物理卷处于LVM中的最底层,可以将其理解为物理硬盘、硬盘分区或者RAID磁盘阵列,这都可以。卷组建立在物理卷之上,一个卷组可以包含多个物理卷,而且在卷组创建之后也可以继续向其中添加新的物理卷。逻辑卷是用卷组中空闲的资源建立的,并且逻辑卷在建立后可以动态地扩展或缩小空间。这就是LVM的核心理念。
7.2.1 部署逻辑卷
一般而言,在生产环境中无法精确地评估每个硬盘分区在日后的使用情况,因此会导致原先分配的硬盘分区不够用。比如,伴随着业务量的增加,用于存放交易记录的数据库目录的体积也随之增加;因为分析并记录用户的行为从而导致日志目录的体积不断变大,这些都会导致原有的硬盘分区在使用上捉襟见肘。而且,还存在对较大的硬盘分区进行精简缩容的情况。
我们可以通过部署LVM来解决上述问题。部署LVM时,需要逐个配置物理卷、卷组和逻辑卷。常用的部署命令如表7-2所示。
7.2.2 扩容逻辑卷
在前面的实验中,卷组是由两块硬盘设备共同组成的。用户在使用存储设备时感知不到设备底层的架构和布局,更不用关心底层是由多少块硬盘组成的,只要卷组中有足够的资源,就可以一直为逻辑卷扩容。扩展前请一定要记得卸载设备和挂载点的关联。
7.2.3 缩小逻辑卷
相较于扩容逻辑卷,在对逻辑卷进行缩容操作时,其丢失数据的风险更大。所以在生产环境中执行相应操作时,一定要提前备份好数据。另外Linux系统规定,在对LVM逻辑卷进行缩容操作之前,要先检查文件系统的完整性(当然这也是为了保证我们的数据安全)。在执行缩容操作前记得先把文件系统卸载掉。
7.2.4 逻辑卷快照
LVM还具备有“快照卷”功能,该功能类似于虚拟机软件的还原时间点功能。例如,可以对某一个逻辑卷设备做一次快照,如果日后发现数据被改错了,就可以利用之前做好的快照卷进行覆盖还原。LVM的快照卷功能有两个特点:
快照卷的容量必须等同于逻辑卷的容量;
快照卷仅一次有效,一旦执行还原操作后则会被立即自动删除。
7.2.5 删除逻辑卷
当生产环境中想要重新部署LVM或者不再需要使用LVM时,则需要执行LVM的删除操作。为此,需要提前备份好重要的数据信息,然后依次删除逻辑卷、卷组、物理卷设备,这个顺序不可颠倒。
第8章 Iptables与Firewalld防火墙
8.1 防火墙管理工具
在公网与企业内网之间充当保护屏障的防火墙(见图8-1)虽然有软件或硬件之分,但主要功能都是依据策略对穿越防火墙自身的流量进行过滤。防火墙策略可以基于流量的源目地址、端口号、协议、应用等信息来定制,然后防火墙使用预先定制的策略规则监控出入的流量,若流量与某一条策略规则相匹配,则执行相应的处理,反之则丢弃。这样一来,就可以保证仅有合法的流量在企业内网和外部公网之间流动了。
在RHEL 7系统中,firewalld防火墙取代了iptables防火墙。对于接触Linux系统比较早或学习过RHEL 6系统的读者来说,当他们发现曾经掌握的知识在RHEL 7中不再适用,需要全新学习firewalld时,难免会有抵触心理。其实,iptables与firewalld都不是真正的防火墙,它们都只是用来定义防火墙策略的防火墙管理工具而已,或者说,它们只是一种服务。
iptables服务会把配置好的防火墙策略交由内核层面的netfilter网络过滤器来处理,而firewalld服务则是把配置好的防火墙策略交由内核层面的nftables包过滤框架来处理。换句话说,当前在Linux系统中其实存在多个防火墙管理工具,旨在方便运维人员管理Linux系统中的防火墙策略,我们只需要配置妥当其中的一个就足够了。
8.2 Iptables
在早期的Linux系统中,默认使用的是iptables防火墙管理服务来配置防火墙。尽管新型的firewalld防火墙管理服务已经被投入使用多年,但是大量的企业在生产环境中依然出于各种原因而继续使用iptables。
8.2.1 策略与规则链
防火墙会从上至下的顺序来读取配置的策略规则,在找到匹配项后就立即结束匹配工作并去执行匹配项中定义的行为(即放行或阻止)。如果在读取完所有的策略规则之后没有匹配项,就去执行默认的策略。
一般而言,防火墙策略规则的设置有两种:一种是“通”(即放行),一种是“堵”(即阻止)。当防火墙的默认策略为拒绝时(堵),就要设置允许规则(通),否则谁都进不来;如果防火墙的默认策略为允许时,就要设置拒绝规则,否则谁都能进来,防火墙也就失去了防范的作用。
iptables服务把用于处理或过滤流量的策略条目称之为规则,多条规则可以组成一个规则链,而规则链则依据数据包处理位置的不同进行分类,具体如下:
在进行路由选择前处理数据包(PREROUTING);
处理流入的数据包(INPUT);
处理流出的数据包(OUTPUT);
处理转发的数据包(FORWARD);
在进行路由选择后处理数据包(POSTROUTING)。
一般来说,从内网向外网发送的流量一般都是可控且良性的,因此我们使用最多的就是INPUT规则链,该规则链可以增大黑客人员从外网入侵内网的难度。
比如在您居住的社区内,物业管理公司有两条规定:禁止小商小贩进入社区;各种车辆在进入社区时都要登记。显而易见,这两条规定应该是用于社区的正门的(流量必须经过的地方),而不是每家每户的防盗门上。根据前面提到的防火墙策略的匹配顺序,可能会存在多种情况。比如,来访人员是小商小贩,则直接会被物业公司的保安拒之门外,也就无需再对车辆进行登记。如果来访人员乘坐一辆汽车进入社区正门,则“禁止小商小贩进入社区”的第一条规则就没有被匹配到,因此按照顺序匹配第二条策略,即需要对车辆进行登记。如果是社区居民要进入正门,则这两条规定都不会匹配到,因此会执行默认的放行策略。
但是,仅有策略规则还不能保证社区的安全,保安还应该知道采用什么样的动作来处理这些匹配的流量,比如“允许”、“拒绝”、“登记”、“不理它”。这些动作对应到iptables服务的术语中分别是ACCEPT(允许流量通过)、REJECT(拒绝流量通过)、LOG(记录日志信息)、DROP(拒绝流量通过)。“允许流量通过”和“记录日志信息”都比较好理解,这里需要着重讲解的是REJECT和DROP的不同点。就DROP来说,它是直接将流量丢弃而且不响应;REJECT则会在拒绝流量后再回复一条“您的信息已经收到,但是被扔掉了”信息,从而让流量发送方清晰地看到数据被拒绝的响应信息。
我们来举一个例子,让各位读者更直观地理解这两个拒绝动作的不同之处。比如有一天您正在家里看电视,突然听到有人敲门,您透过防盗门的猫眼一看是推销商品的,便会在不需要的情况下开门并拒绝他们(REJECT)。但如果您看到的是债主带了十几个小弟来讨债,此时不仅要拒绝开门,还要默不作声,伪装成自己不在家的样子(DROP)。
当把Linux系统中的防火墙策略设置为REJECT拒绝动作后,流量发送方会看到端口不可达的响应:
而把Linux系统中的防火墙策略修改成DROP拒绝动作后,流量发送方会看到响应超时的提醒。但是流量发送方无法判断流量是被拒绝,还是接收方主机当前不在线:
8.2.2 基本的命令参数
iptables是一款基于命令行的防火墙策略管理工具,iptables命令可以根据流量的源地址、目的地址、传输协议、服务类型等信息进行匹配,一旦匹配成功,iptables就会根据策略规则所预设的动作来处理这些流量。
防火墙策略规则的匹配顺序是从上至下的,因此要把较为严格、优先级较高的策略规则放到前面,以免发生错误。表8-1总结归纳了常用的iptables命令参数。
在iptables命令后添加-L参数查看已有的防火墙规则链:
在iptables命令后添加-F参数清空已有的防火墙规则链:
把INPUT规则链的默认策略设置为拒绝:
向INPUT链中添加允许ICMP流量进入的策略规则:
在日常运维工作中,经常会使用ping命令来检查对方主机是否在线,而向防火墙的INPUT规则链中添加一条允许ICMP流量进入的策略规则就默认允许了这种ping命令检测行为。
删除INPUT规则链中刚刚加入的那条策略(允许ICMP流量),并把默认策略设置为允许:
将INPUT规则链设置为只允许指定网段的主机访问本机的22端口,拒绝来自其他所有主机的流量:
在设置完上述INPUT规则链之后,我们使用IP地址在192.168.10.0/24网段内的主机访问服务器(即前面提到的设置了INPUT规则链的主机)的22端口,效果如下:
然后,我们再使用IP地址在192.168.20.0/24网段内的主机访问服务器的22端口(虽网段不同,但已确认可以相互通信),效果如下,就会提示连接请求被拒绝(Connection failed):
有关iptables命令的知识讲解到此就结束了,大家是不是意犹未尽?考虑到Linux防火墙的发展趋势,大家只要能把上面的实例吸收消化,就可以完全搞定日常的iptables配置工作了。但是请特别注意,使用iptables命令配置的防火墙规则默认会在系统下一次重启时失效,如果想让配置的防火墙策略永久生效,还要执行保存命令:
8.3 Firewalld
RHEL 7系统中集成了多款防火墙管理工具,其中firewalld(Dynamic Firewall Manager of Linux systems,Linux系统的动态防火墙管理器)服务是默认的防火墙配置管理工具,它拥有基于CLI(命令行界面)和基于GUI(图形用户界面)的两种管理方式。
相较于传统的防火墙管理配置工具,firewalld支持动态更新技术并加入了区域(zone)的概念。简单来说,区域就是firewalld预先准备了几套防火墙策略集合(策略模板),用户可以根据生产场景的不同而选择合适的策略集合,从而实现防火墙策略之间的快速切换。例如,我们有一台笔记本电脑,每天都要在办公室、咖啡厅和家里使用。按常理来讲,这三者的安全性按照由高到低的顺序来排列,应该是家庭、公司办公室、咖啡厅。当前,我们希望为这台笔记本电脑指定如下防火墙策略规则:在家中允许访问所有服务;在办公室内仅允许访问文件共享服务;在咖啡厅仅允许上网浏览。在以往,我们需要频繁地手动设置防火墙策略规则,而现在只需要预设好区域集合,然后只需轻点鼠标就可以自动切换了,从而极大地提升了防火墙策略的应用效率。
firewalld中常见的区域名称(默认为public)以及相应的策略规则如表8-2所示。
8.3.1 终端管理工具
第2章在讲解Linux命令时曾经听到,命令行终端是一种极富效率的工作方式,firewall-cmd是firewalld防火墙配置管理工具的CLI(命令行界面)版本。它的参数一般都是以“长格式”来提供的,大家不要一听到长格式就头大,因为RHEL 7系统支持部分命令的参数补齐,其中就包含这条命令(很酷吧)。也就是说,现在除了能用Tab键自动补齐命令或文件名等内容之外,还可以用Tab键来补齐表8-3中所示的长格式参数了(这太棒了)。
与Linux系统中其他的防火墙策略配置工具一样,使用firewalld配置的防火墙策略默认为运行时(Runtime)模式,又称为当前生效模式,而且随着系统的重启会失效。如果想让配置策略一直存在,就需要使用永久(Permanent)模式了,方法就是在用firewall-cmd命令正常设置防火墙策略时添加--permanent参数,这样配置的防火墙策略就可以永久生效了。但是,永久生效模式有一个“不近人情”的特点,就是使用它设置的策略只有在系统重启之后才能自动生效。如果想让配置的策略立即生效,需要手动执行firewall-cmd --reload命令。
接下来的实验都很简单,但是提醒大家一定要仔细查看使用的是Runtime模式还是Permanent模式。如果不关注这个细节,就算是正确配置了防火墙策略,也可能无法达到预期的效果。
查看firewalld服务当前所使用的区域:
查询eno16777728网卡在firewalld服务中的区域:
把firewalld服务中eno16777728网卡的默认区域修改为external,并在系统重启后生效。分别查看当前与永久模式下的区域名称:
把firewalld服务的当前默认区域设置为public:
启动/关闭firewalld防火墙服务的应急状况模式,阻断一切网络连接(当远程控制服务器时请慎用):
查询public区域是否允许请求SSH和HTTPS协议的流量:
把firewalld服务中请求HTTPS协议的流量设置为永久允许,并立即生效:
把firewalld服务中请求HTTP协议的流量设置为永久拒绝,并立即生效:
把在firewalld服务中访问8080和8081端口的流量策略设置为允许,但仅限当前生效:
把原本访问本机888端口的流量转发到22端口,要且求当前和长期均有效:
流量转发命令格式为firewall-cmd --permanent --zone=<区域> --add-forward-port=port=<源端口号>:proto=<协议>:toport=<目标端口号>:toaddr=<目标IP地址>
在客户端使用ssh命令尝试访问192.168.10.10主机的888端口:
firewalld中的富规则表示更细致、更详细的防火墙策略配置,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置。它的优先级在所有的防火墙策略中也是最高的。比如,我们可以在firewalld服务中配置一条富规则,使其拒绝192.168.10.0/24网段的所有用户访问本机的ssh服务(22端口):
在客户端使用ssh命令尝试访问192.168.10.10主机的ssh服务(22端口):
8.3.2 图形管理工具
firewall-config是firewalld防火墙配置管理工具的GUI(图形用户界面)版本,几乎可以实现所有以命令行来执行的操作。毫不夸张的说,即使读者没有扎实的Linux命令基础,也完全可以通过它来妥善配置RHEL 7中的防火墙策略。firewall-config的界面如图8-2所示,其功能具体如下。
1:选择运行时(Runtime)模式或永久(Permanent)模式的配置。
2:可选的策略集合区域列表。
3:常用的系统服务列表。
4:当前正在使用的区域。
5:管理当前被选中区域中的服务。
6:管理当前被选中区域中的端口。
7:开启或关闭SNAT(源地址转换协议)技术。
8:设置端口转发策略。
9:控制请求icmp服务的流量。
10:管理防火墙的富规则。
11:管理网卡设备。
12:被选中区域的服务,若勾选相应服务前面的复选框,则表示允许与之相关的流量。
13:firewall-config工具的运行状态。
8.4 服务的访问控制列表
TCP Wrappers是RHEL 7系统中默认启用的一款流量监控程序,它能够根据来访主机的地址与本机的目标服务程序作出允许或拒绝的操作。换句话说,Linux系统中其实有两个层面的防火墙,第一种是前面讲到的基于TCP/IP协议的流量过滤工具,而TCP Wrappers服务则是能允许或禁止Linux系统提供服务的防火墙,从而在更高层面保护了Linux系统的安全运行。
TCP Wrappers服务的防火墙策略由两个控制列表文件所控制,用户可以编辑允许控制列表文件来放行对服务的请求流量,也可以编辑拒绝控制列表文件来阻止对服务的请求流量。控制列表文件修改后会立即生效,系统将会先检查允许控制列表文件(/etc/hosts.allow),如果匹配到相应的允许策略则放行流量;如果没有匹配,则去进一步匹配拒绝控制列表文件(/etc/hosts.deny),若找到匹配项则拒绝该流量。如果这两个文件全都没有匹配到,则默认放行流量。
TCP Wrappers服务的控制列表文件配置起来并不复杂,常用的参数如表8-4所示。
在配置TCP Wrappers服务时需要遵循两个原则:
编写拒绝策略规则时,填写的是服务名称,而非协议名称;
建议先编写拒绝策略规则,再编写允许策略规则,以便直观地看到相应的效果。
下面编写拒绝策略规则文件,禁止访问本机sshd服务的所有流量(无须/etc/hosts.deny文件中修改原有的注释信息):
接下来,在允许策略规则文件中添加一条规则,使其放行源自192.168.10.0/24网段,访问本机sshd服务的所有流量。可以看到,服务器立刻就放行了访问sshd服务的流量,效果非常直观:
第9章 使用ssh服 务管理远程主机
9.1 配置网卡服务
9.1.1 配置网卡参数
在4.1.3小节讲解了如何使用Vim文本编辑器来配置网络参数,其实,在RHEL 7系统中有至少5种网络的配置方法,这里教给大家的是使用nmtui命令来配置网络。
在RHEL 5、RHEL 6系统及其他大多数早期的Linux系统中,网卡的名称一直都是eth0、eth1、eth2、……,但在RHEL 7中则变成了类似于eno16777736这样的名字。不过除了网卡的名称发生变化之外,其他几乎一切照旧,因此这里演示的网络配置实验完全可以适用于各种版本的Linux系统。
在安装RHEL 7系统时默认没有激活网卡,如果各位读者有同样的情况也不用担心,只需使用Vim编辑器将网卡配置文件中的ONBOOT参数修改成yes,这样在系统重启后网卡就被激活了。
当修改完Linux系统中的服务配置文件后,并不会对服务程序立即产生效果。要想让服务程序获取到最新的配置文件,需要手动重启相应的服务,之后就可以看到网络畅通了。
9.1.2 创建网络会话
RHEL和CentOS系统默认使用NetworkManager来提供网络服务,这是一种动态管理网络配置的守护进程,能够让网络设备保持连接状态。可以使用nmcli命令来管理Network Manager服务。nmcli是一款基于命令行的网络配置工具,功能丰富,参数众多。它可以轻松地查看网络信息或网络状态:
另外,RHEL7系统支持网络会话功能,允许用户在多个配置文件中快速切换(非常类似于firewalld防火墙服务中的区域技术)。如果我们在公司网络中使用笔记本电脑时需要手动指定网络的IP地址,而回到家中则是使用DHCP自动分配IP地址。这就需要麻烦地频繁修改IP地址,但是使用了网络会话功能后一切就简单多了—只需在不同的使用环境中激活相应的网络会话,就可以实现网络配置信息的自动切换了。
可以使用nmcli命令并按照“connection add con-name type ifname”的格式来创建网络会话。假设将公司网络中的网络会话称之为company,将家庭网络中的网络会话称之为house,现在依次创建各自的网络会话。
使用con-name参数指定公司所使用的网络会话名称company,然后依次用ifname参数指定本机的网卡名称(千万要以实际环境为准,不要照抄书上的eno16777736),用autoconnect no参数设置该网络会话默认不被自动激活,以及用ip4及gw4参数手动指定网络的IP地址:
使用con-name参数指定家庭所使用的网络会话名称house。因为我们想从外部DHCP服务器自动获得IP地址,因此这里不需要进行手动指定。
在成功创建网络会话后,可以使用nmcli命令查看创建的所有网络会话:
使用nmcli命令配置过的网络会话是永久生效的,这样当我们下班回家后,顺手启用house网络会话,网卡就能自动通过DHCP获取到IP地址了。
9.1.3 绑定两块网卡
一般来讲,生产环境必须提供7×24小时的网络传输服务。借助于网卡绑定技术,不仅可以提高网络传输速度,更重要的是,还可以确保在其中一块网卡出现故障时,依然可以正常提供网络服务。假设我们对两块网卡实施了绑定技术,这样在正常工作中它们会共同传输数据,使得网络传输的速度变得更快;而且即使有一块网卡突然出现了故障,另外一块网卡便会立即自动顶替上去,保证数据传输不会中断。
常见的网卡绑定驱动有三种模式—mode0、mode1和mode6。
mode0(平衡负载模式):平时两块网卡均工作,且自动备援,但需要在与服务器本地网卡相连的交换机设备上进行端口聚合来支持绑定技术。
mode1(自动备援模式):平时只有一块网卡工作,在它故障后自动替换为另外的网卡。
mode6(平衡负载模式):平时两块网卡均工作,且自动备援,无须交换机设备提供辅助支持。
9.2 远程控制服务
9.2.1 配置sshd服务
SSH(Secure Shell)是一种能够以安全的方式提供远程登录的协议,也是目前远程管理Linux系统的首选方式。在此之前,一般使用FTP或Telnet来进行远程登录。但是因为它们以明文的形式在网络中传输账户密码和数据信息,因此很不安全。
想要使用SSH协议来远程管理Linux系统,则需要部署配置sshd服务程序。sshd是基于SSH协议开发的一款远程管理服务程序,不仅使用起来方便快捷,而且能够提供两种安全验证的方法:
基于口令的验证—用账户和密码来验证登录;
基于密钥的验证—需要在本地生成密钥对,然后把密钥对中的公钥上传至服务器,并与服务器中的公钥进行比较;该方式相较来说更安全。
“Linux系统中的一切都是文件”,因此在Linux系统中修改服务程序的运行参数,实际上就是在修改程序配置文件的过程。sshd服务的配置信息保存在/etc/ssh/sshd_config文件中。运维人员一般会把保存着最主要配置信息的文件称为主配置文件,而配置文件中有许多以井号开头的注释行,要想让这些配置参数生效,需要在修改参数后再去掉前面的#号。sshd服务配置文件中包含的重要参数如表9-1所示。
在RHEL 7系统中,已经默认安装并启用了sshd服务程序。接下来使用ssh命令进行远程连接,其格式为“ssh [参数] 主机IP地址”。要退出登录则执行exit命令。
如果禁止以root管理员的身份远程登录到服务器,则可以大大降低被黑客暴力破解密码的几率。下面进行相应配置。首先使用Vim文本编辑器打开sshd服务的主配置文件,然后把第48行#PermitRootLogin yes参数前的井号(#)去掉,并把参数值yes改成no,这样就不再允许root管理员远程登录了。记得最后保存文件并退出。
再次提醒的是,一般的服务程序并不会在配置文件修改之后立即获得最新的参数。如果想让新配置文件生效,则需要手动重启相应的服务程序。最好也将这个服务程序加入到开机启动项中,这样系统在下一次启动时,该服务程序便会自动运行,继续为用户提供服务。
9.2.2 安全密钥验证
加密是对信息进行编码和解码的技术,它通过一定的算法(密钥)将原本可以直接阅读的明文信息转换成密文形式。密钥即是密文的钥匙,有私钥和公钥之分。在传输数据时,如果担心被他人监听或截获,就可以在传输前先使用公钥对数据加密处理,然后再行传送。这样,只有掌握私钥的用户才能解密这段数据,除此之外的其他人即便截获了数据,一般也很难将其破译为明文信息。
一言以蔽之,在生产环境中使用密码进行口令验证终归存在着被暴力破解或嗅探截获的风险。如果正确配置了密钥验证方式,那么sshd服务程序将更加安全。我们下面进行具体的配置,其步骤如下。
第1步:在客户端主机中生成“密钥对”。
第2步:把客户端主机中生成的公钥文件传送至远程主机:
第3步:对服务器进行设置,使其只允许密钥验证,拒绝传统的口令验证方式。记得在修改配置文件后保存并重启sshd服务程序。
第4步:在客户端尝试登录到服务器,此时无须输入密码也可成功登录。
9.2.3 远程传输命令
scp(secure copy)是一个基于SSH协议在网络之间进行安全传输的命令,其格式为“scp [参数] 本地文件 远程帐户@远程IP地址:远程目录”。
与第2章讲解的cp命令不同,cp命令只能在本地硬盘中进行文件复制,而scp不仅能够通过网络传送数据,而且所有的数据都将进行加密处理。例如,如果想把一些文件通过网络从一台主机传递到其他主机,这两台主机又恰巧是Linux系统,这时使用scp命令就可以轻松完成文件的传递了。scp命令中可用的参数以及作用如表9-2所示。
在使用scp命令把文件从本地复制到远程主机时,首先需要以绝对路径的形式写清本地文件的存放位置。如果要传送整个文件夹内的所有数据,还需要额外添加参数-r进行递归操作。然后写上要传送到的远程主机的IP地址,远程服务器便会要求进行身份验证了。当前用户名称为root,而密码则为远程服务器的密码。如果想使用指定用户的身份进行验证,可使用用户名@主机地址的参数格式。最后需要在远程主机的IP地址后面添加冒号,并在后面写上要传送到远程主机的哪个文件夹中。只要参数正确并且成功验证了用户身份,即可开始传送工作。由于scp命令是基于SSH协议进行文件传送的,而9.2.2小节又设置好了密钥验证,因此当前在传输文件时,并不需要账户和密码。
此外,还可以使用scp命令把远程主机上的文件下载到本地主机,其命令格式为“scp [参数] 远程用户@远程IP地址:远程文件 本地目录”。例如,可以把远程主机的系统版本信息文件下载过来,这样就无须先登录远程主机,再进行文件传送了,也就省去了很多周折。
9.3 不间断会话服务
大家在学习sshd服务时,不知有没有注意到这样一个事情:当与远程主机的会话被关闭时,在远程主机上运行的命令也随之被中断。
如果我们正在使用命令来打包文件,或者正在使用脚本安装某个服务程序,中途是绝对不能关闭在本地打开的终端窗口或断开网络链接的,甚至是网速的波动都有可能导致任务中断,此时只能重新进行远程链接并重新开始任务。还有些时候,我们正在执行文件打包操作,同时又想用脚本来安装某个服务程序,这时会因为打包操作的输出信息占满用户的屏幕界面,而只能再打开一个执行远程会话的终端窗口,时间久了,难免会忘记这些打开的终端窗口是做什么用的了。
screen是一款能够实现多窗口远程控制的开源服务程序,简单来说就是为了解决网络异常中断或为了同时控制多个远程终端窗口而设计的程序。用户还可以使用screen服务程序同时在多个远程会话中自由切换,能够做到实现如下功能。
会话恢复:即便网络中断,也可让会话随时恢复,确保用户不会失去对远程会话的控制。
多窗口:每个会话都是独立运行的,拥有各自独立的输入输出终端窗口,终端窗口内显示过的信息也将被分开隔离保存,以便下次使用时依然能看到之前的操作记录。
会话共享:当多个用户同时登录到远程服务器时,便可以使用会话共享功能让用户之间的输入输出信息共享。
在RHEL 7系统中,没有默认安装screen服务程序,因此需要配置Yum仓库来安装它。首先将虚拟机的CD/DVD光盘选项设置为“使用ISO镜像文件”,并选择已经下载好的系统镜像,如图9-12所示。
9.3.1 管理远程会话
screen命令能做的事情非常多:可以用-S参数创建会话窗口;用-d参数将指定会话进行离线处理;用-r参数恢复指定会话;用-x参数一次性恢复所有的会话;用-ls参数显示当前已有的会话;以及用-wipe参数把目前无法使用的会话删除,等等。
下面创建一个名称为backup的会话窗口。请各位读者留心观察,当在命令行中敲下这条命令的一瞬间,屏幕会快速闪动一下,这时就已经进入screen服务会话中了,在里面运行的任何操作都会被后台记录下来。
执行命令后会立即返回一个提示符。虽然看起来与刚才没有不同,但实际上可以查看到当前的会话正在工作中。
要想退出一个会话也十分简单,只需在命令行中执行exit命令即可。
在日常的生产环境中,其实并不是必须先创建会话,然后再开始工作。可以直接使用screen命令执行要运行的命令,这样在命令中的一切操作也都会被记录下来,当命令执行结束后screen会话也会自动结束。
如果我们突然又想到了还有其他事情需要处理,也可以多创建几个会话窗口放在一起使用。如果这段时间内不再使用某个会话窗口,可以把它设置为临时断开(detach)模式,随后在需要时再重新连接(attach)回来即可。这段时间内,在会话窗口内运行的程序会继续执行。
9.3.2 会话共享功能
screen命令不仅可以确保用户在极端情况下也不丢失对系统的远程控制,保证了生产环境中远程工作的不间断性,而且它还具有会话共享、分屏切割、会话锁定等实用的功能。其中,会话共享功能是一件很酷的事情,当多个用户同时控制主机的时候,它可以把屏幕内容共享出来,也就是说每个用户都可以看到相同的内容。
screen的会话共享功能的流程拓扑如图9-13所示。
要实现会话共享功能,首先使用ssh服务程序将终端A远程连接到服务器,并创建一个会话窗口。
然后,使用ssh服务程序将终端B远程连接到服务器,并执行获取远程会话的命令。接下来,两台主机就能看到相同的内容了。
第10章 使用Apache服务部署静态网站
10.1 网站服务程序
Web网络服务是一种被动访问的服务程序,即只有接收到互联网中其他主机发出的请求后才会响应,最终用于提供服务程序的Web服务器会通过HTTP(超文本传输协议)或HTTPS(安全超文本传输协议)把请求的内容传送给用户。
目前能够提供Web网络服务的程序有IIS、Nginx和Apache等。其中,IIS(Internet Information Services,互联网信息服务)是Windows系统中默认的Web服务程序,这是一款图形化的网站管理工具,不仅可以提供Web网站服务,还可以提供FTP、NMTP、SMTP等服务。但是,IIS只能在Windows系统中使用,而我们这本书的名字是《Linux就该这么学》,所以它也就不在我们的学习范围之内了。
10.2 配置服务文件参数
在Linux系统中配置服务,其实就是修改服务的配置文件,因此,还需要知道这些配置文件的所在位置以及用途,httpd服务程序的主要配置文件及存放位置如表10-1所示。
在httpd服务程序的主配置文件中,存在三种类型的信息:注释行信息、全局配置、区域配置,如图10-4所示。
在httpd服务程序主配置文件中,最为常用的参数如表10-2所示。
10.3 SELinux安全子系统
SELinux(Security-Enhanced Linux)是美国国家安全局在Linux开源社区的帮助下开发的一个强制访问控制(MAC,Mandatory Access Control)的安全子系统。RHEL 7系统使用SELinux技术的目的是为了让各个服务进程都受到约束,使其仅获取到本应获取的资源。
SELinux服务有三种配置模式,具体如下。
enforcing:强制启用安全策略模式,将拦截服务的不合法请求。
permissive:遇到服务越权访问时,只发出警告而不强制拦截。
disabled:对于越权的行为不警告也不拦截。
本文中的所有实验都是在强制启用安全策略模式下进行的,虽然在禁用SELinux服务后确实能够减少报错几率,但这在生产环境中相当不推荐。建议大家检查一下自己的系统,查看SELinux服务主配置文件中定义的默认状态。如果是permissive或disabled,建议赶紧修改为enforcing。
SELinux服务的主配置文件中,定义的是SELinux的默认运行状态,可以将其理解为系统重启后的状态,因此它不会在更改后立即生效。可以使用getenforce命令获得当前SELinux服务的运行模式:
用setenforce [0|1]命令修改SELinux当前的运行模式(0为禁用,1为启用)。注意,这种修改只是临时的,在系统重启后就会失效:
现在,我们来回忆一下前面的操作中到底是哪里出问题了呢?
httpd服务程序的功能是允许用户访问网站内容,因此SELinux肯定会默认放行用户对网站的请求操作。但是,我们将网站数据的默认保存目录修改为了/home/wwwroot,而这就产生问题了。在6.1小节中讲到,/home目录是用来存放普通用户的家目录数据的,而现在,httpd提供的网站服务却要去获取普通用户家目录中的数据了,这显然违反了SELinux的监管原则。
现在,我们把SELinux服务恢复到强制启用安全策略模式,然后分别查看原始网站数据的保存目录与当前网站数据的保存目录是否拥有不同的SELinux安全上下文值:
在文件上设置的SELinux安全上下文是由用户段、角色段以及类型段等多个信息项共同组成的。其中,用户段system_u代表系统进程的身份,角色段object_r代表文件目录的角色,类型段httpd_sys_content_t代表网站服务的系统文件。由于SELinux服务实在太过复杂,现在大家只需要简单熟悉SELinux服务的作用就可以,刘遄老师未来会在本书的进阶篇中单独拿出一个章节仔细讲解SELinux服务。
针对当前这种情况,我们只需要使用semanage命令,将当前网站目录/home/wwwroot的SELinux安全上下文修改为跟原始网站目录的一样就可以了。
semanage命令
semanage命令用于管理SELinux的策略,格式为“semanage [选项] [文件]”。
SELinux服务极大地提升了Linux系统的安全性,将用户权限牢牢地锁在笼子里。semanage命令不仅能够像传统chcon命令那样—设置文件、目录的策略,还可以管理网络端口、消息接口(这些新特性将在本章后文中涵盖)。使用semanage命令时,经常用到的几个参数及其功能如下所示:
-l参数用于查询;
-a参数用于添加;
-m参数用于修改;
-d参数用于删除。
10.4 个人用户主页功能
10.5 虚拟网站主机功能
10.6 Apache的访问控制
Apache可以基于源主机名、源IP地址或源主机上的浏览器特征等信息对网站上的资源进行访问控制。它通过Allow指令允许某个主机访问服务器上的网站资源,通过Deny指令实现禁止访问。在允许或禁止访问网站资源时,还会用到Order指令,这个指令用来定义Allow或Deny指令起作用的顺序,其匹配原则是按照顺序进行匹配,若匹配成功则执行后面的默认指令。比如“Order Allow, Deny”表示先将源主机与允许规则进行匹配,若匹配成功则允许访问请求,反之则拒绝访问请求。