社区新闻

网站安全检查——面向网站所有者和管理员的 WP-CLI 指南

查看官方原文 ↗ 发布于

如果您是网站所有者或管理员,您的众多职责之一就是确保网站的安全与防护。为了实现这一目标,您需要利用所有可用的工具来提高效率并确保操作正确。WordPress 的命令行界面 WP-CLI 就是这样的工具之一。如果您认为这对您来说太高级了,永远无法理解,请做好准备,因为这篇文章就是为您准备的。希望您在阅读完本文后,能有足够的信心尝试一些命令。

无需安装

WP-CLI 工具通过终端安装,这可能令人望而生畏,尤其是因为它因操作系统和服务器而异。我们将看看即用型选项。许多托管服务商都开箱即用地提供 WP-CLI。此外,其中许多服务商还有自己的自定义命令,以帮助您执行特定于其服务器的任务。所有这些服务商都有关于如何在其平台上找到和使用 WP-CLI 的说明。在他们的知识库、文档、博客、常见问题解答等中搜索 WP-CLI。

值得注意的是,当您的托管服务提供 WP-CLI 时,这意味着您拥有对您网站的SSH 访问权限。除了知道这是一种非常安全的连接之外,您无需了解其他任何信息。随着时间的推移,当您对终端更加熟悉后,您可能会想学习如何做更多不仅仅是 WP-CLI 的事情。但如果您永远不这样做,也完全没问题。这就是 CLI 工具的魅力所在——您可以根据需要以基本或高级的级别使用它,而不会破坏任何东西。

议程

既然安装 WP-CLI 的繁重部分已经完成,让我们看看我们将要涵盖的内容。确保网站安全的第一步是保持 WordPress 核心、插件和主题处于最新状态。您还需要确保这些更新不会破坏您的网站。

另一个消除压力的重要方法是防止黑客攻击。有时这无法做到,但您在这方面可以做很多事情,例如监控文件更改。此外,有了 WP-CLI,您就拥有了一个强大的用户管理工具。

额外的备份可以成为让您安睡的另一个保障。

看起来我们的议程已经确定了。

命令剖析

在我们开始运行命令之前,这里有一些快速的基础知识,可以让您更容易记住命令。WP-CLI 命令几乎总是具有以下结构:

wp <noun> <verb> --flag-1 --flag-2

名词和动词很少交换顺序,但我们暂时不会看那些命令。名词是代表您要操作的实体的命令,例如 corepluginthemepostuser 等。动词是更深层次的子命令,描述您打算对此实体执行的操作。您会在许多实体中找到相同的动词,例如 listcreatedeleteaddremove 等。标志是额外的参数,使您的请求更具体。

获取帮助

在命令结构(主命令、名词或动词)的任何级别,您都可以使用一个名为 --help 的全局参数,它将显示您可以为当前命令或子命令使用的所有子命令和标志。

例如,如果您想查看可以与 plugin 命令一起使用的子命令(动词),可以输入:

wp plugin --help

如果您想知道可以与 plugin update 子命令一起使用的所有标志,您需要输入:

wp plugin update --help

要退出帮助屏幕,只需输入 q 并按 Enter

您是否在 WordPress 根目录下?

您在本文中看到的所有命令,都应在 WordPress 根文件夹内运行。WordPress 根文件夹可以通过存在以下目录来识别:/wp-admin、/wp-includes 和 /wp-content。

当您登录到托管终端时,很可能您不在 WordPress 根目录下。这因服务商而异,但最常见的情况是您至少高出一级。
要查看您所在的目录,请使用 ls 命令

列出托管服务商根目录内容的终端输出。

在某些情况下,您会看到 public_html,在其他情况下是 www,甚至可能是与您在服务器上的用户名同名的目录。您的 WordPress 根目录就在其中之一。要查看这些目录中的内容,而无需进入其中,请使用相同的命令,后跟目录名称:

ls public_html/
WordPress 根文件和文件夹 - 列出 public_html 目录内容的命令输出。

现在我们已经定位到 WordPress 根目录,让我们进入那里。使用 cd 命令

cd public_html/

您可以再次运行 ls 命令,只是为了确认您确实在 WordPress 根目录下。这就是我们将在本文剩余部分停留的地方。请随意。

安全更新

为确保您的 WordPress 核心安全,您希望使用安全更新使其保持最新。这些更新也称为“次要”更新。

