为您的 WordPress 网站加固 MySQL

已发表: 2023-01-18

WordPress 是最流行的 CMS,运行在 MySQL 上,这是目前最流行的数据库。 花一些时间确保您的 MySQL 安装和 WordPress 数据库配置安装针对常见的攻击向量进行了充分强化,可以帮助您降低风险。 如果您自己管理 MySQL 服务器,则尤其如此。

值得注意的是,许多 WordPress 安装使用 MariaDB,它是 MySQL 的一个分支。 由于两者的工作方式非常相似,我们将使用 MySQL 来表示 MySQL 和 MariaDB。 无论您运行的是哪种 RDMS,强化 MySQL 都可以帮助您最大限度地降低黑客攻击的风险。 但是,这不会取代其他安全措施,例如安装 Web 应用程序防火墙,确保您拥有最新版本的插件、主题和 WordPress,以及加固 WordPress。

注意,本文针对的是运行在 Linux (Ubuntu) 上的 MySQL 8.0。 虽然这些概念将转化为其他操作系统和 MySQL/MariaDB 版本,但这些示例中使用的命令和文件路径可能有所不同。 在对生产系统进行任何更改之前,强烈建议在暂存或预生产环境中测试任何更改。

在这篇主要针对那些管理自己的 MYSQL 的文章中,我们提供了一些关于如何保护 MySQL 的技巧和教程。 即便如此,本文中提供的大量最佳实践对于任何管理 WordPress 网站的人来说都值得一读。 保护您的 MySQL 服务器是维护 WordPress 安全以及保护您自己免受不同类型的暴力攻击、恶意软件注入和其他类型攻击的关键步骤。

目录

  • 考虑使用数据库即服务 (DBaaS)
  • 使 MySQL 保持最新
  • 在专用机器上运行 MySQL
  • 将 MySQL 绑定到 IP 地址
  • 限制使用基于网络的 GUI 工具
  • 使用专用用户运行 MySQL 守护进程
  • 使用 mysql_secure_installation 脚本
  • 创建专用的 WordPress 数据库用户
  • 确保禁用 local_infile
  • 禁用 MySQL 命令历史记录
  • 确保 mysqld 未使用 –skip-grant-tables 参数启动
  • 备份你的数据库
    • 经常备份
    • 经常验证备份的完整性
    • 安全地存储您的备份
  • 启用和执行 TLS 连接
    • 更改表前缀
    • 如何实施改变
    • 确保您的 WordPress 安全

考虑使用数据库即服务 (DBaaS)

如果您没有在托管计划中托管 WordPress,那么数据库即服务非常值得考虑。 它用您连接的服务取代了在本地安装 MySQL 的传统模式。 如果您使用提供托管数据库服务的托管服务提供商来运行 WordPress 网站,这可能适合您的用例。 可用选项通常包括 Amazon RDS、DigitalOcean Managed MySQL 和 Linode Managed MySQL)。 从表面上看,这些服务比自己运行 MySQL 的成本更高。 但是,他们承担了运行生产级数据库的所有繁重工作。 大多数服务包括安全最佳实践预设、持续的安全补丁和维护以及备份。

就安全性和可靠性而言,使用数据库即服务 (DBaaS) 是最佳选择之一。 虽然这不是强制性的,但它仍然是一个很好的选择。 但是,如果您希望自己管理 MySQL,请牢记以下一系列强化技巧。

使 MySQL 保持最新

正如确保您运行最新版本的 WordPress 很重要一样,让 MySQL 保持最新也很重要。 与大多数其他软件一样,MySQL 服务器的更新会定期发布。 这些更新解决了错误、缓解了漏洞并提供了新功能。 您应该使用最新的安全补丁使 MySQL 保持最新状态,以降低运行具有已知漏洞的软件的风险。 请记住,一旦更新,您将需要重新启动“mysql 守护进程”。 这是一个可能会导致停机的过程。 一如既往,提前计划。

在专用机器上运行 MySQL

许多 WordPress 安装在同一台机器上运行 MySQL、PHP 和 Web 服务器(例如 Nginx 或 Apache HTTP 服务器)。 这不是最佳的——无论是在性能还是安全方面。 理想情况下,MySQL 应该在专用服务器上运行,以减少攻击的爆炸半径。 如果攻击者设法破坏并提升 Web 服务器上的权限,那么攻击者将更难横向移动并破坏 MySQL 服务器。

将 MySQL 绑定到 IP 地址

