MySQL 8.0 安全部署指南  /  第 5 章安装后设置

第 5 章安装后设置

安装后设置包括为导入和导出操作创建安全目录、配置服务器启动选项、初始化数据目录、使用 systemd 启动 MySQL、重置 MySQL root@localhost用户帐户的密码以及运行一些测试以确保服务器正常运行在职的。

为导入和导出操作创建安全目录

FILE 拥有该权限 的MySQL用户,可以使用LOAD DATA INFILEand SELECT ... INTO OUTFILE语句, LOAD_FILE()函数对服务器主机上的文件进行读写操作。默认情况下,具有FILE权限的用户可以读取服务器主机上任何全局可读或 MySQL 服务器可读的文件。(这意味着用户可以读取任何数据库目录中的任何文件,因为服务器可以访问这些文件中的任何一个。)该 FILE权限还使用户能够在 MySQL 服务器具有写入权限的任何目录中创建新文件。这包括服务器数据目录,其中包含实现权限表的文件。

要限制FILE 权限范围,请创建一个目录,拥有 FILE权限的用户可以安全地使用该目录进行导入和导出操作。在此部署中,创建的目录已命名mysql-files并位于数据目录下。在后面的步骤中,当配置服务器启动选项时,该 secure_file_priv选项将设置为mysql-files目录。

$> cd /usr/local/mysql  
$> mkdir mysql-files
$> chown mysql:mysql mysql-files
$> chmod 750 mysql-files

配置服务器启动选项

通过将它们放在 MySQL 配置文件中来指定 MySQL 服务器在启动时应使用的选项。如果不这样做,服务器将以其默认设置启动(请参阅 服务器配置默认值)。

笔记

某些InnoDB选项只能在初始化数据目录之前配置。这些选项包括 innodb_data_home_dirinnodb_data_file_pathinnodb_log_file_sizeinnodb_log_group_home_dirinnodb_page_size。如果您不想为这些选项使用默认值,请在初始化数据目录之前在 MySQL 配置文件中设置您自己的值。此部署使用默认 InnoDB配置设置。有关详细信息,请参阅 InnoDB 启动配置

  1. 要创建 MySQL 配置文件,请以 root 身份发出以下命令:

    $> cd /etc
    $> touch my.cnf
    $> chown root:root my.cnf  
    $> chmod 644 my.cnf
    笔记

    my.cnf 如果同一位置存在属于另一个 MySQL 实例 的现有配置文件,请为您的配置文件使用不同的名称。

  2. [mysqld]组条目下, 为实例设置datadir, socket, port, 选项。log-error如果主机上安装了其他 MySQL,请确保这些选项的值对于此实例是唯一的。此部署使用默认值。

    [mysqld]
    datadir=/usr/local/mysql/data
    socket=/tmp/mysql.sock
    port=3306
    log-error=/usr/local/mysql/data/localhost.localdomain.err
    重要的

    MySQL 数据目录的位置对于 MySQL 安装的安全性至关重要。数据目录除了用户数据外,还包含数据字典和系统表,里面存放着数据库对象、用户、权限等敏感信息。遵循最小特权原则,系统用户对数据目录的访问应尽可能受到限制。还应考虑数据目录所在的文件系统的大小。确保文件系统可以容纳预期的数据大小。本指南中描述的部署将数据目录放置在默认位置(/usr/local/mysql/data),并且对目录的访问仅限于 mysql操作系统用户帐户。

  3. 设置user选项以确保服务器作为非特权 mysql用户帐户启动。出于安全原因,避免以操作系统root用户身份运行服务器很重要。

    user=mysql
  4. 如果您打算允许导入和导出操作,请将secure_file_priv系统变量设置为mysql-files 您之前创建的目录的路径。此选项将文件导入和导出操作(例如由LOAD DATAand SELECT ... INTO OUTFILE语句和 LOAD_FILE()函数执行的操作)限制到指定目录。如果您不打算允许导入或导出操作,请设置 secure_file_privNULL,这将完全禁用导入和导出操作。NULL是默认设置。

    secure_file_priv=/usr/local/mysql/mysql-files
  5. LOCAL为避免 的版本存在 潜在的安全问题 LOAD DATA,请确保 local_infile已禁用,默认情况下是禁用的。

    local_infile=OFF

    有关详细信息,请参阅 LOAD DATA LOCAL 的安全注意事项