有两种类型的 WordPress 核心软件更新可用于您的网站:

  • 包含新 WordPress 功能的主要核心更新。您可以通过版本号遵循以下模式来判断更新是否为“主要”版本:4.0、4.1、4.2、4.3、4.4 等。
  • 次要核心更新通常包括维护版本、安全修复和翻译文件更新。您可以通过标识它的数字附加到当前主要版本的编号上来判断更新是否为“次要”版本。例如:4.4.1、4.4.2、4.4.3 等。
– 来源:Learn.WordPress.org, 管理更新

对于更新到主要版本,您需要咨询您的开发人员。这必须在本地环境中进行测试,以确保所有功能在新特性下都能按预期工作。

然而,次要更新您可以自己执行。首先,检查您当前的版本:

wp core version

这将为您提供当前为您的网站安装的主要和次要版本号,例如 6.5.4

然后我们想检查是否有任何可用的更新:

wp core check-update --minor
可用更新表 - 检查是否有次要版本更新的 WP-CLI 命令输出。

省略 --minor 标志将告诉 WP-CLI 查找主要版本。如果您的 WordPress 站点在次要版本上是最新的,您将看到以下消息:

Success: WordPress is at the latest minor release.

但是,如果您看到一个包含 versionupdate_typepackage_url 的表格,则表示有可用更新,您应该尽快更新您的网站:

将 WordPress 更新到最新次要版本的 WP-CLI 命令的终端输出。

次要版本更新不应破坏您网站上的任何内容——这些只是错误修复。尽管如此,您应该检查您的网站以确保一切按预期工作。如果有东西损坏了,您应该做两件事:

  1. 使用以下命令回滚更新:wp core update --version=6.5.4 --force(这就是为什么您首先要检查版本)。每次更新到不是最新版本的版本时,都必须使用 --force 标志,无论它是次要版本还是主要版本。
  2. 与您的开发人员检查是否可以替换导致损坏的插件或主题。如果它们不适用于次要版本,那么其中的代码很可能没有遵循最佳实践。

就是这样。您运行了您的第一个 WP-CLI 命令并做了一些有用的事情。最重要的是,您的网站仍然正常运行。恭喜!

类似的原则可以应用于更新主题插件。两者都有一个 --dry-run 标志,允许您仅检查哪些插件和主题有可用更新,而无需实际更新它们:

wp plugin update --all --dry-run
有可用更新的插件表 - 检查插件可用更新的 WP-CLI 命令输出。

要检查次要版本,--minor 标志也可用:

wp theme update --all --minor --dry-run

如果没有可用更新,您会看到 No theme/plugin updates available 消息。如果有,您会看到一个表格,列出所有有可用更新的插件或主题、它们的当前版本和可用版本,以及状态(激活或未激活)。

有可用次要更新的主题表 - 检查主题可用次要更新的 WP-CLI 命令输出。

要仅更新某些插件或主题,您可以使用上表中的名称来指定它们:

wp plugin update akismet --minor
将 Akismet 插件更新到最新次要版本的 WP-CLI 命令输出。

如果您出于某种原因不想在生产环境中运行这些更新,您可以始终先在暂存网站上测试它们。所有严肃的托管服务商都会为您提供网站的暂存版本用于此类测试。

监控文件更改

通常,当您的网站被黑客入侵时,文件中会有某种更改。它可能以文件系统中任何地方的新文件形式出现,也可能是现有文件的更改。您可以使用 WP-CLI 来监控这些更改。

检查文件的更改是通过 verify-checksums 子命令完成的:

wp core verify-checksums

这将根据已知的 WordPress 版本检查您的 WordPress 核心文件。如果您想检查特定版本,可以指定它:

wp core verify-checksums --version=6.5.2
验证核心文件的 WP-CLI 命令及其输出。

如果检查失败,您将看到此消息:

Error: WordPress installation doesn't verify against checksums.

在此消息之前,您还会看到未通过校验和验证的文件列表。

这可能意味着您的 WordPress 安装已损坏,但也可能是您输错了版本。为了确保您输入了正确的版本,您可以使用:

wp core verify-checksums --version=$(wp core version)

如您所见,在命令替换 $() 内部,我们正在执行命令以获取版本号。因此,您甚至不需要知道您拥有哪个版本,因为不同的 CLI 工具可以完美地协同工作,您可以通过嵌套命令来提供值。只需将它们包装在 $() 中即可。