您可以将 MySQL 配置为仅接受来自特定 IPv4 或 IPv6 接口的 TCP/IP 连接。 您需要做的就是将绑定地址配置选项设置为特定的 IP 地址。 这对客户端应用程序(在我们的例子中是 WordPress)如何连接到 MySQL 提供了额外的控制和限制。 默认情况下,此设置设置为 *,这意味着开箱即用的 MySQL 将侦听所有接口。

如果没有配置监听特定IP,所有IP都可以用来连接MySQL。 如果你在同一台机器上运行 MySQL 作为你暴露给 Internet 的 Web 服务器(在这种情况下,你应该将 bind-address 设置为 127.0.0.1 以便 MySQL 仅在本地主机上侦听),则此设置尤为重要。 .

例如,如果您希望 MySQL 服务器仅接受特定 IPv4 地址上的连接,您可以添加类似于以下示例的条目。 您应该在服务器的 /etc/mysql/mysql.conf.d/mysqld.cnf 配置文件中的 [mysqld] 选项组下输入它。

绑定地址=192.168.0.24

请注意,一旦您设置了此项,您将需要重新配置 WordPress 以使用此 IP 地址连接到数据库(除非它已经这样做),因为不允许连接到其他服务器主机地址。

限制使用基于网络的 GUI 工具

许多 WordPress 安装包括基于 Web 的前端图形管理工具。 常见示例包括 Cpanel、phpMyAdmin 或 Adminer。 这些工具使管理 MySQL 和底层基础设施的其他方面变得更加容易。 虽然基于 Web 的图形界面可以帮助您管理 MySQL 数据库,但这些界面可以通过添加另一个向量来增加攻击面。 此外,存在被攻击者发现和滥用以对您的数据库运行破坏性或恶意 SQL 查询的风险。 攻击甚至可能导致完全接管您的 WordPress 网站。

唯一安全的服务器是关闭和拔掉插头的服务器——但是,风险是可以控制的。 卸载非关键系统是一种选择; 但是,这些也可以被锁定和限制以将风险降至最低。

可以通过多种方式限制对这些工具的访问。 您可以为 WordPress 远程安装 phpMyAdmin,从而最大限度地降低 Web 服务器的风险。 或者,您可能还想考虑在本地计算机上使用 MySQL Workbench 或 Beekeeper Studio 等工具,并通过 SSH 隧道连接到数据库服务器。

使用专用用户运行 MySQL 守护进程

与在服务器上运行的其他服务一样,您可以在专用用户下运行 MySQL 守护进程。 当您使用专用用户运行 MySQL 时,您可以精确地定义该用户在系统中被授予的权限。 在专用用户下运行 MySQL 也遵循最小权限原则,因为这减少了 MySQL 漏洞的爆炸半径。 它还减少了错误配置被利用的可能性,因为受限用户将无法访问与 MySQL 无关的资源(例如操​​作系统配置和机密)。

好消息是,通过包管理器(例如 apt 或 yum)进行安装会在安装 MySQL 时自动完成此步骤。 验证 MySQL 是否在专用用户下运行的快速方法是在运行 MySQL 守护程序的机器上运行以下命令。

ps-ef | egrep “^mysql.*$”

如果 MySQL使用专用用户运行,您应该期望看到至少返回 ps 输出的一行。

使用 mysql_secure_installation 脚本

mysql-server 包附带一个名为 mysql_secure_installation 的 shell 脚本实用程序。 您可以使用此脚本为 MySQL 服务器设置安全起点。 因此,您应该在全新安装 MySQL 后运行它。 此实用程序可帮助您:

  • 为根帐户设置密码
  • 删除可从本地主机外部访问的根帐户
  • 删除匿名用户帐户
  • 删除测试数据库(默认情况下,匿名用户可以访问)

要调用 mysql_secure_installation,请运行以下命令:

须藤 mysql_secure_installation

设置过程开始后,您将看到几个提示,询问您是否要启用验证密码插件,该插件用于测试您为 MySQL 用户选择的密码强度。 建议您启用此插件。

启用验证密码插件后,脚本会要求您指定密码验证策略。 在这里,您应该选择强密码策略。 随后将要求您重置 root 用户的密码。

接下来,该脚本将提示您删除匿名 MySQL 用户。 这对于减少攻击者通过利用匿名 MySQL 用户访问数据库服务器的机会很重要。