完成上述步骤后,假设您没有添加其他设置,配置文件应该包含这些设置:

[mysqld]
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/localhost.localdomain.err
user=mysql
secure_file_priv=/usr/local/mysql/mysql-files
local_infile=OFF

初始化数据目录

安装MySQL后,必须初始化数据目录,其中包括mysql系统数据库及其表,包括授权表、服务器端帮助表和时区表。初始化还创建 root@localhost超级用户帐户和 InnoDB管理表所需的系统表空间和相关数据结构InnoDB

初始化数据目录:

  1. 将位置更改为 MySQL 安装的顶级目录,创建数据目录,并将所有权授予mysql用户。

    $> cd /usr/local/mysql
    $> mkdir data
    $> chmod 750 data
    $> chown mysql:mysql data
    笔记

    数据目录所有权分配给 mysql用户,但大多数 MySQL 安装仍由root. 其他例外是​​错误日志文件、 mysql-files目录、pid 文件和套接字文件,mysql 用户必须对这些文件具有写入权限。mysql用户需要读取访问权限 的文件和资源 包括配置文件(例如/etc/my.cnf)和 MySQL 二进制文件(/usr/local/mysql/bin)。

  2. 初始化数据目录。

    $> cd /usr/local/mysql
    $> bin/mysqld --defaults-file=/etc/my.cnf --initialize

    初始化输出被打印到错误日志 ( /usr/local/mysql/data/localhost.localdomain.err) 中,并且看起来类似于下面所示的输出。输出包括 root@localhost帐户的初始随机密码。稍后需要密码才能重置 root@localhost密码。

    2018-05-02T17:47:49.806563Z 0 [System] [MY-013169] [Server] 
    /usr/local/mysql-commercial-8.0.11-linux-glibc2.12-x86_64/bin/mysqld (mysqld 8.0.11-commercial) 
    initializing of server in progress as process 16039
    2018-05-02T17:47:54.083010Z 5 [Note] [MY-010454] [Server] 
    A temporary password is generated for root@localhost: uZmx9ihSd2;.
    2018-05-02T17:47:56.225881Z 0 [System] [MY-013170] [Server] 
    /usr/local/mysql-commercial-8.0.11-linux-glibc2.12-x86_64/bin/mysqld (mysqld 8.0.11-commercial) 
    initializing of server has completed
笔记

数据目录初始化在数据库中创建时区表 mysql但不填充它们。为此,请参阅 MySQL 服务器时区支持中的说明。

有关数据目录初始化 的更多信息,请参阅初始化数据目录

使用 systemd 启动服务器

本节介绍如何使用 systemd 启动服务器以及如何在主机重新启动时启用 MySQL 服务器的自动重启。

systemd 使用systemctl命令 提供手动服务器管理 :

systemctl {start|stop|restart|status} mysqld

