原文:
zh.annas-archive.org/md5/85DEE4E32CF6CFC6347B684FDF685546
译者:飞龙
第四章:使用 YUM 管理软件包
在本章中,我们将涵盖以下主题:
使用 YUM 更新系统
使用 YUM 搜索软件包
使用 YUM 安装软件包
使用 YUM 删除软件包
保持 YUM 的清洁和整洁
了解您的优先级
使用第三方仓库
创建 YUM 仓库
使用 RPM 软件包管理器
引言
本章是一系列教程的集合,提供了对扩展服务器所需的工具的回顾。软件包管理是任何基于 Linux 的系统的核心,本章的目的强调了在基于 CentOS 的服务器上管理软件包所需的关键工具。
使用 YUM 更新系统
在本教程中,我们将探讨Yellowdog Updater, Modified(YUM)软件包管理器在运行系统更新方面的角色。每隔一段时间,您可能会意识到有更新,或者可能只是想了解是否存在更新。应用补丁和更新是每个服务器管理员的常规任务,一个最新的系统可以帮助提高或确保您的服务器的安全性,因为软件错误和漏洞一直在被发现,并且必须及时修复。在本教程中,您将学习如何借助 YUM 实现这一点。
准备工作
要完成本教程,您需要具备具有 root 权限的 CentOS 7 操作系统的正常安装,您选择的基于控制台的文本编辑器,以及连接到互联网以便于下载额外软件包的能力。
如何操作…
您可以根据自己的选择的时间表经常运行本教程,但应该经常进行,完全了解有时某些更新可能需要完全系统重启:
以 root 身份登录并检查是否有任何适用于您已安装软件包的更新。为此,请登录并输入以下命令:
yum check-update
如果没有可用的更新,那么更新过程将结束,不需要进行进一步的工作。然而,如果有可用的更新,YUM 现在将返回来自系统已知仓库的所有软件包更新的列表。要完成更新过程,请输入以下命令:
yum -y update
通过使用
-y
标志,前面的命令现在将绕过确认交易摘要的需要,您的系统现在将立即进行更新过程。完成后,您将获得一个最终报告,该报告标识了已安装的依赖项和已更新的软件包。通常情况下,不需要进一步的工作,您可以恢复正常的操作。然而,如果安装了新的内核,或者进行了重要的安全更新,可能需要重启系统以使新的更改生效。为此,请输入以下命令:
reboot
注意
尽管关于更新是否需要在实践中进行全面系统重启存在很多争议,但这只有在进行内核更新后才需要考虑,内核更新是对
glibc
和在启动过程中激活的特定安全功能的更新。
它是如何工作的…
YUM 是 CentOS 默认的包管理器,其职责之一是自动计算哪些包可能需要更新,哪些依赖项是必需的,并以非常简单的方式管理整个系统更新过程。
那么,我们从这次经历中学到了什么?
我们通过使用yum
命令和check-update
选项检查系统是否有可用更新来开始这个配方。这样,YUM 现在将检查中央存储库以确认我们的系统是否有适用的更新。存储库是一个包含预制软件包和实用程序的远程目录或网站。YUM 将使用此设施自动定位和获取正确的Red Hat Package Manager(RPM)和依赖项,如果有可用更新,YUM 将相应地响应,提供有关哪些包和依赖项可用的完整摘要。因此,YUM 是一个非常有用的工具,毫无疑问,其机制确实简化了与包管理相关的流程,因为它可以与存储库对话,这使我们不必手动查找和安装新应用程序或更新。如果有可用更新,输出将向我们显示受影响的包,然后我们可以继续使用 YUM 的update
参数更新系统。在这种情况下,前面的命令包括-y
标志。这是为了绕过同意交易摘要的需要,并确认我们已经在运行前面的检查后同意进行这些更新。否则,你只需使用Y键确认请求。
还有更多…
你还可以使用更新参数来更新单个包而不是整个系统,只需提供包名,例如:yum update package_name
。YUM 将确保在安装应用程序时满足所有要求,并自动安装系统上尚未存在的任何依赖项的包。然而,我确信你会很高兴听到这一点,如果新应用程序有与现有软件冲突的要求,YUM 将中止过程而不对系统进行任何更改。如果你想使用特定时间间隔自动更新系统,可以安装yum-cron
包,该包可以高度定制,但超出了本书的范围。安装后启动,使用man yum-cron
。
使用 YUM 搜索包
在本食谱中,我们将研究使用 YUM 查找包的作用。YUM 是为了改进 RPM 软件包的安装而开发的,它用于访问提供服务器提供的全方位服务的不断增长的数学包列表。YUM 使用起来很简单,但如果你不确定包的名称,那么作为服务器管理员的工作就会变得更加困难。为了克服这一点,YUM 维护了广泛的发现工具,本食谱的目的是向您展示如何使用此功能来搜索各种存储库并找到您需要的包。
准备工作
要完成本食谱,您需要具有 root 权限的 CentOS 7 操作系统的工作安装、您选择的基于控制台的文本编辑器以及互联网连接。
如何做到这一点…
本食谱将向您展示如何通过调用 YUM 的搜索选项来找到一个或多个包。为此,您需要以 root 用户身份登录并完成以下过程:
要搜索单个包,请将
keyword
值替换为适当的短语、字符串或参数,然后键入以下内容:yum search keyword
等待搜索结果的摘要,当生成列表时,您可以通过简单地将
package_name
替换为适当的值来查询任何显示的包:yum info package_name
如果前面的结果令人满意,并且您想查看与该包相关的依赖项列表,请键入以下内容:
yum deplist package_name
它是如何工作的…
使用 YUM 搜索包的方式与在 万维网(WWW)上搜索任何内容的方式相同。您可以搜索的单词类型可以像您喜欢的那样具体或一般。它们甚至可以由完整或部分单词组成;找到您可能感兴趣的包后,您会注意到,本食谱还向您展示了如何发现有关该包的更多信息。
那么,我们从这次经历中学到了什么?
YUM 维护了广泛的搜索功能,允许您通过关键字、包名和路径名查询包。例如,如果您想找到编译 C、Objective-C 和 C++ 代码的正确包,可以使用 yum search compiler
查询。在命令行上使用这些搜索词时,会出现许多相关结果,每个包都附有简短描述,使我们能够通过简单的排除过程来选择最明显或最相关的值。考虑到这一点,您可以使用 info
参数向 YUM 查询以了解有关某些包的更多信息。此选项显示了完整的包详细信息以及包旨在提供的功能的详细描述。一般来说,您可能不需要知道更多细节。
然而,在某些情况下,您可能想知道该软件包如何与整个服务器交互(特别是如果您正在处理源安装或修复损坏的软件包),因此我们可以使用 YUM 的deplist
参数,它可以提供相当详细的报告;如果您碰巧有任何损坏的软件包,您可以使用此输出来详细说明您可能需要或不需要安装哪些依赖项来解决潜在问题。当调试依赖关系或处理基于源的安装时,此命令特别有用。
还有更多…
有时,您可能不想搜索特定的软件包,而是可能更愿意以目录式格式显示您存储库的内容。同样,这很容易做到,YUM 提供了以下命令来实现这一功能。如果您想简单地列出当前系统使用的存储库中所有可用的软件包,请键入yum list all
。然而,由于此列表可能非常详尽,您可能更愿意通过使用yum list all | less
来分页浏览结果。类似地,如果您只想列出系统上当前安装的所有软件,请键入yum list installed | less
。如果您想确定哪些软件包提供了特定的文件或功能,只需随时运行以下命令,将your_filename_here
替换为与您自己的需求更相关的内容:yum provides your_filename_here
。
使用 YUM 安装软件包
在本教程中,我们将探讨 YUM 在服务器上安装新软件包的作用。对于每位服务器管理员来说,安装应用程序和服务是一项重要任务。有多种方法可以实现这一点,但最有效的方法涉及使用 YUM 包管理器。YUM 能够搜索任意数量的存储库,自动解决软件包依赖关系,并指定安装一个或多个软件包。YUM 是现代且确定性的方法,用于在服务器上安装软件包,本教程的目的就是向您展示如何做到这一点。
准备工作
要完成本教程,您需要具备 CentOS 7 操作系统的有效安装,拥有 root 权限,选择一个基于控制台的文本编辑器,以及连接到互联网以便下载额外的软件包。如果您已经找到了一些有趣的软件包来安装,那么使用使用 YUM 搜索软件包教程中的说明来学习这些软件包是很好的。
如何做到这一点…
本教程将向您展示如何通过调用 YUM 安装选项来安装一个或多个软件包。为此,您需要以 root 用户身份登录并完成以下过程:
要安装单个软件包,请将
package_name
值替换为适当的值,然后键入以下内容:yum install package_name
你的系统现在将提供一个交易报告,需要你的批准。因此,当提示时,只需使用Y或N键并按Return键来接受或拒绝交易,如下所示:
Is this ok [y/d/N]: y
如果你拒绝了交易,那么不需要进行进一步的工作,你将退出软件包管理例程。然而,如果你确认了交易,那么请观察安装进度,最终它会显示一个
Complete!
消息。恭喜!你现在已经成功安装了你选择的软件包。
它是如何工作的…
所有软件包都存储在 RPM 软件包文件格式中,而 YUM 的作用是提供对存储在互联网上各种仓库中的这些文件的访问。YUM 是 CentOS 软件包管理背后的力量,它确实使得安装过程变得非常简单,但我们从这次经历中学到了什么?
调用install
命令后,YUM 将在各个仓库中进行搜索,以找到与所讨论的软件包相关的相关标题和元数据。例如,如果你想安装一个名为wget
的软件包,你将首先发出这样的install
命令:yum install wget
。然后,YUM 将定位该软件包,并生成一个交易摘要,该摘要不仅指示所需的磁盘空间和预期的安装大小,还将指示所请求的软件包所需的任何必要依赖项。YUM 将检查几个不同的仓库(base
,extras
,和updates
),并在解决了任何必要依赖项的需求后,YUM 将要求我们在继续安装过程之前确认请求。因此,正如你所见,通过使用Y键,我们将向 YUM 提供执行请求的权限,这将导致下载、验证和安装相关软件包。
还有更多…
有时你可能希望一次性安装多个软件包。要实现这一点,只需调用相同的install
命令,但不是指定单个软件包,而是以形成一个长购物清单的方式列出你可能需要的所有软件包:
yum install package_name1 package_name2 package_name3
你可以以这种方式安装的软件包数量没有限制,但始终在每个软件包名称之间留一个空格,并保持命令在一行上。对于非常长的安装指令,可能会发生行包装。
你不需要以任何特定顺序列出软件包,请求将以与原始配方完全相同的方式处理,并且在列出交易摘要后,它将保持待定状态,直到确认或拒绝。再次使用Y键确认你的请求,以便完成该过程。
使用 YUM 删除软件包
在这个食谱中,我们将探讨使用 YUM 的目的,即从你的服务器上移除软件包。在你的服务器生命周期中,某些应用程序和服务可能不再需要。在这种情况下,通常你会想要移除这些软件包以优化你的工作环境,而这个食谱的目的就是向你展示如何做到这一点。
准备工作
要完成这个食谱,你需要一个安装了 CentOS 7 操作系统的工作环境,具有 root 权限,选择一个基于控制台的文本编辑器,以及互联网连接。
如何操作…
这个食谱将向你展示如何通过调用yum remove
选项来移除一个或多个软件包。为此,你需要以 root 用户身份登录并完成以下过程:
要移除单个软件包,将
package_name
替换为适当的值,并输入以下内容:yum remove package_name
等待交易摘要和确认提示显示,然后按Y键确认,或按N键拒绝交易,如下所示:
Is this ok [y/d/N]: y
如果你拒绝了交易,那么不需要进一步的工作,你将退出 YUM。然而,如果你确认了交易,那么只需观察软件包移除的进度,直到它被确认并打印出
Complete!
消息。
它是如何工作的…
不再需要的应用程序可以通过 YUM 移除。这个过程非常直观,类似于安装新软件包,只需要你确认要移除的软件包名称。
那么,我们从这次经历中学到了什么?
调用了remove
命令后,YUM 将在你的系统中搜索相关软件包;通过阅读软件包头和元数据,它还将确定这将影响哪些依赖项。例如,如果我们想移除名为wget
的软件包,我们将开始发出remove
命令,如下所示:yum remove wget
。然后,YUM 将从你的系统中找到软件包详细信息,并获取一个交易摘要,其中可能包括任何不再需要的必要依赖项。打印出的交易将保持待定状态,直到你指示 YUM 移除相关软件包。确认后,YUM 将完成交易,这将导致移除软件包或软件包。如果摘要提到任何依赖项,你应该格外小心,因为这些可能被其他 RPM 所需。如果你担心某些依赖项应该保留在系统上,通常一个好的做法是结束当前交易,并简单地停用或禁用相关软件。与install
命令一样,你也可以一次移除多个软件包,软件包名称之间留一个空格:
yum remove package_name1 package_name2 package_name3
保持 YUM 的整洁
在这个步骤中,我们将调查 YUM 在确保工作缓存保持最新方面的作用。作为其典型操作模式的一部分,YUM 将创建一个由元数据和软件包组成的缓存。这些文件非常有用,但随着时间的推移,它们会积累到一定程度,你可能会发现 YUM 行为异常或不如预期。这种情况发生的频率因系统而异,但通常意味着 YUM 缓存系统需要你立即关注。这种情况可能会非常令人沮丧,但这个步骤的目的是提供一个快速解决方案,帮助你清理缓存并将 YUM 恢复到原始工作状态。
准备就绪
要完成这个步骤,你需要一个具有 root 权限的 CentOS 7 操作系统的工作安装,一个你选择的基于控制台的文本编辑器,以及一个互联网连接,以便于下载额外的软件包。
如何操作…
在我们开始之前,重要的是要意识到,虽然我们正在解决当前的问题,但这个相同的步骤可以按需运行,以保持 YUM 处于最佳工作状态:
我们将从这个步骤开始,让 YUM 清理任何缓存的软件包信息。为此,以 root 身份登录并输入以下内容:
yum clean packages
允许系统响应一段时间,完成后,输入以下命令以删除任何缓存的基于 XML 的元数据:
yum clean metadata
再次等待 YUM 响应,准备就绪后,输入以下命令以删除任何缓存的数据库文件:
yum clean dbcache
接下来,你需要清理所有文件以确认前面的指令,并确保不使用不必要的磁盘空间。为此,输入以下行:
yum clean all
最后,你需要通过输入以下内容来重建 YUM 缓存:
yum makecache
它是如何工作的…
YUM 是一个非常强大的工具,以其解决软件包依赖关系和自动化软件包管理过程的能力而闻名,但正如所有事物一样,有时即使是最好的工具也会感到困惑,可能会报告错误或行为异常。解决这个问题相对简单,本步骤中概述的方法也将有助于保持你的软件包管理器在你的操作系统生命周期内保持健康运行状态。
那么,我们从这次经历中学到了什么?
在 YUM 的典型运行过程中,它会在/var/cache/yum
位置创建一个元数据和包的缓存。这些文件至关重要,但随着它们的大小增长,这个缓存最终会减慢该工具的整体使用速度,甚至可能导致一些问题。为了解决这个问题,我们首先使用以下命令清理当前基于包的缓存,使用 YUM 的clean packages
参数选项。然后,我们通过执行clean metadata
命令清理元数据缓存,这将删除任何多余的基于 XML 的文件。YUM 在其正常操作中使用 SQLite 数据库,因此下一步是使用clean dbcache
参数删除任何剩余的数据库文件。接下来,我们清理所有与启用仓库相关的文件,以回收任何未使用的磁盘空间:yum clean all
。最后,我们通过使用makecache
选项重建缓存,将 YUM 恢复到正常工作状态。
还有更多…
在典型的服务器上,YUM 是一个出色的工具,它将解决与包依赖关系和包管理相关的最复杂问题。然而,在明知混合了不兼容的仓库或使用了不完整的源的情况下,YUM 可能无法提供帮助。
注意
记住,在这种情况下,你应该将以下建议视为仅是临时补救措施。忽视 YUM 提供的任何警告只会导致将来出现更大的问题。
如果发生这种情况,并且错误是基于 RPM 的,作为临时修复,你可以使用以下命令跳过损坏的包:
yum -y update --skip-broken
这个命令将允许 YUM 继续工作,绕过任何有错误的包,但正如前面所述,这应该被视为仅是临时修复。你应该始终意识到,一个依赖关系损坏的系统不被认为是一个健康的系统。这种情况应该不惜一切代价避免,在这种情况下,修复此类错误应该成为你的首要任务。
了解你的优先级
在本食谱中,我们将探讨准备 YUM 管理额外仓库的任务,通过安装一个名为YUM priorities的插件。YUM 有能力从各种远程位置搜索、删除、安装、检索和更新包。这些功能使 YUM 成为一个强大的工具,但如果你决定添加额外的第三方仓库,有可能冲突会导致系统不稳定。稳定性是使用 CentOS 操作系统的众多优势之一,本食谱的目的是展示如何在同时允许添加新仓库的情况下保持这种信心。
准备就绪
要完成这个食谱,你需要一个具有 root 权限的 CentOS 7 操作系统的正常安装,一个基于控制台的文本编辑器,以及一个互联网连接,以便下载额外的包。
如何做…
本食谱将向您展示如何准备 YUM,以便通过安装和配置 YUM 优先级来管理使用一个或多个第三方仓库的过程:
要开始这个食谱,请以 root 身份登录并输入以下内容:
yum install yum-plugin-priorities
确认安装,完成后输入以下内容:
vi /etc/yum/pluginconf.d/priorities.conf
您应该确保此文件指示插件已启用。它应该显示指令
enabled = 1
。通常不需要在此文件中进行任何更改,但如果您已进行任何更改,请在继续之前保存并关闭文件。现在我们需要为每个仓库建立一个优先级值。这是一个升序的数值,其中最高优先级被赋予最低的数字。为此,按照以下所示打开以下文件:
vi /etc/yum.repos.d/CentOS-Base.repo
在
[base]
部分末尾添加以下行:priority=1
现在,在
[updates]
部分末尾添加以下行:priority=1
最后,在
[extras]
部分末尾添加以下行:priority=1
完成后,保存并关闭文件,然后运行软件包更新:
yum update
它是如何工作的…
YUM 优先级是一个简单的插件,它使 YUM 能够决定在安装和更新新软件包时哪些仓库将具有最高优先级。使用此插件将减少软件包混淆的可能性,确保任何特定软件包始终从同一仓库安装或更新。这样,您可以添加无限数量的仓库,并使 YUM 保持对软件包管理的控制。
那么,我们从这次经历中学到了什么?
通过安装yum-plugin-priorities
软件包并确保在其配置文件中启用它,我们简单地增强了 YUM。然后我们发现优先级是按升序设置的,其中最低值优先于所有其他值。当然,这简化了整个过程,因此我们确保默认仓库被赋予值1
(priority=1
)。这将确保默认仓库保持最高优先级,因此当您决定添加其他仓库时,可以为它们分配优先级值 2、3、4…和 10,或更多。另一方面,应该注意的是,我们只在三个主要部分设置了此值:[base]
、[updates]
和[extras]
。简单来说,这只是因为其他部分显示为禁用。例如,您可能已经注意到/etc/yum.repos.d/CentOS-Base.repo
中的[centosplus]
部分包含以下行:enabled=0
,而[updates]
和[extras]
部分显示此值为enabled=1
。当然,如果您打算激活此仓库,则需要为其设置优先级值,但为了本食谱的目的,不需要进行此操作。最后,我们运行了一个简单的 YUM 软件包更新以激活我们的修订设置。
因此,正如我们所见,YUM 优先级是一个极其灵活的软件包,它使您能够确定在扩展安装选项时哪些存储库具有优先权。然而,您应该始终意识到,YUM 优先级可能并不适合您的系统,因为您赋予了它决定哪些软件包将被忽略、哪些软件包将被安装、哪些软件包将被更新以及以何种顺序和从哪个存储库获取它们的权力。对于大多数不倾向于远离典型服务器功能的用户来说,这可能不是立即关注的问题;您甚至可以安全地忽略这个警告。但如果稳定性和安全性是压倒性的关注点,并且您确实打算从外部存储库使用额外的软件包,那么您应该仔细考虑使用此插件,或者至少考虑并研究所使用的第三方存储库的完整性。
使用第三方存储库
在本配方中,我们将探讨充分利用 CentOS 可用软件包的愿望,通过安装 EPEL 和 Remi 存储库。CentOS 是一个以稳定性为傲的企业级操作系统,在您的服务器生命周期中,可能并非您需要的每一件软件都能在默认存储库中找到。您也可能需要当前软件的更新软件包,出于这些原因,许多服务器管理员选择安装 EPEL 和 Remi 存储库。这些不是唯一可用的存储库,但由于它们代表了最受欢迎的组合之一,因此本配方的目的是向您展示如何将 EPEL 和 Remi 存储库添加到您的系统中。
准备工作
要完成这个配方,您需要一个具有 root 权限的 CentOS 7 操作系统的有效安装,您选择的基于控制台的文本编辑器,以及连接到互联网以便于下载额外软件包的能力。
如何操作…
在我们开始之前,假设您已经遵循了之前的配方,该配方向您展示了如何安装和激活 YUM 优先级。
首先,以 root 身份登录并使用 YUM 安装 EPEL 发布存储库:
yum install epel-release
接下来,从您的家目录中,键入以下命令以下载
remi release
rpm
软件包:curl -O http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
注意
请注意,当您阅读本文时,此 URL 可能已更改;如果是这样,请进行一些互联网研究,以了解是否有新的 URL 可用。
前面的文件现在应该位于您的家目录中。要继续,请键入以下命令:
rpm -Uvh remi-release-7.rpm
安装完成后,使用您最喜欢的文本编辑器打开 Remi 存储库文件:
vi /etc/yum.repos.d/remi.repo
将
enabled=0
更改为enabled=1
,并在[remi]
部分的末尾添加行priority=10
。现在,使用您最喜欢的文本编辑器打开 EPEL 存储库文件:
vi /etc/yum.repos.d/epel.repo
再次,如果未自动设置,请将
enabled=0
更改为enabled=1
,并在[epel]
部分中添加行priority=10
。最后,按照以下方式更新 YUM:
yum update
如果有可用更新,请选择Y继续。完成更新过程后,您现在将能够从 Remi 和 EPEL 存储库下载和安装软件包,作为默认使用的补充。
它是如何工作的…
为了使用和享受第三方存储库的好处,您首先需要使用 YUM 和 RPM 包管理器安装并启用它。
那么,我们从这次经历中学到了什么?
开始执行配方后,安装 Remi 和 EPEL 存储库的任务是一个非常顺畅的过程。虽然使用 YUM 安装 EPEL 存储库非常安全,不会对系统造成影响,但 Remi 存储库的先前 URL 由存储库所有者自行维护,因此您应始终确保它们是最新的。然而,一旦获得了必要的存储库设置文件,接下来就是使用基于 RPM 的命令在系统上安装所有必要的存储库文件。完成这一步后,我们还需要打开每个已安装存储库的相关配置文件并启用它们(通过将enabled=0
更改为enabled=1
),并设置优先级值(priority=10
)。前一个值仅会打开存储库,而后一个值将由 YUM 用于在我们调用update
命令时正确识别哪些存储库最为合适。正如在前一个关于 YUM 优先级的配方中所讨论的,一个简单的经验法则是记住这句话:“数字越低,优先级越高。”这本身(取决于您的目的)可能不是一件坏事,但对于本配方的目的,它表明默认的 CentOS 存储库应该优先于所有其他存储库。当然,您可能不同意这一点,并且确实没有任何阻止您将相同的优先级规则应用于第三方供应商,但我确实在您深入之前提醒您,特别是在这是为了关键任务生产服务器的情况下。请记住,如果所有优先级值都相同,那么 YUM 将默认尝试下载最新版本。
将 Remi 和 EPEL 的优先级设置得比现有的基于 CentOS 的仓库更高,是基于考虑安全更新的需要。除非你另有决定,否则始终建议基础文件应首先来自 CentOS。这包括但不限于内核更新、SELinux 及相关软件包。第三方仓库应用于获取无法从原始来源获得的额外软件包,或访问可能不适用于 CentOS 基础版本的特定更新。这可能包括 Apache、MariaDB 或 PHP 等软件包。最后,你可能会注意到 Remi 和 EPEL 仓库共享相同的优先级值。这是有意为之,因为这些仓库通常被视为合作伙伴。然而,如果你决定开始混合使用仓库,或使用此方法作为安装此处未提及的其他仓库的途径,那么你应该始终进行研究,并逐个评估每个第三方仓库。Remi 和 EPEL 仓库非常受欢迎,所以如果你确实打算添加更多第三方资源,请围绕主题进行阅读,谨慎选择你的仓库,并保持忠诚。
还有更多…
CentOS 7 有许多其他有趣的仓库,例如专注于硬件相关软件包的 ELRepo,如文件系统驱动、图形驱动、网络驱动、声音驱动以及摄像头或视频驱动。访问elrepo.org
学习如何安装和访问它。
创建 YUM 仓库
如果你在本地网络中维护多个 CentOS 服务器,并希望节省互联网带宽或加快重复下载相同远程仓库软件包的速度,或者处于一个非常受限的网络环境中,你的客户端无法访问任何远程 CentOS 仓库,你可能需要考虑运行自己的 YUM 仓库。拥有自己的仓库也是一个很好的解决方案,如果你想向本地用户推出一些自定义或非官方的 RPM 软件包(例如内部配置文件或程序),或者你只是想创建一个官方 CentOS 7 仓库的镜像站点。在本方法中,我们将向你展示如何设置你自己的第一个 YUM CentOS 7 仓库,以及如何为你的本地网络提供服务。
准备就绪
要完成此配方,您需要一个具有 root 权限的 CentOS 7 操作系统的有效安装,您选择的基于控制台的文本编辑器,以及连接到互联网以方便下载额外软件包。为了使此配方工作,您还需要将 CentOS 7 Everything DVD iso 文件图像放置在服务器的根目录中,如果您还没有下载它,请参考第一章中的第一个配方,安装 CentOS(但下载最新的CentOS-7-x86_64-Everything-XXXX.iso
文件而不是最小 iso 文件)。此外,我们需要一个正在运行的 Apache Web 服务器来共享我们的 YUM 仓库到我们的本地网络;请阅读第十二章中的第一个配方,提供 Web 服务,以了解如何设置它。
如何操作…
要创建我们自己的 YUM 仓库,我们需要createrepo
程序,该程序在 CentOS 7 上默认未安装。让我们从安装它开始我们的旅程。在本例中,我们将使用 IP 地址192.168.1.7
作为我们的 YUM 仓库服务器:
以 root 身份登录到您的服务器并安装以下软件包:
yum install createrepo
接下来,对于您想要共享的每个仓库,在 Apache Web 根目录下的
/var/www/html/repository/
下创建一个子文件夹,当 Apache 运行时,该文件夹将公开可用;例如,要共享完整的 CentOS 7Everything
仓库包,您可以使用:mkdir -p /var/www/html/repository/centos/7.1
现在,将您选择的 RPM 包文件放入此处创建的仓库文件夹中。在我们的示例中,我们将把
Everything
iso 文件中的所有 RPM 包放入我们新的本地仓库位置,之后我们将把 iso 文件的内容挂载到文件系统上:mount ~/CentOS-7-x86_64-Everything-1503-01.iso /mnt/ cp -r /mnt/Packages/* /var/www/html/repository/centos/7.1/
之后,我们需要为复制到 Apache Web 根目录中的所有新文件更新 SELinux 安全上下文:
restorecon -v -R /var/www/html
现在,对于我们想要设置的每个仓库,运行以下命令:
createrepo --database /var/www/html/repository/centos/7.1
恭喜,您现在已经成功创建了您的第一个 YUM 仓库,该仓库可以通过正在运行的 Apache Web 服务器从同一网络中的任何计算机访问。为了测试它,以 root 身份登录到任何其他可以 ping 通我们的仓库服务器的 CentOS 7 系统,并将我们的新仓库添加到其 YUM 仓库配置目录中:
vi /etc/yum.repos.d/myCentosMirror.repo
将以下内容添加到这个空文件中(根据您的需要适当更改
baseurl
):[myCentosMirror] name=my CentOS 7.1 mirror baseurl=http://192.168.1.7/repository/centos/7.1 gpgcheck=1 gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7
保存并关闭文件,然后测试您的新仓库是否可用(它应该出现在列表中)在您的客户端上:
yum repolist | grep myCentosMirror
现在,为了测试我们的新 YUM 仓库,我们可以尝试以下命令:
yum --disablerepo="*" --enablerepo="myCentosMirror" list available
它是如何工作的…
在本节中,我们已经向你展示了安装和设置本地 YUM 仓库是多么容易。然而,我们只向你展示了如何创建所有 CentOS 7 Everything iso RPM 包的镜像站点,但你可以重复此过程来创建你想要与你的网络共享的任何类型的包的 YUM 仓库。
那么,我们从这次经历中学到了什么?
设置自己的 YUM 仓库只需安装createrepo
包,并将你想要共享的所有 RPM 包复制到 Apache 文档根目录下的一个子文件夹中(在我们的例子中,我们需要挂载 CentOS 7 Everything iso 文件到文件系统,以便访问我们想要共享的包含的 RPM 包文件)。由于 Apache 的文档根目录受 SELinux 控制,之后我们需要将该目录中新 RPM 文件的安全上下文设置为httpd_sys_content_t
类型标签;否则,通过 Web 服务器将无法访问。最后,我们需要在我们的新仓库文件夹上运行createrepo
命令,这将创建我们新仓库所需的元数据,以便任何想要连接到仓库的 YUM 客户端稍后可以对其进行查询。
随后,为了测试我们的新仓库,我们在另一台想要使用这项新服务的 CentOS 7 系统上创建了一个新的仓库定义文件,该系统必须与我们的 YUM 仓库服务器处于同一网络中。在这个自定义的.repo
配置文件中,我们设置了正确的仓库 URL 路径,启用了gpg
检查,并采用了标准的 CentOS 7 gpgkey
,以便我们的 YUM 客户端能够验证官方仓库包的有效性。最后,我们使用带有--disablerepo="*"
和--enablerepo="myCentosMirror"
参数的yum
命令,这将确保只使用我们的新自定义仓库作为源。你可以将这两个参数与任何其他yum
命令(如install
、search
、info
、list
等)结合使用。这只是为了测试;如果你想要将你的新仓库与现有的仓库结合使用,请使用 YUM 优先级(如本章另一节中所述)。
还有更多…
现在,在我们向我们的网络宣布新的集中式 YUM 仓库之前,我们应该首先更新自 CentOS Everything iso 发布以来已更改的所有 RPM 包。为此,请访问www.centos.org
并选择一个rsync://
镜像链接,该链接地理位置上靠近您当前的位置。例如,如果您位于德国,一个选项可能是rsync://ftp.hosteurope.de/centos/(有关导航 CentOS 网站的更详细说明,请阅读第一章-version number (1.4.6)-release(1)-CPU architecture (x86_64)
接下来,我们使用 RPM 包管理器安装了下载的`pv`包,该管理器可以通过命令行上的`rpm`命令执行。我们使用了带有`-Uvh`命令参数的`rpm`命令,以及下载的包 rpm 文件的完整名称。 ### 注意 如果使用 rpm 命令安装或升级 rpm 软件包,您应该始终使用`-Uvh`,但有一个例外;即内核包。`-U`会在更新时删除旧包,如果您安装新内核,这不是您想要的。请改用`-i`(用于安装),因为这将保留旧内核文件,以便在遇到问题时可以回退到较早的版本。 `-U`是安装或升级包的参数。如果系统上未安装该包,它将被安装;否则,如果 RPM 包版本比已安装的版本新,`rpm`将尝试升级它。`-v`参数打印更详细的输出,而`-h`显示一个漂亮的进度条。如果您在系统上未启用 EPEL 仓库的情况下安装`pv`包,将收到以下警告消息:
pv-1.6.0-1.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 3fc56f51: NOKEY
RPM 在安装前会自动检查包的签名有效性,以确保包的内容自签名后未被篡改。同时,它还会检查 RPM 包的可信度,因为应该由官方第三方权威供应商使用加密密钥进行签名。您可以忽略此消息,因为 EPEL 仓库的包来自安全源。要永久信任 EPEL 源,您可以使用以下命令在系统上安装其`gpg`公钥,从而消除所有未来的签名警告消息:
rpm --import https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
成功安装包后,我们现在拥有一个名为`pv`的漂亮命令行工具,它可以显示通过 Unix 管道的数据进度,如果您通过管道传输大量数据,这可能会很有用,因为您通常永远不会知道当前的进度状态。之后,我们查询了存储有关 CentOS 7 系统上所有已安装包信息的 RPM 数据库,使用带有`-q`标志的`rpm`命令。在处理 RPM 数据库时,我们必须使用真实的包名(`pv`)而不是安装包时使用的文件名(`pv-1.4.6-1.x86_64.rpm`)。在卸载已安装的包时也是如此;请指定包名,而不是版本号或完整文件名。 要获取有关已安装包`pv`的详细信息,我们使用了`-qi`(`i`表示信息),并使用`-ql`参数;我们显示了包中所有文件的完整文件名和路径。`-qd`显示了包中包含文档的所有文件。要了解更多的查询选项,请键入`man rpm`并查看`PACKAGE QUERY OPTIONS`部分。 总之,我们可以说,在系统管理员的生活中,有时需要安装一个不是通过官方仓库分发的软件(例如,非开源、前沿程序或测试版、有许可证不允许将其放入仓库的软件,如 Java,或来自独立开发者的软件),这时需要下载单独的 RPM 包并手动安装它们。在幕后,YUM 也依赖并使用 RPM 包管理器,因此你也可以使用 YUM 程序来安装 rpm 文件(`yum install <filename.rpm>`)。然而,当涉及到查询你下载的 rpm 文件或系统上已安装的包时,有时使用较旧的`rpm`命令而不必安装额外的基于 YUM 的软件(如`yum-utils`)会更好。 RPM 的最大弱点是它不支持仓库,并且缺少依赖管理系统。如果你仅使用 RPM 在 CentOS 系统上安装所有软件,你很容易遇到包依赖问题,因为你无法安装特定的包,因为它依赖于其他一些包。通常,当你尝试安装依赖的包时,你需要它们依赖的其他包,如此类推。这可能是一项非常繁琐的工作,应该始终通过使用 YUM 来避免。 ## 还有更多... `rpm`命令不仅可以用于查询 rpm 数据库中关于已安装包的信息,还可以用于查询你下载的 rpm 文件。例如,使用`-qlp`参数来显示本地`rpm`包文件中的所有文件:
rpm -qlp ~/pv-1.4.6-1.el7.x86_64.rpm
要从`rpm`文件中获取关于包的详细信息,使用`-qip`参数,如下所示:
rpm -qip ~/pv-1.4.6-1.el7.x86_64.rpm
如果你想安装一个本地下载的 RPM 包,并且该包有依赖关系,你可以使用`yum localinstall`命令。一旦提供了包的文件名,该命令将安装本地包,并尝试从远程源解决所有依赖关系,例如:
wget http://location/to/a/rpm/package_name.rpm
yum localinstall package_name.rpm
# 第五章:管理文件系统 在本章中,我们将涵盖以下主题: + 创建虚拟块设备 + 格式化和挂载文件系统 + 使用磁盘配额 + 维护文件系统 + 扩展文件系统的容量 # 简介 本章是一系列步骤的集合,旨在满足驱动基于 CentOS 的服务器解决方案的需求。从格式化和挂载磁盘到扩展逻辑卷以及维护文件系统和磁盘配额,本章的目的是向你展示如何快速轻松地掌握管理当今最苛刻环境中用户需求任务的技能。 # 创建虚拟块设备 在本步骤中,我们将创建一个虚拟块设备,用于模拟真实设备和分区,以便我们可以在本章后续的所有步骤中测试驱动概念和命令。使用真实磁盘和分区通常涉及丢失重要数据甚至需要重新安装整个系统的风险。虚拟块设备是学习技术和尝试操作的理想选择,然后再切换到“生产模式”。稍后,如果你获得了足够的经验并感到安全,你可以轻松地将其替换为“真实”硬件设备、分区以及逻辑卷(这是 LVM 的一部分;请参阅后面的步骤)。你所需要做的就是将你的虚拟设备替换为“真实”块设备名称。 ## 准备工作 要完成这个步骤,你需要一个具有 root 访问权限的 CentOS 7 操作系统的最小安装。为了创建一个虚拟块设备,你应该至少有一 GB 的可用硬盘空间,我们将暂时使用这些空间来创建和制作。你可以在之后删除这部分预留空间(或者在重启后它会自动删除)。这只是为了测试。 ## 如何操作... 1. 首先,以`root`身份登录并创建一个精确大小为 1GB 的空文件: ``` dd if=/dev/zero of=/tmp/test-image.dd bs=1M count=1000 ``` 1. 现在,让我们从刚刚创建的文件中创建一个循环设备: ``` losetup -fP /tmp/test-image.dd ``` 1. 接下来,打印生成的循环设备名称: ``` losetup -a ``` 1. 由于这将是当前系统中创建的第一个循环设备,输出将如下所示(如果你之前创建了循环设备,`loop0`可能是一个不同的数字): ``` /dev/loop0: [0035]:3714186 (/tmp/test-image.dd) ``` 1. 要获取当前系统上所有已附加的块设备的列表以及重要详细信息,请键入以下内容: ``` lsblk -io NAME,TYPE,SIZE,MOUNTPOINT,FSTYPE,MODEL ``` 1. 现在,让我们在我们的新循环设备上创建一个类型为`gpt`的新分区表(确认删除任何数据): ``` parted /dev/loop0 mklabel gpt ``` 1. 最后,从你的循环设备创建设备映射,使其更类似于真实的硬盘分区: ``` kpartx -a /dev/loop0 ``` ## 它是如何工作的... 在本步骤中,我们学习了如何创建一个虚拟块设备,作为测试如何在本章后续步骤中创建分区、逻辑卷和文件系统的起点。 那么,我们从这次经历中学到了什么? 我们通过使用`dd`工具在`/tmp`目录中创建一个大小为 1GB 的新空文件来开始这个操作。`dd`用于制作文件的精确副本(有时称为克隆),并期望两个参数:输入文件(`if`参数)和输出文件(`of`参数)。我们使用`zero`设备(`/dev/zero`)作为输入文件,它返回一个包含零的无尽字节流。然后,我们通过定义块大小(`bs`)和`count`参数来限制流。`bs`定义了一次读取的数据量(以字节为单位),而`count`参数计算`bs`将允许重复多少次。因此,这些参数可以被理解为*当达到块大小乘以计数的数据量时停止复制过程*。在我们的示例中,我们使用了`1`*兆字节乘以 1000 = 1GB*的块大小。这些零字节数据被写入到我们的输出文件(`of`),称为`/tmp/test-image.dd`。 在我们创建了这个空文件之后,我们用它创建了一个临时的**循环**设备。循环设备只是一个伪设备,它使得可以将文件用作**块设备**。通常,这样的文件是一个 CD ISO 镜像,将其用作循环设备将使其可访问,就像它是一个正常的硬件驱动器一样。任何允许以块为单位读写数据的设备都可以称为块设备;为了获取系统中所有可用块设备的列表,我们使用了`lsblk`命令,正如您所见,这也包括我们的循环设备。标准的循环设备名称以数字零开头,例如`/dev/loop0`。 之后,我们使用`parted`命令在我们的循环设备上创建了一个新的**分区表**。分区表是操作系统在磁盘上维护的一个表,描述了磁盘上的分区,我们必须先创建分区表,然后才能创建分区。我们使用了分区表类型`gpt`,但您也可以在这里使用旧的 msdos 类型。 通常,在虚拟块设备上创建分区表时,我们无法访问单个分区或为其上的不同分区创建文件系统,因为分区不能单独寻址。在这里,我们使用`kpartx`命令从分区表创建设备映射,这允许我们稍后使用表示法`/dev/loop0p1`访问循环设备 0 上的分区 1,以及`/dev/loop0p2`访问循环设备 0 上的分区 2,以便为单个分区创建文件系统。 恭喜,您现在已经创建了一个带有标准分区表的新虚拟块设备,它可以像普通磁盘设备一样被使用和访问。 ## 还有更多... 如果我们想要移除一个虚拟块设备,首先需要将其从文件系统中卸载,如果它当前已挂载(例如,`umount /dev/loop0p1`)。接下来,我们需要使用`-d`参数将虚拟块设备文件从循环设备中分离,如下所示:`losetup -d /dev/loop0`。之后,如果我们愿意,可以删除块文件:`rm /tmp/test-image.dd`。 # 格式化和挂载文件系统 在本食谱中,您将了解标准 CentOS 文件系统**XFS**、**Ext4**和**Btrfs**。文件系统是任何操作系统最基本的部分之一,几乎所有东西都依赖于它们。在这里,您将学习如何在 CentOS 7 中创建不同类型的标准文件系统,以及如何将它们链接到您的系统,以便我们随后可以访问它们进行读写。这两种技术被称为**格式化**和**挂载**文件系统;虽然您不经常这样做,但它仍然是 Linux 系统管理员最基本的任务之一。 ## 准备就绪 要完成此食谱,您需要具备具有 root 访问权限的 CentOS 7 操作系统的最小安装。我们还将使用虚拟块设备而不是实际磁盘设备,因为使用“虚拟”设备演示创建文件系统和格式化磁盘的使用情况比擦除实际硬盘内容更好。因此,您应该已经应用了*创建虚拟块设备*食谱,并创建了一个 1GB 的虚拟块设备,在本例中将被命名为`/dev/loop0`。 如果您想将此方法应用于实际磁盘设备,您只需将`/dev/loop0`替换为正确的分区——例如,对于逻辑卷(lv),如`/dev/mapper/myServer/data`,对于 SATA 设备,如`/dev/sdX`,或对于基于 IDE 的硬盘名称,如`/dev/hdX`(其中`X`是字符`a-z`)。 ## 如何操作... 在我们的示例中,此块设备被标记为`/dev/loop0`。请注意,如果您创建了多个块设备,您的编号可能会有所不同,因此请相应地更改名称: 1. 首先,让我们以`root`身份登录并显示所有当前可用的块设备的信息: ``` lsblk -io NAME,TYPE,SIZE,MOUNTPOINT,FSTYPE,MODEL ``` 1. 现在,重新检查我们是否在设备上安装了有效的分区表: ``` parted /dev/loop0 print ``` 1. 前面的行应该打印出以下内容:`Partition Table: gpt`。如果不是这种情况,让我们创建一个新的分区表(确认删除任何数据): ``` parted /dev/loop0 mklabel gpt ``` 1. 现在,我们将创建一个覆盖整个磁盘空间的新分区,并使用`ext4`文件系统标签(尚未安装文件系统;它只是一个标签): ``` parted -a optimal /dev/loop0 mkpart primary ext4 2048KiB 100% ``` 1. 再次打印分区表以显示我们刚刚创建的新分区: ``` parted /dev/loop0 print ``` 1. 现在,让我们删除分区: ``` parted /dev/loop0 rm 1 ``` 1. 我们还可以创建一个带有 btrfs 标签的分区: ``` parted -a optimal /dev/loop0 unit MB mkpart primary btrfs 2048KiB 100% ``` 1. 之后,让我们创建一个覆盖整个磁盘的 XFS 标签分区: ``` parted /dev/loop0 rm 1 parted -a optimal /dev/loop0 mkpart primary xfs 2048KiB 100% ``` 1. 现在,再次显示块表以查看我们更改了什么: ``` lsblk -io NAME,TYPE,SIZE,MOUNTPOINT,FSTYPE,MODEL ``` 1. 由于我们只定义了分区类型*标签*,我们仍然没有在分区上安装有效的文件系统;因此,在下一步中,我们使用正确的类型格式化磁盘。在我们的示例中,我们使用 XFS。请根据需要更改`mkfs -t <type>`,如果您使用`ext4`或`btrfs`: ``` mkfs -t xfs /dev/loop0p1 ``` 1. 接下来,让我们将虚拟块设备分区挂载到系统上,挂载到目录`/media/vbd-1`,并请根据需要更改`-t <type>`,如果您使用`ext4`或`btrfs`: ``` mkdir /media/vbd-1 mount -t xfs /dev/loop0p1 /media/vbd-1 ``` 1. 最后,测试我们是否可以对新文件系统进行读写: ``` echo "this is a test" > /media/vbd-1/testfile.txt cat /media/vbd-1/testfile.txt ``` ## 它是如何工作的… 在这个过程中,我们向用户展示了如何创建 CentOS 7 标准分区,覆盖整个磁盘,然后我们在这些分区上创建了一些文件系统,这称为格式化,使用了不同的文件系统类型。CentOS 7 中的标准文件系统是 XFS,但正如我们在本过程中所学到的,还有许多其他可用的文件系统,包括流行的 ext4 和 btrfs。XFS 是一种非常健壮且高性能的文件系统,适用于大型存储配置;它被认为非常成熟和稳定。在 CentOS 7 之前,标准文件系统是 ext4,但它有一些限制,并且在处理数百万个文件时性能不佳,被认为勉强适合当今非常大的文件系统。btrfs 是一个相对较新的文件系统,包含在 CentOS 7 中,但在撰写本文时仍处于开发阶段,不应在生产系统中使用。预计在后续的 CentOS 7 小版本中将得到全面支持,并有可能在未来取代 XFS 成为 CentOS 的标准文件系统类型,因为它具有一系列非常有前景的特性和增强功能,例如写时复制,每次写入文件时都会复制文件,这使得能够回溯到以前的文件版本。 那么,我们从这次经历中学到了什么? 我们通过使用`lsblk`命令开始这个过程,该命令用于打印系统上当前连接的所有可用块设备的列表。我们使用这个命令来检查我们想要用于安装分区和文件系统的目标块设备是否可用。在我们的例子中,我们将使用`/dev/loop0`设备,如果您的系统上名称不同,请更改此名称(如前所述,您也可以使用“真实”磁盘块设备,例如`/dev/sda`,但始终要小心!)。确认设备准备就绪后,我们使用`parted`命令检查磁盘的分区表。分区表对于任何硬盘都是必需的,以便跟踪其上的分区信息。如您所见,我们创建分区表和分区的首选工具是*parted*,因为它是 CentOS 7 官方推荐的工具,但也有其他程序可以执行相同任务,例如`fdisk`或`gdisk`。如果没有可用的分区表,我们必须使用 parted 的`mklabel gpt`参数创建一个类型为`gpt`的分区表。 接下来,在我们创建了分区表之后,我们在其上放置了一些分区。因此,我们使用 parted 的`mkpart`命令,并带有`-a optimal primary ext4 2048KiB 100%`选项。 ### 注意 始终小心使用`parted`命令,并在执行前仔细检查所有内容,因为其大多数命令都会彻底销毁磁盘上当前存储的所有数据。 这将创建一个新的分区,从 2,048 千字节(kb)开始直到磁盘末端。我们没有从磁盘的最开始(0%)开始,因为 2,048 kb 是磁盘上第一个扇区的开始,留下一些空间来存储一些额外的数据。`-a optimal`将分区对齐到物理块大小的倍数,这将保证最佳性能。接下来,我们使用`rm`选项和数字`1`删除了分区,这指的是我们刚刚创建的第一个分区。我们重新创建了类型为`btrfs`和最终`xfs`的新分区。在磁盘分区之后,我们需要在其上创建一个实际的文件系统,因为 parted 仅将分区标记为特定类型,但并不进行实际的格式化。为了创建文件系统,我们使用`mkfs`工具。你可以使用`-t`标志运行它,就像我们所做的那样,或者使用点表示法,例如`mkfs.xfs`,来指定你想要格式化的类型。`mkfs`命令为我们提供了详细的输出,例如已经写入了多少块等等。 最后,在我们为磁盘分区创建了文件系统之后,我们可以使用`mount`命令使其可用并在当前系统中工作。`mount`要么将设备的文件系统附加到我们系统的根文件系统,要么将其分离。因此,我们需要首先创建一个目录来定义我们想要将其附加到哪里。我们使用目录`/media/vbd-1`作为实际`mount`命令的参数,语法为`mount -t <文件系统类型> <设备> <目录>`。对于几乎所有标准文件系统,你可以跳过`-t`参数,因为它会自动检测正确的类型。要从系统中分离文件系统,你可以使用`umount`命令,参数是你想要移除的设备(你也可以使用它所挂载的文件夹;两者都有效!)。在我们的例子中,要卸载我们的循环设备的第一分区,请输入`umount /dev/loop0p1`。 在挂载我们格式化的分区设备之后,我们可以像访问根目录下的任何其他组件一样访问它。 ## 还有更多... 在本食谱中,我们总是使用一个分区覆盖整个可用磁盘空间。通常,你会在一个磁盘上有多个分区,所以让我们创建这种布局。在这个例子中,我们在`/dev/loop0`上创建三个 100 MB 的分区: 1. 首先,让我们再次使用`rm`参数删除我们的分区,以便我们可以添加新的分区: ``` parted /dev/loop0 rm 1 ``` 1. 现在,让我们创建三个等分的分区: ``` parted -a optimal /dev/loop0 unit MiB mkpart primary ext4 2048KiB 100 parted -a optimal /dev/loop0 unit MiB mkpart primary ext4 100 200 parted -a optimal /dev/loop0 unit MiB mkpart primary ext4 300 400 ``` 1. 让我们回顾一下我们的布局: ``` parted /dev/loop0 print ``` ### 注意 使用`gpt`分区表,我们可以在任何磁盘上创建多达 128 个主分区;当使用较旧的`msdos`分区类型时,最多有四个主分区。如果你需要更多,你必须从主分区中创建扩展分区。 # 使用磁盘配额 在管理具有多个系统用户的 Linux 多用户系统时,明智的做法是设置某种限制或限制系统共享资源的限制。在文件系统级别,您可以限制可用硬盘空间或总文件数到固定大小,可以是用户、组或目录级别。引入这些规则可以防止人们“滥发”系统,填满其可用空间,并且通常您的用户将更加意识到重要和不重要数据之间的区别,并且更有可能保持其主目录整洁和干净。在本食谱中,我们将向您展示如何为 XFS 文件系统设置**磁盘配额**限制系统,该系统对系统用户帐户允许存储的数据量施加限制。 ## 准备就绪 要完成本食谱,您需要具有 root 访问权限的 CentOS 7 操作系统的最小安装和您选择的基于控制台的文本编辑器。为了使本食谱工作,并且为了设置配额,您至少需要一个系统用户帐户,除了您的 root 帐户;如果您还没有一个,请参阅第三章,*管理用户和他们的组*,了解如何创建一个。此外,在本食谱的主要部分中,假设您的 CentOS 7 使用 XFS 文件系统,这是安装时的标准。最后,您的 CentOS 7 安装需要安装在至少 64 GB 空间的磁盘上,否则安装程序不会创建单独的逻辑`/home`卷,这是本食谱中使配额工作的要求。 ## 如何做到这一点... 在这里,我们将学习如何为 XFS 文件系统设置配额系统的两种不同方式:首先,设置用户和组的限制,然后设置目录(项目)级别的限制。磁盘配额系统必须在文件系统挂载时设置。 ### 启用用户和组配额 1. 首先,以`root`身份登录并打开包含静态挂载信息的`fstab`文件: ``` vi /etc/fstab ``` 1. 现在,将光标导航到包含`/home`的行(使用*上*和*下*箭头键),并将其移动到单词`defaults`,然后在`defaults`之后添加以下文本,用逗号分隔: ``` ,uquota,gquota ``` 1. 完整的行将如下所示(您的设备名称将根据您的个人 LVM 名称而不同;在这里,它是`myserver`): ``` /dev/mapper/myserver-home /home XFS defaults,uquota,gquota 0 0 ``` 1. 保存并关闭文件,然后重新挂载`/home`分区以激活`quota`指令: ``` umount /home;mount -a ``` 1. 接下来,为特定用户名为`john`的用户(根据您系统上可用的用户进行适当更改)创建用户配额,限制其总文件大小: ``` xfs_quota -x -c 'limit bsoft=768m bhard=1g john' /home/ ``` 1. 接下来,为另一个用户`joe`可以拥有的总*数量*文件创建用户配额: ``` xfs_quota -x -c 'limit isoft=1000 ihard=5000 joe' /home/ ``` 1. 让我们为`devgrp`用户组中的每个人设置文件数量和大小限制(文件系统组`devgrp`必须存在): ``` xfs_quota -x -c 'limit -g bsoft=5g bhard=6g isoft=10000 ihard=50000 devgrp' /home ``` 1. 最后,显示`home`卷的整个配额报告: ``` xfs_quota -x -c 'report -bi -h' /home ``` ### 启用项目(目录)配额 为了启用单个目录的磁盘配额而不是用户或组配额,我们必须将名为 `pquota` 的项目配额指令添加到包含该目录的卷中。由于我们将使用名为 `/srv/data` 的目录进行项目配额,我们需要将完整的底层 `/` 根分区置于配额控制之下。对于根分区,我们必须设置内核引导选项的配额标志: 1. 首先,在备份该文件后,以 root 身份打开以下文件: ``` cp /etc/default/grub /etc/default/grub.BAK vi /etc/default/grub ``` 1. 在行尾(在它之前添加一个空格字符)以 `GRUB_CMDLINE_LINUX=` 开头,在结束的双引号之前,添加 `rootflags=pquota` 指令,如下所示: ``` GRUB_CMDLINE_LINUX="rd.lvm.lv=centos/root rd.lvm.lv=centos/swap crashkernel=auto rhgb quiet rootflags=pquota" ``` 1. 保存并关闭文件,然后使用我们的新引导选项重建 `grub` 配置: ``` grub2-mkconfig -o /boot/grub2/grub.cfg ``` 1. 现在,在你的 `/etc/fstab` 中为根卷添加 `pquota` 标志: ``` vi /etc/fstab ``` 1. 将光标导航到包含根挂载点 / 的行,并将其移动到单词 `defaults`,然后添加以下文本,用逗号分隔: ``` ,prjquota ``` 1. 完整的行将类似于以下内容: ``` /dev/mapper/myserver-root / XFS defaults,prjquota 0 0 ``` 1. 接下来,重启计算机以将更改应用到 `root` 卷: ``` reboot ``` 1. 重启后,确保 `root` 卷已启用项目配额,该配额在卷选项中定义为 `prjquota` 标志(否则,如果设置错误且不起作用,它将显示为 `noquota`): ``` cat /etc/mtab | grep root ``` 1. 接下来,让我们创建我们想要设置配额的目标文件夹: ``` mkdir /srv/data ``` 1. 我们需要添加一个项目名称和一个关联的新唯一 ID: ``` echo "myProject:1400" >> /etc/projid ``` 1. 现在,定义 `/srv/data` 将使用我们项目 ID 的配额规则: ``` echo "1400:/srv/data" >> /etc/projects ``` 1. 接下来,为 `root` 卷初始化 `project` 配额: ``` xfs_quota -xc 'project -s myProject' / ``` 1. 最后,应用以下规则来创建特定的目录限制: ``` xfs_quota -x -c 'limit -p bsoft=1000m bhard=1200m myProject' / ``` 1. 打印出我们为这个设备设定的配额规则: ``` xfs_quota -x -c 'report -bi -h' / ``` ## 它是如何工作的... 在本教程中,你学会了在用户、组或目录(项目)级别设置配额系统是多么容易。此外,你还了解到有两种基本方式来定义配额:要么对 *总文件大小*(称为块)施加限制,要么对 *文件数量*(称为 inode)设置限制。 那么,我们从这次经历中学到了什么? 我们从这个配方开始设置用户和组配额。正如你所见,通过在`/etc/fstab`文件中选择的分区添加相关的指令,可以轻松启用配额系统。因此,我们从这个文件开始,为 XFS 用户和组配额向我们的`/home`分区添加了特殊的配额关键词。为了应用这些更改,我们不得不使用`mount`命令重新挂载文件系统。由于配额系统已成功启动,我们使用`xfs_quota -x -c`命令行在我们的启用文件系统`/home`上设置了一些配额限制。`-x`启用专家模式,而`-c`允许我们在命令行上运行命令作为参数。当运行`xfs_quota`而不带`-c`选项时,你将进入一个交互式提示。首先,我们为用户`john`和`joe`设置了某些用户限制。我们通过定义以下参数及其数字来实现这一点:`bsoft`,`bhard`,`isoft`,`ihard`。如你所见,对于文件大小(**块**)和文件数量(**索引节点**)都有软限制和硬限制。块配额可以以典型的度量单位给出,如千字节(`k`),兆字节(`m`)和千兆字节(`g`),而索引节点是一个数字。软限制是一个阈值,当超过时,会在命令行上打印出警告消息,而硬限制将阻止用户在配额保护下的文件系统中添加更多数据或文件。之后,我们设置了一个基于组的配额。如果你使用`-g`标志,限制将为一个组而不是用户定义。根据用户应被允许拥有的文件数量或总文件大小,将用户分成不同的组,使用组规则可能非常有帮助。最后,我们为所有当前配额限制生成了一个报告。我们使用的命令是`'report -bi -h'`,它为已使用的文件空间(`-b`表示块)和总文件数量(`-i`表示索引节点)生成报告。`-h`指定我们希望输出以兆字节或千兆字节为单位,便于人类阅读。 为了测试配额是否有效,让我们为用户`jack`创建以下块和索引节点配额:
xfs_quota -x -c ‘limit bhard=20m jack’ /home/
xfs_quota -x -c ‘limit ihard=1000 jack’ /home/
以用户`jack`的身份登录(`su - jack`)并运行以下命令:
dd if=/dev/urandom of=~/test.dd bs=1M count=21
通过此命令,用户`john`将尝试创建一个 21 兆字节大小的文件,但在开始写入第二十兆字节时,将出现以下错误消息:
dd: error writing ‘/home/jack/test.dd’: Disk quota exceeded
现在,删除`~/test.dd`文件,以便我们可以开始另一个测试。如果你超过了文件数量限制,同样的情况也会发生。通过尝试创建 2000 个多文件来测试以下配额限制,而配额限制为 1000;通过添加大量新文件来实现这一点:`for i in {1..2000}; do touch ~/test$i.txt; done`。这将导致以下错误消息:
touch: cannot touch ‘/home/jack/test1001.txt’: Disk quota exceeded
要暂时关闭特定文件系统的用户和组配额检查,可以以`root`用户身份运行`xfs_quota -x -c 'off -u -g' /home/`(`-u`代表用户,`-g`代表组)。这只是一时的;要重新启用它,需要重新挂载感兴趣的文件系统,即`umount /home;mount -a`。要删除特定的配额规则,只需将其限制设置为零,例如:
xfs_quota -x -c ‘limit bhard=0 john’ /home
接下来,我们在*目录*级别而不是用户/组级别设置配额。这是 XFS 文件系统独有的功能;所有其他文件系统只能在磁盘或分区级别设置配额。如果您不想为特权用户或组设置配额限制,则能够控制目录层次结构的磁盘使用量非常有用。要激活目录配额,我们首先必须将其作为内核引导选项启用,因为默认情况下,根卷被标记为`noquota`。此外,我们在`/etc/fstab`中为根分区添加了`prjquota`指令以使其生效。如果您想了解更多关于内核引导选项的信息,请阅读第一章中的引导加载程序配方,*安装 CentOS*。要为根分区设置文件系统标志,我们需要重新启动系统。完成此操作后,我们通过查看`mtab`文件确保已成功设置引导选项,该文件列出了所有当前挂载的文件系统。接下来,我们在`/etc/projid`文件中设置了一个具有关联唯一项目 ID(我们随机选择`1400`)的项目名称。在下一步中,我们将此新项目 ID(`1400`)应用于`/etc/projects`文件中的目录`/srv/data`。该系统允许将特定的项目配额规则应用于许多不同的目录。之后,我们使用`xfs_quota`命令的`project`选项为根分区初始化项目配额,并为该项目名称创建了一个`limit`配额规则。在`/etc/projects`文件中定义的与相应项目 ID 对应的目录都会受到此规则的影响。这种类型的系统可用于精细的多文件夹配额规则。对于每个目录,您可以设置一个新的项目名称或重用特定的名称,使该系统非常灵活。 在本例中,我们为项目名称`myProject`设置了 1200 兆字节的块大小硬限制。要测试此配额,请输入以下内容:
dd if=/dev/zero of=/srv/data/dd.img bs=1M count=1201
使用以下命令行错误消息,应该可以在写入 1200 兆字节后准确停止`dd`:
dd: error writing ‘/srv/data/dd.img’: No space left on device
## 还有更多... 顾名思义,本例中所示的`xfs_quota`程序仅适用于 XFS 文件系统。如果您想为其他文件系统(如 ext4 或 btrfs)在用户或组级别使用磁盘配额,则必须安装`quota`软件包(`yum install quota`)。设置配额的方式与本例中所示的步骤类似;请阅读手册`man quota`以开始使用。 # 维护文件系统 在本教程中,我们将学习如何检查和可选地修复 CentOS 7 文件系统的完整性。文件系统不一致是罕见的事件,文件系统检查通常在启动时自动运行。但是,系统管理员也应该知道如何手动运行这些测试,如果他们认为文件系统存在问题。 ## 准备工作 要完成本教程,你需要一个具有 root 权限的 CentOS 7 操作系统的正常安装。我们将使用虚拟块设备而不是真实磁盘设备,因为我们*不能*在*已挂载*的磁盘上应用任何文件系统检查。因此,你应该已经应用了*格式化和挂载文件系统*教程,并创建了一个 1GB 的虚拟块设备,有两个分区,每个分区大小为总大小的一半:首先是一个带有 XFS 的分区,然后是另一个带有 ext4 文件系统的分区。在本例中,我们将使用名为`/dev/loop0`的虚拟块设备。 如前所述,这些可以很容易地替换为真实的磁盘名称。 ## 如何操作... 1. 首先,以`root`身份登录,并显示当前连接到系统的块设备信息: ``` lsblk -io NAME,TYPE,SIZE,MOUNTPOINT,FSTYPE,MODEL ``` 1. 在这里,你应该看到`loop0`设备上有两个分区:`/dev/loop0p1`和`/dev/loop0p2`。如果你看到它们当前被挂载到系统上,请现在卸载它们: ``` umount /dev/loop0p1 umount /dev/loop0p2 ``` 1. 现在,让我们检查示例中的 loop0p1(适当更改)的 XFS 文件系统: ``` xfs_repair -n /dev/loop0p1 ``` 1. 对于磁盘上的第二个 ext4 分区,我们将使用以下行: ``` fsck -f /dev/loop0p2 ``` ## 工作原理... 在本教程中,我们学习了在 XFS 或 ext4 文件系统上运行文件系统检查是多么简单。你应该学到的最重要的一课是,在运行任何文件系统检查之前,你总是必须*卸载*你的磁盘分区! 那么,我们从这次经历中学到了什么? 由于我们不能在任何已挂载的设备上运行文件系统检查,如果你想检查系统的磁盘和分区,通常你必须在*救援*模式下运行这些检查,其中你的文件系统未挂载(例如,你不能卸载根分区来检查,因为它一直需要由系统使用,而对于单独的 home 分区,这是可能的)。 对于 XFS 文件系统,我们使用`xfs_repair`工具,对于其他所有文件系统,我们将使用带有`-f`参数(强制)的`fsck`程序来检查我们的文件系统。 重要的是要注意,我们总是需要运行`fsck`而不是特定的`fsck.<文件系统类型>`(如`fsck.ext4`,`fsck.btrfs`),因为它会自动检测正确的工具。这是必要的,因为如果你在错误的文件系统上运行错误的特定`fsck.<文件系统类型>`工具(比如在 btrfs 文件系统上运行`fsck.ext4`),它可能会完全破坏它! ## 还有更多... 到目前为止,我们只向你展示了如何使用`xfs_repair`和`fsck`*检查*文件系统。如果在 XFS 文件系统的“检查”运行期间出现错误,请在不使用`-n`选项的情况下运行`xfs_repair`——例如,使用`xfs_repair /dev/loop0p1`。在非 XFS 分区(如 ext4)上,你将使用`fsck`的`-a`选项(`a`代表自动修复)——例如,`fsck -a /dev/loop0p2`。对于`fsck`,如果你有很多错误,最好也使用`-y`,这样你就不必确认每个错误修复。 现在,让我们模拟如果我们使用虚拟块设备获得了一个损坏的 XFS 文件系统会发生什么(*千万不要*在任何真实磁盘分区上这样做!): 1. 首先,将`/dev/loop0p1`分区挂载到你的根文件系统上: ``` mkdir /media/vbd-1 mount -t xfs /dev/loop0p1 /media/vbd-1 ``` 1. 接下来,在这个挂载的文件系统上创建大量文件——例如,`2000`个文件: ``` for i in {1..2000}; do dd if=/dev/urandom bs=16 count=1 of=/media/vbd-1/file$i; done ``` 1. 现在,卸载设备并使用`dd`破坏文件系统: ``` umount /dev/loop0p1 dd bs=512 count=10 seek=100 if=/dev/urandom of=/dev/loop0p1 ``` 1. 现在,运行文件系统检查: ``` xfs_repair -n /dev/loop0p1 ``` 1. 这很可能会向你显示一份损坏文件的列表;为了修复它,请使用以下行: ``` xfs_repair /dev/loop0p1 ``` 你还可以在你的 ext4 虚拟块设备上模拟文件系统损坏,然后使用`fsck -ay /dev/loop0p2`修复它。 # 扩展文件系统的容量 CentOS 7 使用**逻辑卷管理器**(**LVM**)来组织你的分区的结构和可用容量。它是一个非常动态和灵活的系统,可以随着时间的推移进行扩展或重新排列,并且在当今最苛刻和不断变化的环境中是必不可少的。目前,到处都可以听到大数据或云计算这样的流行词。由于不断产生大量数据,存储需求和磁盘空间必须以同样的稳定速度增长,。在这个食谱中,你将学习如何使用 LVM 系统,以及如何扩展你的物理驱动器,以及如何缩小和扩展你的文件系统的容量。 ## 准备就绪 要完成这个食谱,你需要一个安装了 CentOS 7 操作系统并具有 root 权限的工作环境。我们将使用虚拟块设备而不是真实磁盘设备,从头开始教你如何设置 LVM,然后如何使用它。请阅读*创建虚拟块设备*食谱,并创建三个 1GB 的虚拟块设备,使用 GPT 分区表,在本例中将被标记为`/dev/loop0`、`/dev/loop1`和`/dev/loop2`。 再次,如果你准备好了,可以自由使用真实磁盘设备。 ## 如何做到这一点... 首先,我们将开始创建一个类似于标准 CentOS 7 LVM 结构的 LVM 测试环境,该结构在每个服务器系统的安装过程中设置: 1. 首先,让我们以`root`身份登录并显示有关我们的虚拟块设备的信息: ``` lsblk -io NAME,SIZE ``` 1. 接下来,在每个三个虚拟块设备上创建跨越整个磁盘的新分区(不带文件系统标签): ``` parted -a optimal /dev/loop0 mkpart primary 2048KiB 100% parted -a optimal /dev/loop1 mkpart primary 2048KiB 100% parted -a optimal /dev/loop2 mkpart primary 2048KiB 100% ``` 1. 现在,让我们在每个循环设备上创建 LVM*物理卷*(输入`yes`以移除`gpt`标签): ``` pvcreate /dev/loop0p1 pvcreate /dev/loop1p1 pvcreate /dev/loop2p1 ``` 1. 接下来,显示有关我们的物理卷的信息: ``` pvdisplay ``` 1. 接下来,我们将在第一个物理卷上创建一个新的 LVM 卷组: ``` vgcreate myVG1 /dev/loop0p1 ``` 1. 现在,显示有关创建的组的信息: ``` vgdisplay myVG1 ``` 1. 之后,让我们在我们的第一个卷组上创建一些逻辑卷,这些逻辑卷将被视为我们 Linux 系统中的虚拟分区: ``` lvcreate -L 10m -n swap myVG1 lvcreate -L 100m -n home myVG1 lvcreate -L 400m -n root myVG1 ``` 1. 接下来,显示有关逻辑卷的信息: ``` lvdisplay myVG1 ``` 1. 现在,显示我们的底层卷组还剩下多少可用空间,如果你想扩展一些逻辑卷,这将变得很重要(查看输出中的`Free PE / Size`部分): ``` vgdisplay myVG1 ``` 1. 之后,让我们在那些新的逻辑卷上创建文件系统: ``` mkswap /dev/myVG1/swap mkfs.xfs /dev/myVG1/home mkfs.xfs /dev/myVG1/root ``` 1. 现在,在我们创建了测试 LVM 系统(它与真实的 CentOS LVM 标准布局非常相似,但尺寸较小)之后,让我们开始使用它。 1. 首先,让我们将`root`分区的大小从当前的`400`兆字节(`M`)缩小`200`兆字节,然后,让我们将`home`分区的大小增加`500`兆字节(确认可能的数据丢失): ``` lvresize -L -200m /dev/myVG1/root lvresize -L +500m /dev/myVG1/home ``` 1. 再次使用`vgdisplay myVG1`来查看运行前面的命令后卷组的可用空间如何变化(查看`Free PE / Size`)。 1. 现在,让我们扩展增长,逻辑卷上的 XFS 文件系统: ``` mkdir /media/home-test;mount /dev/myVG1/home /media/home-test xfs_growfs /dev/myVG1/home ``` ### 注意 非常重要的一点是,不要使用`resize2fs`来扩展 XFS 文件系统,因为它们不兼容,可能会导致文件系统损坏。 1. 现在,假设过了一段时间你的数据再次增长,你需要将 home 分区扩展到 1.5 千兆字节(`G`),但你的底层卷组只剩下 184.00 MiB。首先,我们需要将本菜谱开始时准备的两个物理卷添加到我们的卷组中: ``` vgextend myVG1 /dev/loop1p1 /dev/loop2p1 vgdisplay myVG1 ``` 1. 之后,我们的卷组中有足够的可用空间(查看`Free PE / Size`)来扩展我们的 home 逻辑卷(卷必须保持挂载状态): ``` lvresize -L +1500m /dev/myVG1/home xfs_growfs /dev/myVG1/home ``` ## 它是如何工作的... 在本菜谱中,我们向您展示了如何使用 LVM 处理 XFS 分区。它是为了动态管理多个硬盘上的磁盘空间而开发的。您可以轻松地将多个物理硬盘合并在一起,使它们对系统来说就像一个单一的虚拟硬盘。这使得它比使用传统的静态分区更加灵活和可扩展。传统的分区受限于它们所在的硬盘总容量,不能超过这个容量,而且它们的静态分区布局不容易改变。此外,我们还介绍了一些重要的 LVM 技术术语,它们为硬盘提供了不同的抽象层,本节将解释这些概念背后的内容:**物理卷**(**pv**)、**卷组**(**vg**)和**逻辑卷**(**lv**)。 那么,我们从这次经历中学到了什么? 我们从这个菜谱开始,创建了三个每个 1 千兆字节(`G`)的虚拟块设备,然后在每个设备上创建了一个跨越整个设备的分区。之后,我们使用`pvcreate`命令将这些单分区设备定义为物理卷(pv)。pv 是 LVM 术语,定义了 LVM 世界中的存储单元。它必须定义在分区、全驱动器或循环设备上。pv 只是对周围分区中所有可用空间的抽象,以便我们可以基于 LVM 进行工作。接下来,我们使用`vgcreate`命令创建了一个卷组(vg),在这里我们还必须定义一个我们选择的卷组名称,并将第一个 pv 作为基本存储卷放入其中。如你所见,一个 vg 至少包含一个 pv(我们稍后会添加更多 pv)。向 vg 添加或从 vg 删除 pv 是整个 LVM 系统可扩展性概念的核心。pv 不必都是相同的大小,并且可以通过添加数十个新物理驱动器(全部定义为 pv)来扩展 vg。你的系统上可以有多个 vg,并且可以通过你给它们的唯一名称来识别它们。因此,总之,要扩展 vg 的空间,你必须从物理驱动器创建 pv,然后你可以添加它们。 最终,我们在我们的卷组(vg)上创建了逻辑卷(lv),这些逻辑卷在卷组内部可以像真实的物理分区一样被看到和使用。在这里,我们使用`lvcreate`命令创建了三个 lv,通过这个命令我们需要定义我们想要放置目标 lv 的 vg 的名称(记住,你的系统上可以有多个 vg),以及卷的大小,以及作为最后一个参数的名称。你可以将多个 lv 添加到一个 vg 中,并且不需要使用 vg 底层可用空间中的全部分配空间。你可以非常灵活地使用它。最好的部分是,你关于卷的大小和布局的决定不必永远固定;你可以在任何时候更改它们。这是一个非常动态的系统,可以扩展和缩小,删除和创建,而不需要事先卸载卷。但是你必须记住,所有 lv 都绑定到一个 vg,没有 vg 就不可能创建它们,也不能超出其空间边界。如果你需要将 lv 的空间扩展到基础 vg 的边界之外,你必须扩展 vg,如本菜谱所示。 ### 注意 你可能已经注意到,对于每个 LVM 术语,都有一个“显示”和“创建”命令,所以很容易记住:`pvdisplay`,`vgdisplay`,`lvdisplay`,`pvcreate`,`vgcreate`,`lvcreate`。 在成功创建了逻辑卷之后,您可以像处理系统上的其他块设备分区一样处理它们。唯一的区别是它们位于特殊的设备文件夹中:`/dev/<vg name>/<lv name>`或`/dev/mapper/<vg name>/<lv name>`。例如,在本示例中创建的家卷的名称为`/dev/myVG1/home`。最后,为了将它们用作正常的挂载点,我们在它们上创建了一些测试文件系统。 在本食谱的第二部分中,我们向您展示了如何扩展我们的卷组以及如何缩小和扩展我们的逻辑卷测试系统。 我们首先使用`vgdisplay myVG1`命令来显示卷组上当前可用的空间。在命令输出中,我们看到我们的当前卷组总共有`996M`(`VG Size`),我们的逻辑卷(`swap`,`home`,`root`)的已分配大小为`512M`(`Alloc PE / Size`),空闲大小为`484M`(`Free PE /Size`)。接下来,我们使用`lvresize`命令来缩小和扩展逻辑卷的根和家。`-L`参数设置卷的新大小,使用`+`或`-`符号,值将添加到或从逻辑卷的实际大小中减去。如果没有它,该值将被视为绝对值。请记住,我们只能增加家分区,因为当前卷布局没有占用卷组的总空间。调整大小后,如果我们再次使用`vgdisplay`命令,我们会看到我们现在在卷组中占用了更多的空间;其空闲大小已减少到`184M`。由于我们将`home`卷从`100M`扩展到`500M`,因此我们需要记住也要扩展其 XFS 文件系统,因为扩展卷不会自动扩展其文件系统。因此,当前卷的`400M`未分配,没有任何文件系统信息。我们使用了`xfs_growfs`命令,该命令将不定义限制参数,使用完整的未分配区域用于 XFS 文件系统。如果您想调整任何其他文件系统类型的大小,例如 ext4,则可以使用`resize2fs`命令代替。 最后,我们想将家卷扩展`1.5G`,但我们只有`184M`剩余的空间来扩展。这就是 LVM 真正*闪耀*的地方,因为我们可以简单地向其中添加更多的物理卷(在现实世界中,您只需在服务器中安装新的硬盘并将其用作 pvs)。我们向您展示了如何使用`vgextend`命令将两个 1G 大小的 pvs 添加到卷组中来*扩展*卷组的容量。之后,我们使用`vgdisplay`查看我们的卷组现在已经增长了 3G 的总大小,所以最后我们可以扩展我们的家逻辑卷,因为它现在可以适合它。作为最后一步,我们再次扩展了 XFS 文件系统,以填充整个 2G 的家卷大小。 请始终牢记,如果你在多个物理硬盘上使用 vg,你的数据将会在这些硬盘之间分布。LVM 并非 RAID 系统,不具备冗余性,因此如果一个硬盘损坏,你的整个 vg 也会随之失效,数据将丢失!为了解决这个问题,一个建议的解决方案是在硬盘上使用物理 RAID 系统,并在其上创建 LVM。 # 第六章:提供安全性 在本章中,我们将介绍以下主题: + 锁定远程访问并加固 SSH + 安装和配置 fail2ban + 使用防火墙 + 通过示例伪造防火墙规则 + 生成自签名证书 + 使用安全的 FTP 替代方案 # 引言 本章是一系列操作的集合,为服务器在几乎任何环境中提供安全性提供了坚实的基础。安全性是优秀管理员的基础,本章说明了您可以如何快速轻松地设计和实施一系列检查点,以提供所需的保护。 # 锁定远程访问并加固 SSH 在本操作中,我们将学习如何提供额外的安全措施以加固安全 Shell 环境。**安全 Shell**(**SSH**)是提供远程访问服务器的基本工具包。远程机器的实际距离无关紧要,但 Shell 环境使您能够执行维护、升级、软件包安装和文件传输;您还可以在安全环境中执行作为管理员所需执行的任何操作。这是一个重要的工具;作为进入系统的门户,本操作的目的是向您展示如何执行一些基本的配置更改,以保护您的服务器免受不受欢迎的访客。 ## 准备 要完成此操作,您需要具备 CentOS 7 操作系统的最小安装、具有 root 权限、您选择的基于控制台的文本编辑器以及连接到互联网以下载其他软件包的能力。假设您的服务器已经至少维护了一个基于非 root 的管理员帐户,可以使用此操作提供的功能。 ## 如何操作... SSH 的作用对于远程管理服务器至关重要,因此有必要提供一些基本步骤以确保其安全: 1. 首先,以`root`身份登录并创建原始配置文件的备份,方法是键入以下命令: ``` cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak ``` 1. 现在,通过键入以下内容打开主`sshd`配置文件: ``` vi /etc/ssh/sshd_config ``` 1. 我们将首先调整允许完成登录过程的时间,因此请向下滚动并找到以下行: ``` #LoginGraceTime 2m ``` 1. 取消注释此行并将其值更改为更合适的值,例如: ``` LoginGraceTime 30 ``` 1. 现在,再向下滚动几行并找到以下行: ``` #PermitRootLogin yes ``` 1. 将其更改为以下内容: ``` PermitRootLogin no ``` 1. 找到以下行: ``` X11Forwarding yes ``` 1. 并将其更改为以下内容: ``` X11Forwarding no ``` 1. 在重新启动 SSH 服务之前,保存并关闭文件,如下所示: ``` systemctl restart sshd ``` 1. 在此阶段,您可能希望在退出当前会话之前,使用新设置创建一个新的 SSH 会话。这是为了确保一切正常工作,并避免意外锁定自己无法访问服务器。如果您在启动新的 SSH 会话时遇到困难,只需返回到原始会话窗口并进行必要的调整(然后重新启动 SSH 服务)。但是,如果没有遇到任何困难,并且您已成功登录到辅助会话,则可以通过键入`exit`关闭原始 shell 环境。 ### 注意 请记住,遵循本教程后,您现在应该发现 shell 的 root 访问权限已被拒绝,您必须使用标准用户帐户登录。任何需要 root 权限的进一步工作都需要使用`su`或`sudo`命令,具体取决于您的偏好。 ## 它是如何工作的... SSH 是一项至关重要的服务,它使您能够远程访问服务器。没有它,服务器管理员将无法工作。在本教程中,我们向您展示了如何使该服务更加安全。 那么,我们从这次经历中学到了什么? 我们首先创建了原始主`sshd`配置文件的备份副本。接下来是打开并编辑它。SSH 的配置文件维护了一个长长的设置列表,这些设置非常适合大多数内部需求,但对于生产环境中的服务器,通常建议更改默认的 SSH 配置文件以满足您的特定需求。在这方面,第一步是建议更改登录宽限时间,`LoginGraceTime 30`。与默认的两分钟不同,前面的值将只允许最多 30 秒。这是用户可以连接但尚未开始身份验证过程的时间段;数字越低,保持打开的未经验证的连接就越少。接下来,我们通过使用`PermitRootLogin no`指令删除了远程用户以 root 用户身份登录的能力。在大多数情况下,这是必须的,除非服务器处于受控环境中,否则远程服务器不应允许直接 root 登录。这样做的原因是为了降低被黑客攻击的风险。每个 SSH 黑客试图破解的第一件事是 root 用户的密码。如果您不允许 root 登录,攻击者还需要猜测用户名,这要复杂得多。下一个设置简单地禁用了`X11Forwarding`。在这些情况下,通常是一个好主意,应用短语“如果您不使用它,请禁用它”。为了完成本教程,您需要重新启动 SSH 服务器,以便允许更改立即生效,并启动一个新的 SSH 会话,以确保修改确实按预期工作。没有任何系统是绝对安全的,但通过这样做,您现在可以放心,知道您已经使 SSH 服务器更加安全。 ## 还有更多... 为了使您的 SSH 服务器更加安全,还有几个主题需要涵盖:我们应该更改 SSH 端口号,并向您展示如何限制特定系统用户的 SSH 访问。 ### 更改服务器 SSH 端口号 端口 22 是所有 SSH 服务器使用的默认端口,更改使用的端口号可以在一定程度上增加服务器整体安全性。再次打开主 SSH 守护程序配置文件`sshd_config`。现在,向下滚动并找到以下行:
#Port 22
删除前面的`#`字符(取消注释)并将端口号更改为另一个值,将`XXXX`替换为适当的端口号:
Port XXXX
您必须确保新端口号未被使用,完成后保存文件并关闭。请记住,此处所做的任何更改都会反映在您的防火墙配置中。因此,我们还需要在 firewalld 中打开新端口。通过环境变量`NEWPORT`设置新端口(将`XXXX`替换为您的新 SSH 端口),然后执行以下`sed`命令以更改 SSH firewalld 服务文件并在之后重新加载`firewalld`守护进程(有关详细信息,请阅读本章中的防火墙配方):
NEWPORT=XXXX
sed “s/port=“22”/port=”$NEWPORT"/g" /usr/lib/firewalld/services/ssh.xml > /etc/firewalld/services/ssh.xml firewall-cmd --reload
此外,我们还需要告诉 SELinux(参见第十四章,*使用 YUM 管理包*)。 ## 如何操作... `fail2ban`默认未安装,因此我们需要调用 YUM 包管理器并下载必要的包: 1. 为了开始本食谱,以`root`身份登录并输入以下命令: ``` yum install fail2ban-firewalld fail2ban-systemd ``` 1. 在你的首选文本编辑器中创建一个新的配置文件,如下所示: ``` vi /etc/fail2ban/jail.local ``` 1. 放入以下内容: ``` [DEFAULT] findtime = 900 [sshd] enabled = true ``` 1. 现在,添加以下定义封禁期限的行。它是以秒为单位计算的,因此调整时间期限以反映一个更合适的值。在这种情况下,我们选择将其设为一小时: ``` bantime = 3600 ``` 1. 然后,添加最大登录尝试次数: ``` maxretry = 5 ``` 1. 如果你通过非`22`的定制端口运行 SSH,你需要告诉`fail2ban`这一点(用你选择的端口号替换`XXXX`),否则跳过此步骤: ``` port=XXXX ``` 1. 现在,以通常的方式保存并关闭文件,然后继续在启动时启用`fail2ban`服务。为此,输入以下命令: ``` systemctl enable fail2ban ``` 1. 为了完成本食谱,你现在应该通过输入以下命令来启动服务: ``` systemctl start fail2ban ``` ## 它是如何工作的... `fail2ban`旨在监控那些在你的服务器上反复登录失败的用户,其主要目的是减轻旨在破解密码和窃取用户凭据的攻击。它通过持续读取系统日志文件来工作,如果其中包含指示多次失败尝试的模式,那么它将采取行动对抗违规 IP 地址。我们都知道服务器不是孤立存在的,通过使用这个工具,在几分钟内,服务器将运行在额外的保护层之下。 那么,我们从这次经历中学到了什么? `fail2ban`并未包含在标准的 CentOS 仓库中,因此您的服务器需要能够访问 EPEL 仓库。`fail2ban`软件包的安装非常简单;除了主要的`fail2ban`软件包外,我们还安装了另外两个软件包,以便将其集成到 CentOS 7 的新`systemd`和 firewalld 服务器技术中。接下来,为了进行本地定制,我们创建了一个新的`jail.local`文件。我们首先为所有目标(在`[DEFAULT]`部分中指定)指定了`findtime`参数,这是用户尝试登录的时间。该值以秒为单位,意味着如果用户在指定时间内未能成功登录,则他们将被禁止。接下来,我们通过添加一个`[sshd]`部分来启用`fail2ban`服务。在该部分中,我们引入了`bantime`值,该值表示如果主机违反规则,将被阻止访问服务器的总秒数。基于此,您被要求确定在阻止之前允许的最大登录尝试次数。此外,如果您更改了服务的标准监听端口,则必须使用`port`指令定义自定义端口。为了测试您的设置,请尝试使用 SSH 认证用户并提供错误的密码五次。在第六次尝试时,您应该在一个小时内无法返回到登录提示! 保护`sshd`服务免受暴力攻击只是开始的第一步,而使用`failban`还有很多需要学习的地方。要排查服务问题,请查看位于`/var/log/fail2ban.log`的日志文件。为了获取一些关于如何使用它的想法,请打开以下示例`failban`配置文件:`less /etc/fail2ban/jail.conf`。 # 与防火墙协同工作 防火墙是一种程序,它监控和控制系统网络接口的传入和传出网络流量,并可以限制传输到仅对计算机系统或网络有用和无害的数据。默认情况下,CentOS 提供了一个极其强大的防火墙,直接构建在内核中,称为**netfilter**。虽然在旧版本的 CentOS 中,我们使用著名的 iptables 应用程序来控制它,但在版本 7 中,新的标准 netfilter 管理程序已更改为名为`firewalld`的服务,该服务默认情况下已在每个 CentOS 7 服务器上安装并启用。 这是一个非常强大的服务,可以完全控制服务器的防火墙安全,并且比 iptables 更容易使用。它的主要优点是它具有更好的结构和更逻辑的方法来管理和配置现代防火墙解决方案的各个方面。因此,它将成为您服务器安全的基础,因此本食谱的目的是让您快速了解 firewalld 的基本原理。 ## 准备就绪 要完成本食谱,您需要具有 root 权限的 CentOS 7 操作系统的最小安装以及您选择的基于控制台的文本编辑器。 ## 如何做到这一点... 由于`firewalld`服务在每个 CentOS 7 服务器上默认运行,因此我们可以直接通过以`root`用户身份登录到服务器来开始使用该服务。 1. 键入以下命令以查询与区域相关的信息: ``` firewall-cmd --get-zones | tr " " "\n" firewall-cmd --list-all-zones firewall-cmd --get-default-zone firewall-cmd --list-all ``` 1. 我们可以通过使用以下行切换到不同的防火墙`默认`区域: ``` firewall-cmd --set-default-zone=internal ``` 1. 临时将网络接口添加到`区域`: ``` firewall-cmd --zone=work --add-interface=enp0s8 ``` 1. 现在,临时将服务添加到`区域`: ``` firewall-cmd --zone=work --add-service=ftp ``` 1. 测试添加接口和服务是否成功: ``` firewall-cmd --zone=work --list-all ``` 1. 现在,永久添加服务: ``` firewall-cmd --permanent --zone=work --add-service=ftp firewall-cmd --reload firewall-cmd --zone=work --list-all ``` 1. 最后,让我们通过打开以下文件来创建一个新的防火墙区域: ``` vi /etc/firewalld/zones/seccon.xml ``` 1. 现在输入以下内容: ``` <?xml version="1.0" encoding="utf-8"?> <zone> <short>security-congress</short> <description>For use at the security congress. </description> <service name="ssh"/> </zone> ``` 1. 保存并关闭,然后重新加载`防火墙`配置,以便我们可以看到新区域: ``` firewall-cmd --reload ``` 1. 最后,检查新区域是否可用: ``` firewall-cmd --get-zones ``` ## 它是如何工作的... 与 iptables 相比,新的 firewalld 系统隐藏了创建复杂网络规则的过程,并且具有非常简单的语法,出错的可能性较小。它可以在运行时动态重新加载 netfilter 设置,而无需重新启动整个服务,并且我们可以在每个系统上设置多个防火墙配置,这使得它在不断变化的网络环境中工作时非常出色,例如对于移动设备如笔记本电脑。在本食谱中,我们向您介绍了 firewalld 的两个基本构建块:**区域**和**服务**。 那么,我们从这次经历中学到了什么? 我们从这个食谱开始使用`firewall-cmd`来获取系统上可用防火墙区域的信息。Firewalld 引入了网络或防火墙区域的新概念,它为服务器的网络接口及其相关连接分配不同级别的信任。在 CentOS 7 中,已经存在一些预定义的 firewalld 区域,所有这些区域(例如,`private`、`home`、`public`等,除了`trusted`区域)将阻止任何形式的传入网络连接到服务器,除非它们被附加到区域的特殊规则明确允许(这些规则称为 firewalld 服务,我们将在后面看到)。我们使用`firewall-cmd`查询区域信息,使用`--get-zones`或(更详细)使用`--list-all-zones`参数。每个这些区域都作为一个完整和全面的防火墙,您可以根据系统的环境和位置使用。例如,顾名思义,`home`区域适用于您的计算机位于家庭区域的情况。如果选择此选项,您基本上信任网络上的所有其他计算机和服务不会损害您的计算机,而公共区域更多地用于公共场所,如公共接入点等。在这里,您不信任网络上的其他计算机和服务不会伤害您。在 CentOS 7 上,安装后设置的标准`default`区域配置是`public`区域,我们使用命令的`--get-default-zone`参数显示,并使用`--list-all`更详细地显示。 ### 注意 简而言之,firewalld 区域主要是关于控制服务器上的传入连接。使用 firewalld 限制传出连接也是可能的,但这超出了本书的范围。 此外,为了获取所有当前可用区域的更多技术信息,我们使用了防火墙客户端的`--list-all-zones`参数。在命令的输出中,您会注意到一个区域可以有一些关联的网络接口和一个属于它的服务列表,这些是应用于传入网络连接的特殊防火墙规则。您可能还会注意到,虽然默认列出所有区域及其关联服务的详细信息,但所有 firewalld 区域都非常限制,几乎不允许任何东西连接到服务器。此外,从上面的命令输出中还可以看到另一个非常重要的概念。我们的`public`区域被标记为`default`和`active`。虽然`active`区域是直接与网络接口关联的区域,但如果您有多个网络适配器可用,`default`区域确实可以变得非常重要。在这里,它充当标准的最小防火墙保护和回退策略,以防您错过了为每个接口分配一些活动区域。对于只有一个网络接口设置的系统,`default`区域还将自动设置`active`区域。要设置`default`区域,我们使用了`--set-default-zone`参数,并且要使区域对某个接口处于活动状态,我们使用了`--add-interface`。请注意,如果您不指定`--zone`参数,大多数`firewall-cmd`命令将使用`default`区域来应用设置。Firewalld 正在监听系统上的每个网络接口,并等待新的网络数据包到达。总之,我们可以说,如果有新的数据包进入特定接口,Firewalld 接下来要做的是找出与我们网络接口关联的正确区域(使用其活动配置,或者如果没有可用的话,使用其默认配置);找到它之后,它将对属于它的网络数据包应用所有服务规则。 接下来,我们向您展示了如何使用 firewalld 服务。简单来说,firewalld 服务是规则,它们在我们的防火墙内打开并允许与我们的服务器建立特定连接。使用这种服务文件定义允许包含的规则的可重用性,因为它们可以添加或删除到任何区域。此外,使用系统中已有的预定义 firewalld 服务,而不是手动查找并打开协议、端口或端口范围,使用复杂的 iptables 语法为您的系统服务感兴趣,可以使您的管理工作变得更加容易。我们通过调用`--add-service`将`ftp`服务添加到`work`区域。之后,我们使用`--list-all`打印出 work 区域的详细信息。firewalld 被设计为具有分离的运行时和永久配置。对运行时配置的任何更改都会立即生效,但会消失,而永久配置将在重新加载或重启 firewalld 服务后仍然存在。一些命令,如切换默认区域,会将更改写入两个配置,这意味着它们会立即在运行时应用,并且在服务重启后仍然持久。其他配置设置,如将服务添加到区域,仅写入运行时配置。如果重新启动 firewalld,重新加载其配置,或重新启动计算机,这些临时更改将丢失。为了使这些临时更改永久化,我们可以使用`--permanent`标志与`firewall-cmd`程序调用一起将其写入永久配置文件。 与运行时选项不同,这里的更改不会立即生效,只有在服务重启/重新加载或系统重启后才会生效。因此,对于这种仅运行时命令的永久设置,最常见的方法是首先使用`--permanent`参数应用设置,然后重新加载防火墙的配置文件以实际激活它们。 最后,我们向您展示了如何创建自己的区域,这只是一个您需要在`/etc/firewalld/zones/`目录中创建的 XML 文件,我们在其中指定了名称、描述以及您想要激活的所有服务。如果您在任何防火墙配置文件中做了更改,别忘了之后重新加载防火墙配置。 为了完成这个配置,我们将撤销对`work`区域所做的永久性更改,并重新加载 firewalld 以重置在本配置中应用的所有非永久性更改:
firewall-cmd --permanent --zone=work --remove-service=ftp
firewall-cmd --reload
## 还有更多... 为了解决阻止服务的问题,而不是完全关闭防火墙,您应该将`zone`切换到`trusted`,这将打开所有传入端口到防火墙:
firewall-cmd --set-default-zone=trusted
一旦您完成了测试,只需切换回您之前所在的区域,例如:
firewall-cmd --set-default-zone=public
# 通过示例构建防火墙规则 在本教程中,我们希望向您展示如何创建您自己的 firewalld 服务定义,或者如何更改现有的服务定义,这是任何 CentOS 7 系统管理员都应该知道的,如果预定义的服务文件不符合您系统的需求。 ## 准备就绪 要完成本教程,您需要一个最小安装的 CentOS 7 操作系统,具有`root`权限和一个基于控制台的文本编辑器。我们将更改 firewalld 中 SSH 服务的端口号,因此请确保您已按照教程*锁定远程访问并加固 SSH*中的说明配置了新端口。在我们的示例中,我们将端口更改为`2223`。此外,我们将为一个小型的基于 Python 的 Web 服务器创建一个新的 firewalld 服务,我们将使用它来演示如何将新的系统服务集成到 firewalld 中。在开始之前,通过*使用防火墙*教程掌握 firewalld 的基础知识是有益的。 ## 如何操作... 在本教程中,我们将向您展示如何更改和如何创建新的 firewalld 服务定义。在本教程中,我们假设我们处于默认的公共区域。 ### 更改现有的 firewalld 服务(ssh) 1. 首先,以`root`身份登录,并将`ssh`服务复制到正确的位置以进行编辑: ``` cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services ``` 1. 接下来,打开`ssh`服务定义文件: ``` vi /etc/firewalld/services/ssh.xml ``` 1. 将端口从`22`更改为`2223`,然后保存文件并关闭它: ``` <port protocol="tcp" port="2223"/> ``` 1. 最后,重新加载防火墙: ``` firewall-cmd --reload ``` ### 创建您自己的新服务 执行以下步骤以创建您自己的新服务: 1. 打开一个新文件: ``` vi /etc/firewalld/services/python-webserver.xml ``` 1. 输入以下服务定义: ``` <?xml version="1.0" encoding="utf-8"?> <service> <short>Python Webserver</short> <description>For pythons webservers</description> <port port="8000" protocol="tcp"/> </service> ``` 1. 保存并关闭文件,然后最后重新加载防火墙: ``` firewall-cmd --reload ``` 1. 现在,将此新服务添加到我们的`default`区域: ``` firewall-cmd --add-service=python-webserver ``` 1. 之后,运行以下命令以在端口`8000`上启动一个简单的 Python Web 服务器(按下*Ctrl* + *C*组合键停止它): ``` python -m SimpleHTTPServer 8000 ``` 1. 恭喜!您的新网络服务器位于端口`8000`,现在可以从您网络中的其他计算机访问了。 ``` http://<ip address of your computer>:8000/ ``` ## 它是如何工作的... 在本教程中,我们展示了如何轻松地自定义或定义新的 firewalld 服务,如果预定义的服务需要更改,或者对于全新的系统服务,这些服务根本未定义。服务定义文件是简单的 XML 文件,您在其中为给定的系统服务或程序定义规则。我们的 firewalld 服务文件存放在两个不同的目录中:`/usr/lib/firewalld/services`用于系统安装时提供的所有预定义服务,以及`/etc/firewalld/services`用于所有自定义和用户创建的服务。 那么,我们从这次经历中学到了什么? 我们首先通过在正确的位置`/etc/firewalld/services`创建 SSH firewalld 服务文件的工作副本来开始这个配置。我们可以直接复制原始文件,因为该目录中的所有文件都会覆盖`/usr/lib/firewalld/services`中的默认配置文件。接下来,我们打开文件并将其默认端口从`22`更改为`2223`。每当更改系统服务的标准监听端口时,我们都需要这样做,以便让防火墙知道它应该允许通过更改后的端口的网络流量。打开文件时,您会看到服务文件是简单的 XML 文本文件,包含一些强制性和一些可选的标签和属性。它们包含一个或多个端口和协议的列表,这些定义了如果服务连接到某个区域,firewalld 应该启用什么。XML 文件中还可以有另一个重要设置:辅助模块。例如,如果您打开位于`/usr/lib/firewalld/services/samba.xml`的 SAMBA 服务文件,您会看到标签`<module name="nf_conntrack_netbios_ns"/>`。这些是特殊的内核 netfilter 辅助模块,可以动态加载到基于内核的防火墙中,并且对于某些系统服务(如 Samba 或 FTP)是必需的,这些服务在临时 TCP 或 UDP 端口上创建动态连接,而不是使用静态端口。重新加载防火墙配置后,我们现在应该能够使用更改后的端口从网络中的另一台计算机测试连接。 在本配置的第二部分,我们为一个新的系统服务创建了一个全新的服务文件,这是一个简单的 Python Web 服务器,监听端口 8000,显示简单的目录内容列表。因此,我们为 Python Web 服务器创建了一个简单的 XML 服务文件,包括正确的端口 8000,重新启动了防火墙,然后将这个新服务添加到我们的默认公共区域,以便我们实际上可以通过该服务打开连接。现在,您应该能够使用同一网络中的另一台计算机浏览到我们的 Web 服务器的起始页面。但是,由于我们没有使用`--permanent`标志,如果您重新启动 firewalld 守护进程,`python-webserver`服务将从`public`区域消失(或者您也可以使用参数`--remove-service=python-webserver`)。 总之,我们可以说,在 CentOS 7 中推荐的防火墙选择是 firewalld,因为所有重要的系统服务都已经通过预定义的服务规则设置为使用它。您应该记住,Linux 防火墙是一个非常复杂的主题,很容易填满整本书,而且您可以使用`firewall-cmd`做更多的事情,这些在这本书中无法涵盖。 ## 还有更多... 通常,您可能只想快速打开特定端口来测试事物,然后再编写自己的自定义服务定义。为此,您可以使用以下命令行,该命令行将在`default`区域上临时使用 tcp 协议打开端口`2888`:
firewall-cmd --add-port=2888/tcp
测试完成后,只需重新加载防火墙配置即可再次删除并关闭特定端口。 # 生成自签名证书 在本教程中,我们将学习如何使用 OpenSSL 工具包创建自签名**安全套接字层**(**SSL**)证书。SSL 是一种用于加密通信两端(例如服务器和客户端)之间的消息的技术,以便第三方无法读取它们之间发送的消息。证书不用于加密数据,但它们在通信过程中非常重要,以确保您与之通信的一方正是您认为的那一方。没有它们,身份冒充攻击将更加常见。 ## 准备工作 要完成此操作,您需要一个具有 root 权限和您选择的基于控制台的文本编辑器的 CentOS 7 操作系统的工作安装。 ### 注意 一般来说,如果您打算在生产服务器上使用 SSL 证书,您可能希望从受信任的证书颁发机构购买 SSL 证书。关于哪种证书最适合您的需求和预算,您有很多选择,但为了本教程的目的,我们将仅限于讨论自签名证书,这对于任何开发服务器或内部网络来说已经足够了。 ## 如何操作... 1. 首先,以`root`身份登录并转到以下目录,以便我们可以使用 Makefile 生成我们想要的证书和密钥文件: ``` cd /etc/pki/tls/certs ``` 1. 现在,要创建一个包含嵌入式公钥的自签名证书(两者都在文件`server.crt`中)以及服务器的私钥(文件名为`server.key`),请输入以下命令: ``` make server.crt ``` 1. 然后,系统会要求您输入密码并收到一系列问题,您应该用适当的值回答。通过特别注意通用名称值来完成所有必需的详细信息,该值应反映您将为此证书使用的服务器的域名或 IP 地址。例如,您可以输入: ``` mylocaldomainname.home ``` 1. 要创建一个包含自签名证书、公钥和私钥的`pem`文件,有效期为五年,请输入以下命令: ``` make server.pem DAYS=1825 ``` 1. 现在,让我们为 Apache Web 服务器创建一个密钥对(一个私钥和包含公钥的自签名证书),我们需要启用`https`,它将在`/etc/pki/tls/private/localhost.key`和`/etc/pki/tls/certs/localhost.crt`中生成(使用安全密码并在第二个命令中重复): ``` make testcert ``` 1. 要创建一个**证书签名请求**(**CSR**)文件而不是自签名证书,请使用以下命令: ``` make server.csr ``` ## 它是如何工作的... 在本教程中,我们向您介绍了使用**公钥加密技术**(**PKI**)的 SSL 技术(其中存在两种形式的密钥:公钥和私钥)。在服务器上,我们存储私钥,而客户端获得公钥。从一端发送到另一端的每条消息都由属于一侧的密钥加密,并且只能由另一侧的相应密钥解密。例如,使用服务器的私钥加密的消息只能由客户端的公钥解密和阅读,反之亦然。公钥通过证书文件发送给客户端,它是文件的一部分。如前所述,公钥负责加密和解密数据,而证书则负责识别服务器与客户端,并确保您实际上连接到了您试图连接的同一服务器。如果您想在 FTPS、HTTPS、POP3S、IMAPS、LDAPS、SMTPS 等协议中设置使用 SSL 加密的安全服务,您需要一个签名的服务器证书来配合工作。如果您想将这些服务用于您的业务,并希望使用和处理这些服务的人信任它们,例如在公共互联网上,您的证书应该由官方的**认证机构**(**CA**)签名。证书的价格按订阅支付,可能非常昂贵。如果您不打算向公众提供您的证书或启用了 SSL 的服务,或者您只想在公司内部网内提供这些服务,或者只是想在购买前测试一下,您也可以使用 OpenSSL 工具包自行签名(自签名)证书。 ### 注意 自签名证书与来自官方 CA 的证书之间的唯一区别是,大多数使用证书进行通信的程序会向您发出警告,表示它不知道该 CA,并且您不应该信任它。在确认安全风险后,您可以正常使用该服务。 那么,我们从这次经历中学到了什么? 我们从这个食谱开始,前往 CentOS 7 中所有系统证书的标准位置:`/etc/pki/tls/certs`。在这里,我们可以找到一个 Makefile,这是一个方便生成公钥/私钥对、SSL CSR 和自签名 SSL 测试证书的辅助脚本。它通过隐藏 OpenSSL 程序的复杂命令行参数来工作。它非常易于使用,并且将自动通过你的文件名参数的文件扩展名识别你的目标。因此,通过提供带有`.crt`扩展名的输出文件名来生成 SSL 密钥对是一个简单的过程。如前所述,你将被要求输入密码和一系列关于证书所有权的问题,其中最重要的是通用名称。这应该反映你计划使用此证书的服务器的域名,因为大多数程序,如网络浏览器或电子邮件客户端,将检查域名以查看它们是否有效。运行此命令的结果是证书及其嵌入的公钥在文件`server.crt`中,以及称为`server.key`的服务器的相应私钥。 接下来,我们创建了一个`.pem`文件,并提供了一个`DAYS`参数,使证书有效期为五年,而不是默认的一年,当你不带它运行时。`pem`文件是一个容器文件,包含密钥对的两部分:私钥和自签名证书(带有其嵌入的公钥)。这种文件格式有时是某些程序(如`vsftpd`)所要求的,以启用 SSL 加密,而不是提供两个分离的文件中的密钥对。接下来,我们运行了 Makefile 目标`testcert`,它生成了私钥以及公钥,以及正确位置的证书,Apache Web 服务器期望在那里设置 HTTPS。请注意,如果你需要稍后重复任何 Makefile 运行,你需要删除生成的输出文件;例如,对于 Apache,你需要在可以再次构建输出文件之前删除以下文件:
rm /etc/pki/tls/certs/localhost.crt /etc/pki/tls/private/localhost.key
make testcert
最后,我们向你展示了如何生成 CSR 文件,如果你计划从受信任的证书颁发机构购买 SSL 证书,这将需要。 ## 还有更多... 我们没有涵盖 Makefile 脚本在生成证书方面提供的所有可能性。如果你运行命令`make`而不给出任何目标参数,程序将打印出一个使用帮助文本,其中包含所有可能的选项。 正如我们所学,公钥和私钥是成对生成的,并将加密和解密对方的消息。你可以通过比较以下输出(必须完全相同)来验证你的密钥对是否有效且属于一起:
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5
# 使用 FTP 的安全替代方案 尽管 FTP 仍然流行用于共享数据或在网络上传输文件,但您必须意识到您正在使用一个非常不安全的网络协议,该协议默认情况下没有内置保护。这意味着在网络传输过程中,您的数据完全暴露给潜在的攻击者。这绝不是您希望用于传输敏感数据(如登录凭据)的方式。为了避免这些潜在风险,我们将在此菜谱中向您展示如何使用和设置两种替代方案来保护 FTP,即使用 FTPS(FTP over SSL 或 FTP/SSL)或 SFTPS(启用 SSH 的 FTP)。 ## 准备就绪 要完成此菜谱,您需要一个具有 root 权限的 CentOS 7 操作系统的最小安装和一个您选择的基于控制台的文本编辑器。您应该已经安装并配置了一个基本的 vsftpd 服务器(请参阅[第十二章](part0098_split_000.html#2TEN41-4cf34a6d07944734bb93fb0cd15cce8c "Chapter 12. Providing Web Services"),*提供 Web 服务*了解如何操作)。此外,为了设置 SFTP,我们需要创建一些自签名证书;如果您想了解其背后的详细信息,请阅读本章中的*生成自签名证书*菜谱。 ## 如何操作... 您必须事先决定是要使用 SFTP 还是 FTPS。这两种方法不能同时应用,因此您必须首先决定选择哪种选项。如果您在这两种方法之间切换,您需要先恢复`vsftpd.conf`或`sshd_config`的默认配置文件状态。 ### 使用 SSL 保护您的 vsftpd 服务器 - FTPS 要使用 SSL-FTPS 保护您的 vsftpd 服务器,请执行以下步骤: 1. 以`root`身份登录并转到标准证书位置: ``` cd /etc/pki/tls/certs ``` 1. 现在,让我们为我们的`ftp-server`配置创建一个 SSL 密钥对,该密钥对包括证书及其嵌入的公钥以及私钥在一个文件中(请记住,`Common name`值应反映您的 FTP 服务器的域名): ``` make ftp-server.pem ``` 1. 更改到更安全的文件访问规则: ``` chmod 400 /etc/pki/tls/certs/ftp-server.pem ``` 1. 现在,在对其进行操作之前,首先备份`vsftpd.conf`文件。 ``` cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.BAK ``` 1. 现在,启用 SSL 并将我们刚刚创建的密钥对文件添加到我们的`vsftpd`配置中: ``` echo "rsa_cert_file=/etc/pki/tls/certs/ftp-server.pem ssl_enable=YES force_local_data_ssl=YES force_local_logins_ssl=YES pasv_min_port=40000 pasv_max_port=40100" >> /etc/vsftpd/vsftpd.conf ``` 1. 接下来,我们需要添加一个新的 firewalld 服务文件,因此打开以下内容: ``` vi /etc/firewalld/services/ftps.xml ``` 1. 请输入以下内容: ``` <?xml version="1.0" encoding="utf-8"?> <service> <description>enable FTPS ports</description> <port protocol="tcp" port="40000-40100"/> <port protocol="tcp" port="21"/> <module name="nf_conntrack_ftp"/> </service> ``` 1. 最后,重新加载防火墙,添加`ftps`服务,并重启您的`vsftpd`服务器: ``` firewall-cmd --reload; firewall-cmd --permanent --add-service=ftps; firewall-cmd --reload systemctl restart vsftpd ``` ### 使用 SSH 保护您的 vsftpd 服务器 - SFTP 要使用 SSL-SFTP 保护您的 vsftpd 服务器,请执行以下步骤: 1. 首先,为所有有效的 SFTP 用户创建一个组: ``` groupadd sshftp ``` 1. 我们将对`sshd`主配置文件进行操作,因此在进行任何更改之前,请先备份: ``` cp /etc/ssh/sshd_config /etc/ssh/sshd_config.BAK ``` 1. 现在,打开`sshd_config`文件,转到包含`Subsystem`指令的行,禁用它(这意味着在该行前面加上`#`符号),并添加以下行,如下所示: ``` #Subsystem sftp /usr/libexec/openssh/sftp-server Subsystem sftp internal-sftp ``` 1. 接下来,在文件末尾添加以下行以启用 SFTP: ``` Match Group sshftp ChrootDirectory /home ForceCommand internal-sftp ``` 1. 最后,重启`sshd`守护进程。 ``` systemctl restart sshd ``` ## 它是如何工作的... 在这个过程中,你学会了如何通过从标准 FTP 协议切换到使用 SSL 上的 FTP 或 SSH 上的 FTP 来使你的文件共享更安全。无论你选择哪种选项,SSL 都用于在传输过程中加密数据,这有助于保护你的隐私。你选择哪种变体取决于你,但要记住,SFTP 设置起来稍微容易一些,因为你不需要在你的防火墙中配置额外的端口或证书,因为一切都在 SSH 上运行,这在大多数系统上应该是默认启用的。 那么,我们从这次经历中学到了什么? 我们首先通过配置 FTPS 开始这个过程。我们进入了一个特殊的目录,叫做`/etc/pki/tls/certs`,CentOS 在这里存储所有的证书。在其中,有一个 Makefile,我们用它来创建一个包含公钥/私钥对和自签名证书的`.pem`文件,这是我们 FTP 服务器配置所需的。之后,我们使用 chmod 确保只有 root 用户可以读取这个文件。然后,我们在主`vsftpd`配置文件中追加了六行代码(首先,我们备份了原始文件);它们相当直观:启用 SSL 协议,使用自签名证书,禁止任何非 SSL 通信,并使用一个固定的被动控制端口范围。此外,我们创建了一个新的防火墙服务,它将打开 FTPS 所需的被动控制端口。 之后,我们通过 chroot jail 配置了 SFTP。如果不使用 chroot jail 设置 SFTP,每个登录用户都可以查看根文件系统,这是非常不安全的。SFTP 的配置完全在主`sshd`配置文件中完成。在备份原始文件后,我们将 FTP 子系统更改为`internal-sftp`,这是一个更新的 FTP 服务器版本,性能更好,并在同一进程中运行。接下来,我们在`vsftpd`配置文件中添加了三行;只有`sshftp`组中的用户使用 SFTP,并被放入 chroot jail 中,只能查看其`home`目录及以下的文件。`ForceCommand`忽略用户的所有本地设置,并在此处强制执行这些规则。要添加新的 chroot SFTP 用户,你只需创建一个标准的 Linux 用户账户,并将他们添加到`sshftp`用户组。 ## 还有更多... 如果你想测试你的已启用 FTPS 服务器,你需要一个支持“FTP over TLS”的 FTP 客户端。你需要在你的 FTP 客户端设置中找到并启用这个选项。在 Linux 下,你可以安装`lftp`客户端来测试你是否可以连接到我们的 FTPS 服务器。首先,安装`lftp`包(例如,`yum install lftp`)。然后,使用 TLS 配置客户端:
echo “set ftp:ssl-auth TLS
set ftp:ssl-force true
set ftp:ssl-protect-list yes
set ftp:ssl-protect-data yes
set ftp:ssl-protect-fxp yes
set ssl:verify-certificate no” >~/.lftprc
现在,你可以使用以下命令连接并测试你的 FTPS 服务器:
lftp -u username
如果你想测试你的已启用 SFTP 服务器,你需要一个名为`sftp`的程序:
sftp john@ -p 22
### 注意 你必须记住,对`sshd_config`所做的所有更改也会反映在 SFTP 中。因此,如果你禁用了 root 登录或使 SSH 在不同于`22`的端口上运行,当你尝试登录 SFTP 时,必须考虑到这一点。