下一个提示将询问您是否要在对 MySQL 服务器进行远程身份验证时禁用使用 root 用户登录。 使用 root 用户进行远程身份验证很危险,而且很少需要。 相反,您应该通过 SSH 连接到 MySQL 并使用服务器上的 MySQL 客户端以 root 用户身份进行身份验证,或者最好使用 SSH 隧道将远程 MySQL 端口转发到本地计算机并使用本地客户端进行连接。

接下来,系统会要求您删除 MySQL 附带的默认数据库(如果存在)。 这是生产 MySQL 服务器的推荐做法。

删除默认数据库

最后,系统会询问您是否要为所有已应用生效的更改重新加载权限表。

创建专用的 WordPress 数据库用户

安全最佳实践规定按职责或角色分离用户和权限。 这意味着每个使用数据库的应用程序都应该有自己的专用用户,这些用户具有执行其工作所需的最少 MySQL 数据库权限。 因此,您将确保用户权限不会超过所需权限。

这种做法应该扩展到运行多个 WordPress 网站的部署——每个 WordPress 网站都应该有自己的专用数据库和 MySQL 用户。 这样可以确保在任何时候,一次只有一个用户可以访问一个数据库,用户不能访问其他数据库,从而避免未经授权的访问和数据泄露。

以下 SQL 语句(替换 <host> 和 <password> 和 <database> 以满足您的需要)可用于为您的 WordPress 网站创建专用用户并授予常规使用权限。 请记住,某些 WordPress 插件、主题和 WordPress 更新有时可能需要额外的权限才能正常运行(有关更多信息,请参阅官方 WordPress 指南)

确保禁用 local_infile

LOAD DATA 语句允许您将数据文件加载到数据库表中。 在特定情况下,这可能会被滥用以从 MySQL 服务器读取文件。 因此,除非您在 WordPress 站点中有特定的用例,否则您应该禁用此功能。

如果 MySQL 和 Web 服务器在同一台机器上运行,则可能允许攻击者使用 LOAD DATA LOCAL 语句读取 Web 服务器进程具有读取权限的任意文件。 这假设攻击者有能力对 MySQL 运行任意 SQL 语句。 SQL 注入漏洞或通过安装恶意 WordPress 插件可能就是这种情况。 这是将 Web 服务器和数据库服务器分开的另一个原因。

默认情况下,local_infile 在 MySQL 8.0 中是禁用的(它在早期版本的 MySQL 中默认是启用的)。 要防止 MySQL 服务器接受 LOAD DATA LOCAL 语句,请确保 mysqld 守护程序在启动时禁用 local_infile。

禁用 MySQL 命令历史记录

在 Linux 上,交互式执行的 MySQL 客户端日志语句被保存到一个历史文件中(通常位于 $HOME/.mysql_history 中)。 最好禁用 MySQL 命令历史记录,因为这会降低泄露敏感信息(如密码、加密密钥或其他秘密)的可能性。

要验证系统中不存在 .mysql_history 文件,请运行以下命令:

找到 /home -name “.mysql_history”
找到 /root -name “.mysql_history”

如果上述命令返回任何输出,请删除任何 .mysql_history 文件。 此外,您可以将 $HOME/.mysql_history 设置为 /dev/null 的符号链接,如下所示:

ln -s /dev/null $HOME/.mysql_history

确保 mysqld 未使用 –skip-grant-tables 参数启动

如果 MySQL 的 root 密码放错了地方,虽然这不是首选方法,但一些 MySQL 管理员可能会求助于将 MySQL 设置为使用 –skip-grant-tables 参数启动。 使用此参数启动 MySQL 时,它将避免在客户端连接或运行查询时检查其授权表,从而有效地允许任何人在任何地方(只要他们可以通过网络访问数据库)在数据库服务器上执行任何操作。

为确保未启用 –skip-grant-tables,请打开服务器的 /etc/mysql/mysql.conf.d/mysqld.cnf 配置文件并查找 skip-grant-tables。 该值不应设置,或设置为 skip-grant-tables = FALSE。

备份你的数据库

备份您的 WordPress 数据库对于能够从灾难或攻击中迅速恢复绝对至关重要。 虽然有无数种方法可以备份您的 WordPress 数据库——从 WordPress 备份插件和服务到定期进行数据库转储的自制脚本——但以下是一些需要牢记的重要提示。

经常备份

进行定期备份非常明显且不言自明——您进行数据库备份的频率越高,从数据丢失事件中恢复就越容易。 虽然备份的频率取决于您运行的 WordPress 站点的类型,但根据经验,每天进行备份可以很好地满足大多数用例。