要配置 MySQL 安装以使用 systemd:

  1. 添加一个 systemd 服务单元配置文件,其中包含有关 MySQL 服务的详细信息。该文件被命名 mysqld.service并放置在 /usr/lib/systemd/system.

    $> cd /usr/lib/systemd/system
    $> touch mysqld.service
    $> chmod 644 mysqld.service

    将此配置信息添加到 mysqld.service文件中:

    [Unit]
    Description=MySQL Server
    Documentation=man:mysqld(8)
    Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
    After=network.target
    After=syslog.target
    
    [Install]
    WantedBy=multi-user.target
    
    [Service]
    User=mysql
    Group=mysql
    
    # Have mysqld write its state to the systemd notify socket
    Type=notify
    
    # Disable service start and stop timeout logic of systemd for mysqld service.
    TimeoutSec=0
    
    # Start main service
    ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf $MYSQLD_OPTS 
    
    # Use this to switch malloc implementation
    EnvironmentFile=-/etc/sysconfig/mysql
    
    # Sets open_files_limit
    LimitNOFILE = 10000
    
    Restart=on-failure
    
    RestartPreventExitStatus=1
    
    # Set environment variable MYSQLD_PARENT_PID. This is required for restart.
    Environment=MYSQLD_PARENT_PID=1
    
    PrivateTmp=false
  2. 使mysqld服务在重新启动时自动启动。

    $> systemctl enable mysqld.service
    Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld.service 
    to /usr/lib/systemd/system/mysqld.service.
  3. 为确保 systemd 配置正常工作,请 使用systemctlmysqld手动启动服务 。

    $> systemctl start mysqld
  4. 检查mysqld服务的状态。输出应类似于以下内容,这表明mysqld服务已成功启动。

    $> systemctl status mysqld
    ● mysqld.service - MySQL Server
       Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
       Active: active (running) since Wed 2018-05-02 18:18:05 ADT; 5s ago
         Docs: man:mysqld(8)
               http://dev.mysql.com/doc/refman/en/using-systemd.html
     Main PID: 19520 (mysqld)
       Status: "SERVER_OPERATING"
       CGroup: /system.slice/mysqld.service
               └─19520 /usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
    
    May 02 18:18:04 localhost.localdomain systemd[1]: Starting MySQL Server...
    May 02 18:18:05 localhost.localdomain systemd[1]: Started MySQL Server.
  5. 要验证系统重启时 systemd 是否自动启动 MySQL,请重新启动系统并mysqld再次检查服务的状态。

    $> systemctl status mysqld
笔记

systemd 有自己的日志文件,可以使用 journalctl访问。要查看与 mysqld 相关的日志消息,请使用journalctl -u mysqld. 某些消息(例如 MySQL 启动消息)可能会打印到 systemd 日志中。

有关 systemd 的更多信息,请参阅 使用 systemd 管理 MySQL 服务器

重置 MySQL root 帐户密码

此过程假定 MySQL 服务器正在运行。您可以通过发出以下命令来检查服务器状态:

$> systemctl status mysqld

root 初始化数据目录时,会为 MySQL帐户 生成一个随机初始密码( root@localhost) 并标记为已过期。执行以下步骤以设置新密码:

  1. 使用客户端,使用服务器在初始化序列期间生成的随机密码 mysql连接到服务器:root@localhost

    $> cd /usr/local/mysql 
    $> bin/mysql -u root -p
    Enter password: (enter the random root password here)
  2. 连接后,分配一个新 root@localhost密码。使用强密码。理想情况下,密码应符合您将使用该 validate_password组件定义的密码策略,该组件将在后面的步骤中启用。(请参阅 第 6 章,安装 MySQL 密码验证组件。)

    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';

    RANDOM PASSWORD或者,您可以使用该选项 生成一个随机密码 。有关详细信息,请参阅 随机密码生成

测试服务器

现在已经安装并初始化了 MySQL,并且 root重置了 MySQL 用户密码,执行几个简单的测试来验证服务器是否正常工作。

  1. 使用mysqlshow验证您是否可以从服务器检索信息。

    $> cd /usr/local/mysql 
    $> bin/mysqlshow -u root -p
    Enter password: (enter root password here)
    +--------------------+
    |     Databases      |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
  2. 使用mysqladmin查看MySQL服务器版本信息。

    $> cd /usr/local/mysql 
    $> bin/mysqladmin -u root -p version
    Enter password: (enter root password here)

    输出应与此处显示的类似:

    bin/mysqladmin  Ver 8.0.19-commercial for linux-glibc2.12 on x86_64 
    (MySQL Enterprise Server - Commercial)
    Copyright (c) 2000, 2020, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Server version		8.0.19-commercial
    Protocol version	10
    Connection		Localhost via UNIX socket
    UNIX socket		/tmp/mysql.sock
    Uptime:			11 min 7 sec
    
    Threads: 3  Questions: 8  Slow queries: 0  Opens: 146  Flush tables: 3  
    Open tables: 63  Queries per second avg: 0.011

有关其他测试,请参阅测试服务器