如果一切正常,您将看到以下消息:

Success: WordPress installation verifies against checksums.

即使恶意更改仍然发生,也有可能收到此成功消息。例如,即使没有修改核心文件,您的安装中也可能出现新文件。如果这个新文件添加在 /wp-includes/wp-admin 文件夹中,您将看到关于不应存在于该处的文件的警告:

Warning: File should not exist: wp-includes/install-wp.php
包含关于存在未知文件的警告消息的输出,同时核心文件通过验证。

要将 WordPress 的根文件夹包含在此检查中,请添加 --include-root 标志。

wp core verify-checksums --include-root --version=$(wp core version)

现在只剩下 wp-content 作为唯一未检查的目录。在此目录中,您应该只有 index.php 文件以及以您在 WordPress 仪表板中看到的插件命名的文件夹(或单个 PHP 文件)。要检查所有插件,您可以运行相同的 verify-checksums 子命令。如果您还想检查微小的更改(例如在 readme.txt 文件中),请添加 --strict 标志。

wp plugin verify-checksums --all --strict

对于任何未托管在 WordPress.org 的插件,您将收到以下警告:

Warning: Couldn't fetch response from https://downloads.wordpress.org/plugin-checksums/<plugin>/<version>.json (HTTP code 404).
Warning: Could not retrieve the checksums for version <version> of plugin <plugin>, skipping.
包含警告消息的输出,表明 WP-CLI 无法对一个插件执行验证,而两个插件已成功验证。

同样,这并不一定意味着您的 WordPress 安装中存在恶意代码。这只意味着此插件未托管在 WordPress.org。它可能是您的开发人员专门为您的网站创建的自定义插件,也可能是您在某个市场购买的插件的付费版本。

如果您不确定如何处理看到的所有这些警告,您应该将终端中的输出复制并粘贴到另一个文档中,然后发送给您的开发人员进行进一步调查。这将大大减少调试时间,或者证明是虚惊一场。这两者都比它们的替代方案更可取。

用户管理

有时,当黑客入侵网站时,他们会更改用户的访问权限。他们可以完全删除一个或多个用户(主要是管理员),或者只是限制访问。在这种情况下,很可能是他们通过入侵密码或通过在您的 WordPress 安装中执行文件来创建新用户,从而通过 WordPress 仪表板入侵的。

但您拥有 SSH 访问权限。这使您成为服务器上最强大的人。因此,首先您要检查具有管理员访问权限的所有用户

wp user list --role=administrator
列出所有具有管理员角色的用户的 WP-CLI 命令输出的表格。

您将获得一个包含用户 ID、用户名、显示名称、电子邮件、角色和注册日期的表格。如果用户名和电子邮件没有引起任何警觉,最近注册的用户应该引起怀疑。

请记住,即使您的用户已不存在,您也可以看到此列表并执行所有操作。您不需要访问 WordPress 仪表板即可通过 WP-CLI 进行任何更改。

从这一点出发,您可以使用以下命令静默撤销可疑用户的访问权限(您需要他们的用户名、电子邮件地址或用户 ID):

wp user remove-role <strong><user_name|user_email|ID></strong>
从用户移除角色的 WP-CLI 命令输出。

当用户没有角色时,WordPress 不知道如何处理他们,因此他们没有任何访问权限。即使是订阅者也可以访问仪表板中的个人资料,而没有角色的用户则没有任何访问权限。

如果您不确定哪个用户是恶意的,您可以通过组合其他 CLI 工具来移除所有管理员的角色:

for i in $(wp user list --role=administrator --field=ID); do wp user remove-role $i; done

您可能在这里认出了命令替换——$()。我们用它来获取每个管理员的用户 ID。您可以使用 user_nameuser_email 代替 ID。由于可能不止一个,我们需要执行上述命令来移除每个用户的角色。这就是为什么我们通过一个 for 循环运行我们的 ID,其中 i 代表用户的值。现在我们要为每个用户运行 wp user remove-role,其中单个值用 $i 表示。当我们遍历完所有用户后,我们就 done 了。

运行后,您将看到一条消息,通知您成功或可能的失败:

Success: Removed <strong><user_login></strong> (<strong><ID></strong>) from <strong><URL></strong>.
移除所有管理员用户角色的输出。

现在,如果需要,您可以创建自己的新用户</