经常验证备份的完整性

您的备份只有在有效时才有用。 当您正处于试图恢复数据的事件中时,您可能不想知道。 对此的简单补救措施是通过每隔一段时间进行测试恢复来经常验证您的备份是否确实有效。 执行此操作的一个好方法是每隔几个月设置一个日历事件来执行还原过程,以确保您的备份仍按预期工作。 此外,记录数据库恢复步骤也是一个好主意——在响应事件时猜测越少越好。

安全地存储您的备份

永远不要在您的网络或数据库服务器上(尤其是在您的网络服务器上)保留您的 WordPress 站点的备份。 备份是攻击者进行垃圾箱潜水的好地方。 强烈建议将备份存储在安全的异地位置。 如果要定期进行数据库转储,请考虑将数据库转储存储在对象存储服务上。 这些可能包括 Amazon S3、Cloudflare R2、DigitalOcean Spaces、Linode Object Storage 等。采用这种方式可能是存储数据库备份的一种经济高效的好方法。 但是,请格外小心,不要让您正在使用的存储桶可公开访问。

启用和执行 TLS 连接

除非您在与 Web 服务器相同的机器上运行 MySQL(正如我们上面已经提到的,这不是理想的安全实践),否则强烈建议使用传输层安全性(TLS 证书)加密 WordPress 和 MySQL 之间的数据,以前称为安全套接字层(SSL 证书)。

默认情况下,当您安装 MySQL 时,它会自动为您生成一个自签名证书。 您可以通过运行以下命令来验证这一点(或者,您可以使用 mysql_ssl_rsa_setup 脚本生成新证书)。

您需要将 ca.pem 从上面的列表(例如,通过 SCP)复制到运行您的 WordPress 网站的服务器。 将 ca.pem 文件上传到 WordPress 服务器后,您需要将证书移至操作系统的证书信任库并按如下方式更新证书信任库。

注意,CA 证书的文件名必须以 .crt 文件扩展名结尾(例如 mysql-ca.crt 有效,但 mysql-ca.pem.crt 或 mysql-ca.pem 无效)。

sudo mv ca.pem /usr/local/share/ca-certificates/mysql-ca.crt
sudo 更新-ca-证书

接下来,您需要将 WordPress 配置为在连接到 MySQL 时使用 TLS,方法是将以下内容添加到 WordPress 安装的 wp-config.php 文件中。

定义('MYSQL_CLIENT_FLAGS',MYSQLI_CLIENT_SSL);

更新 wp-config.php 后,WordPress 将使用 TLS 启动与 MySQL 服务器的连接。

接下来,建议您通过将以下内容添加到 /etc/mysql/mysql.conf.d/mysqld.cnf 文件来使用 require_secure_transport 系统变量强制与 MySQL 服务器建立 TLS 连接。

require_secure_transport = 开

最后,重新启动 MySQL 以使更改生效。

systemctl 重启mysql

更改表前缀

默认情况下,所有 WordPress 表都是使用“wp_”前缀创建的。 这可以使攻击者更容易在某些攻击中获得成功,例如 SQL 注入,因为他们知道数据库表的名称。 虽然仅此一项并不能保护您,但这是一个简单的练习,被许多人推荐为最佳 WordPress 安全实践。

您可以在安装过程中或之后的任何时候更改数据库前缀,尽管后者稍微复杂一些。 无论哪种方式,您都可以找到有关更改 WordPress 数据库前缀的在线教程。

如何实施改变

希望本文为您提供了在运行 WordPress 网站的上下文中 MySQL 安全强化的概述。 虽然在网站安全方面没有灵丹妙药,但通过一些努力,采用分层、纵深防御的安全方法将使攻击者更难攻击您的网站。
虽然本指南介绍了许多 MySQL 强化技术,但 MySQL 只是 WordPress 生态系统的一个组成部分。 因此,您还应该考虑我们的 WordPress 安全强化指南中涵盖的 WordPress 安全的其他方面。 这与经过验证的安全措施(例如 WordPress 双因素身份验证)相结合,将帮助您确保尽可能安全。

如果感觉要接受很多东西,请记住您可以(并且可能应该)逐渐应用本指南中涵盖的各种强化技术。

确保您的 WordPress 安全

请记住,攻击者通常是在寻找软目标,因为他们不需要花费太多精力来利用安全性较弱的网站。 比下一个 WordPress 网站的安全态势领先一步会让您成为一个不太有吸引力的目标。