### 6.1.1 安全指南

[](<>)[](<>)

任何在连接到 Internet 的计算机上使用 MySQL 的人都应该阅读本节以避免最常见的安全错误。

在讨论安全性时，有必要考虑全面保护整个服务器主机（不仅仅是 MySQL 服务器）免受所有类型的适用攻击：窃听、更改、回放和拒绝服务。我们不在这里涵盖可用性和容错的所有方面。

MySQL 对用户可以尝试执行的所有连接、查询和其他操作使用基于访问控制列表 (ACL) 的安全性。还支持 MySQL 客户端和服务器之间的 SSL 加密连接。这里讨论的许多概念根本不是 MySQL 特有的。相同的一般思想适用于几乎所有应用程序。

运行 MySQL 时，请遵循以下准则：

-   **永远不要给任何人（除了 MySQL`根`帐户）访问`用户`表中的`mysql`系统数据库！**这很关键。

-   了解 MySQL 访问权限系统的工作原理（请参阅[第 6.2 节，“访问控制和帐户管理”](access-control.html)）。使用[`授予`](grant.html)和[`撤销`](revoke.html)用于控制对 MySQL 的访问的语句。不要授予超出必要的权限。永远不要向所有主机授予权限。

    清单：

    -   尝试`mysql -u 根目录`.如果您能够成功连接到服务器而无需输入密码，那么任何人都可以作为 MySQL 连接到您的 MySQL 服务器`根`拥有完全权限的用户！查看 MySQL 安装说明，特别注意有关设置`根`密码。看[第 2.10.4 节，“保护初始 MySQL 帐户”](default-privileges.html).

    -   使用[`显示赠款`](show-grants.html)检查哪些帐户可以访问什么的声明。然后使用[`撤销`](revoke.html)声明删除那些不必要的特权。

-   不要在数据库中存储明文密码。如果您的计算机受到威胁，入侵者可以获取完整的密码列表并使用它们。相反，使用[`SHA2()`](encryption-functions.html#function_sha2)或其他一些单向散列函数并存储散列值。

    为防止使用彩虹表恢复密码，请勿对纯密码使用这些功能；相反，选择一些字符串用作盐，并使用 hash(hash(password)+salt) 值。

-   假设所有密码都将使用已知密码列表进行自动破解尝试，并使用有关您的公开信息（例如社交媒体帖子）进行有针对性的猜测。不要选择由容易破解或猜测的项目组成的密码，例如字典单词、专有名称、运动队名称、首字母缩略词或众所周知的短语，尤其是当它们与您相关时。如果以可预测的方式使用大写字母、数字替换和添加以及特殊字符，这些都将无济于事。也不要选择任何您曾在任何地方用作示例的密码或其变体，即使它是作为强密码的示例。

    相反，请选择尽可能长且不可预测的密码。这并不意味着组合必须是难以记住和复制的随机字符串，尽管如果您拥有可以生成和填充此类密码并安全存储它们的密码管理器软件，这是一个很好的方法。包含多个单词的密码短语易于创建、记住和复制，并且比由单个修改的单词或可预测的字符序列组成的典型用户选择密码更安全。要创建安全密码短语，请确保其中的单词和其他项目不是已知的短语或引用，不会以可预测的顺序出现，并且最好彼此之间完全没有先前的关系。

-   投资防火墙。这可以保护您免受任何软件中至少 50% 的所有类型的攻击。将 MySQL 放在防火墙后面或非军事区 (DMZ)。

    清单：

    -   尝试使用以下工具从 Internet 扫描您的端口`地图`.MySQL 默认使用端口 3306。此端口不应从不受信任的主机访问。作为检查 MySQL 端口是否打开的一种简单方法，请在某个远程计算机上尝试以下命令，其中*`服务器主机`*是运行 MySQL 服务器的主机的主机名或 IP 地址：

        ```
        $> telnet server_host 3306
        ```

        如果**远程登录**挂起或连接被拒绝，端口被阻塞，这就是你想要的。如果你得到一个连接和一些乱码，端口是打开的，应该在你的防火墙或路由器上关闭，除非你真的有充分的理由让它保持打开。

-   访问 MySQL 的应用程序不应信任用户输入的任何数据，并且应使用适当的防御性编程技术编写。看[第 6.1.7 节，“客户端编程安全指南”](secure-client-programming.html).

-   不要通过 Internet 传输普通（未加密）数据。每个有时间和能力拦截并用于自己目的的人都可以访问此信息。相反，请使用加密协议，例如 SSL 或 SSH。MySQL 支持内部 SSL 连接。另一种技术是使用 SSH 端口转发来创建用于通信的加密（和压缩）隧道。

-   学习使用**tcpdump**和**字符串**公用事业。在大多数情况下，您可以通过发出如下命令来检查 MySQL 数据流是否未加密：

    ```
    $> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
    ```

    这在 Linux 下工作，并且应该在其他系统下进行小的修改。

    警告

    如果您看不到明文数据，这并不总是意味着信息实际上是加密的。如果您需要高安全性，请咨询安全专家。
