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