任何在互联网连接的计算机上使用 MySQL 的人都应该阅读本节,以避免最常见的安全错误。
讨论安全时,需要考虑完全保护整个服务器主机(不仅仅是 MySQL 服务器)免受所有类型的攻击:窃听、篡改、重放和拒绝服务。我们这里不讨论所有方面的可用性和容错性。
MySQL 使用基于访问控制列表(ACL)的安全机制来控制所有连接、查询和用户尝试执行的操作。还支持 MySQL 客户端和服务器之间的 SSL 加密连接。这里讨论的大多数概念并不特定于 MySQL;同样的通用想法适用于几乎所有应用程序。
在运行 MySQL 时,请遵循以下指南:
-
永远不要将任何人(除了 MySQL
root
帐户)授予对user
表的访问权限在mysql
系统数据库中! 这一点非常重要。 -
了解 MySQL 访问权限系统的工作原理(见 第 8.2 节,“访问控制和帐户管理”)。使用
GRANT
和REVOKE
语句来控制对 MySQL 的访问权限。不要授予不必要的权限。永远不要授予所有主机权限。检查清单:
-
尝试
mysql -u root
。如果您可以成功连接到服务器而不需要密码,那么任何人都可以以 MySQLroot
用户身份连接到您的 MySQL 服务器,拥有完全权限!查看 MySQL 安装说明,特别注意设置root
密码的信息。见 第 2.9.4 节,“保护初始 MySQL 帐户”。 -
使用
SHOW GRANTS
语句来检查哪些帐户拥有访问权限。然后使用REVOKE
语句来撤销不必要的权限。
-
-
不要在数据库中存储明文密码。如果您的计算机被入侵,入侵者可以获取完整的密码列表并使用它们。相反,使用
SHA2()
或其他单向哈希函数,并存储哈希值。为了防止使用彩虹表恢复密码,不要对明文密码使用这些函数,而是选择一些字符串作为 salt,然后使用 hash(hash(password)+salt) 值。
-
假设所有密码都将受到自动破解尝试,使用已知密码列表,并且使用公开可获取的关于您的信息,例如社交媒体帖子,来进行目标猜测。不要选择密码,例如字典单词、专有名词、体育团队名称、缩写或常见短语,特别是如果它们与您有关。使用大写字母、数字替换和特殊字符并不有帮助,如果它们以可预测的方式使用。也不要选择您曾经见过的示例密码,或者其变体,即使它们被作为强密码的示例。
相反,选择尽可能长和不可预测的密码。这并不意味着组合需要是一个难以记忆和重复的随机字符串,尽管这是一种良好的方法,如果您拥有密码管理软件,可以生成和存储这些密码。一个包含多个单词的密码短语易于创建、记忆和重复,并且比典型用户选择的单个修改过的单词或可预测的字符序列更加安全。
-
投资防火墙。这可以保护您免受至少 50% 的软件漏洞攻击。将 MySQL 放在防火墙后面或在非军事化区(DMZ)中。
检查清单:
-
尝试使用工具如
nmap
从互联网扫描您的端口。MySQL 默认使用端口 3306。这个端口不应该从不受信任的主机访问。作为检查 MySQL 端口是否打开的简单方法,尝试以下命令,从某个远程机器上,whereserver_host
是您的 MySQL 服务器运行的主机名或 IP 地址:$> telnet server_host 3306
如果 telnet 挂起或连接被拒绝,端口被阻止,这是你想要的。如果你获得连接并收到一些垃圾字符,端口是开放的,应该在防火墙或路由器上关闭它,除非你有充分的理由保持它开放。
-
-
访问 MySQL 的应用程序不应该信任用户输入的任何数据,并且应该使用适当的防御编程技术。参见 第 8.1.7 节,“客户端编程安全指南”。
-
不要通过互联网传输明文(未加密)数据。这些信息对任何有时间和能力截获它并将其用于自己的目的的人都是可访问的。相反,使用加密协议,如 SSL 或 SSH。MySQL 支持内部 SSL 连接。另一种技术是使用 SSH 端口转发来创建加密(和压缩)隧道以进行通信。
-
学习使用 tcpdump 和 strings 实用程序。在大多数情况下,你可以通过发出类似以下的命令来检查 MySQL 数据流是否未加密:
$> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
这在 Linux 下工作,并且应该在其他系统上以小修改工作。
Warning如果你没有看到明文数据,这并不总是意味着信息实际上是加密的。如果你需要高安全性,请与安全专家咨询。