如何在 Linux VPS 中保护 MySQL 和 MariaDB 数据库
介绍
Linux 和类 Unix 系统上有许多可用的 SQL 数据库语言实现。MySQL 和 MariaDB 是在服务器环境中部署关系数据库的两种流行选择。
但是,与大多数软件一样,如果配置不正确,这些工具可能会成为安全隐患。本教程将指导您完成一些基本步骤,以保护您的 MariaDB 或 MySQL 数据库,并确保它们不会成为您 VPS 的敞开大门。
为了简单起见,我们将使用 Ubuntu 12.04 VPS 实例上的 MySQL 服务器。但是,这些技术可以应用于其他 Linux 发行版,也可以与 MariaDB 一起使用。
初始设置
MySQL 让您有机会在安装过程中迈出安全的第一步。它将要求您设置 root 密码。
sudo apt-get install mysql-server
?????????????????????????? Configuring mysql-server-5.5 ??????????????????????????? ? While not mandatory, it is highly recommended that you set a password for the ? ? MySQL administrative "root" user. ? ? ? ? If this field is left blank, the password will not be changed. ? ? ? ? New password for the MySQL "root" user: ? ? ? ? _______________________________________________________________________________ ? ? ? ?? ? ? ???????????????????????????????????????????????????????????????????????????????????
您可以随时在以后设置 root 密码,但没有理由跳过此步骤,因此您应该从一开始就保护您的管理员帐户。
安装完成后,我们应该运行一些附带的脚本。首先,我们将使用“mysql_install_db”脚本为我们的数据库创建目录布局。
sudo mysql_install_db
接下来,运行名为“mysql_secure_installation”的脚本。这将引导我们完成一些步骤,以删除在生产环境中使用起来很危险的一些默认设置。
sudo mysql_secure_installation
首先,它会提示您输入安装期间设置的 root 密码。紧接着,系统会询问您一系列问题,首先是您是否要更改 root 密码。
如果您还没有这样做,这是另一个将密码更改为安全密码的机会。
您应该对所有剩余问题回答“Y”(代表是)。
这将删除任何人默认登录 MySQL 的能力,禁用使用管理员帐户远程登录,删除一些不安全的测试数据库,并更新正在运行的 MySQL 实例以反映这些更改。
安全注意事项
确保 MySQL(以及几乎所有其他系统)安全的首要原则是,只有在绝对必要时才应授予访问权限。您的数据安全有时归结为便利性和安全性之间的平衡。
在本指南中,我们将倾向于安全性方面,尽管您对数据库软件的具体使用可能会导致您从这些选项中进行选择。
通过 My.cnf 文件实现安全性
MySQL 的主要配置文件是名为“my.cnf”的文件,该文件位于 Ubuntu 上的“/etc/mysql/”目录中和一些其他 VPS 上的“/etc/”目录中。
我们将更改此文件中的某些设置来锁定我们的 MySQL 实例。
使用 root 权限打开文件。如果您在其他系统上学习本教程,请根据需要更改目录路径:
sudo nano /etc/mysql/my.cnf
我们应该检查的第一个设置是“[mysqld]”部分中的“bind-address”设置。此设置应设置为本地环回网络设备,即“127.0.0.1”。
bind-address = 127.0.0.1
这确保了 MySQL 不会接受来自本地机器以外任何地方的连接。
如果您需要从另一台机器访问该数据库,请考虑通过 SSH 连接以在本地执行数据库查询和管理,并通过 ssh 隧道发送结果。
我们要修补的下一个漏洞是允许从 MySQL 内部访问底层文件系统的功能。这可能会带来严重的安全隐患,除非绝对需要,否则应将其关闭。
在该文件的同一部分,我们将添加一条指令来禁用加载本地文件的功能:
local-infile=0
这将禁止没有文件级别权限的用户从文件系统向数据库加载文件。
如果我们有足够的空间并且没有操作庞大的数据库,那么记录额外的信息来监视可疑活动会很有帮助。
记录过多可能会对性能造成影响,因此您需要仔细权衡这一点。
您可以在我们一直添加的相同“[mysqld]”部分内设置日志变量。
log=/var/log/mysql-logfile
确保 MySQL 日志、错误日志和 mysql 日志目录不是所有人都可读的:
sudo ls -l /var/log/mysql*
-rw-r----- 1 mysql adm 0 Jul 23 18:06 /var/log/mysql.err -rw-r----- 1 mysql adm 0 Jul 23 18:06 /var/log/mysql.log /var/log/mysql: total 28 -rw-rw---- 1 mysql adm 20694 Jul 23 19:17 error.log
从内部保护 MySQL
使用 MySQL 时,您可以采取多种措施来提高安全性。
我们将把本节中的命令输入到MySQL提示符界面中,因此我们需要登录。
mysql -u root -p
系统将要求您输入之前设置的 root 密码。
保护密码和主机关联
首先,确保 MySQL 中没有没有密码或主机关联的用户:
SELECT User,Host,Password FROM mysql.user;
+------------------+-----------+-------------------------------------------+ | user | host | password | +------------------+-----------+-------------------------------------------+ | root | localhost | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 | | demo-user | % | | | root | 127.0.0.1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 | | root | ::1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 | | debian-sys-maint | localhost | *ECE81E38F064E50419F3074004A8352B6A683390 | +------------------+-----------+-------------------------------------------+ 5 rows in set (0.00 sec)
如您所见,在我们的示例设置中,用户“demo-user”没有密码,无论他在哪个主机上都是有效的。这非常不安全。
我们可以使用此命令为用户设置密码。更改“ newPassWord ”以反映您希望分配的密码。
UPDATE mysql.user SET Password=PASSWORD('newPassWord') WHERE User="demo-user";
如果我们再次检查 User 表,我们将看到演示用户现在有一个密码:
SELECT User,Host,Password FROM mysql.user;
+------------------+-----------+-------------------------------------------+ | user | host | password | +------------------+-----------+-------------------------------------------+ | root | localhost | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 | | demo-user | % | *D8DECEC305209EEFEC43008E1D420E1AA06B19E0 | | root | 127.0.0.1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 | | root | ::1 | *DE06E242B88EFB1FE4B5083587C260BACB2A6158 | | debian-sys-maint | localhost | *ECE81E38F064E50419F3074004A8352B6A683390 | +------------------+-----------+-------------------------------------------+ 5 rows in set (0.00 sec)
如果您查看“主机”字段,您将看到我们仍然有一个“%”,这是一个通配符,表示任何主机。这不是我们想要的。让我们将其更改为“localhost”:
UPDATE mysql.user SET Host='localhost' WHERE User="demo-user";
如果我们再次检查,我们可以看到用户表现在已经设置了适当的字段。
SELECT User,Host,Password FROM mysql.user;
如果我们的表包含任何空白用户(由于我们运行了“mysql_secure_installation”,因此此时不应该如此,但我们无论如何都会介绍这一点),我们应该删除它们。
为此,我们可以使用以下调用从访问表中删除空白用户:
DELETE FROM mysql.user WHERE User="";
修改完User表之后,我们需要输入以下命令来实现新的权限:
FLUSH PRIVILEGES;
实现特定于应用程序的用户
与在 Linux 中以隔离用户身份运行进程的做法类似,MySQL 也受益于相同类型的隔离。
每个使用 MySQL 的应用程序都应该有自己的用户,该用户仅具有有限的权限并且只能访问其运行所需的数据库。
当我们配置一个新的应用程序来使用 MySQL 时,我们应该创建该应用程序所需的数据库:
create database testDB;
Query OK, 1 row affected (0.00 sec)
接下来,我们应该创建一个用户来管理该数据库,并为其分配所需的权限。这将因应用程序而异,有些用途需要比其他用途更多的开放权限。
要创建新用户,请使用以下命令:
CREATE USER 'demo-user'@'localhost' IDENTIFIED BY 'password';
我们可以使用以下命令授予新用户对新表的权限。请参阅有关如何在 MySQL 中创建新用户和授予权限的教程,以了解有关特定权限的更多信息:
GRANT SELECT,UPDATE,DELETE ON testDB.* TO 'demo-user'@'localhost';
例如,如果我们稍后需要撤销该帐户的更新权限,我们可以使用以下命令:
REVOKE UPDATE ON testDB.* FROM 'demo-user'@'localhost';
如果我们需要某个数据库的所有权限,我们可以这样指定:
GRANT ALL ON testDB.* TO 'demo-user'@'localhost';
要显示用户的当前权限,我们首先必须使用“flush rights”命令实现我们指定的权限。然后,我们可以查询用户拥有哪些权限:
FLUSH PRIVILEGES;
show grants for 'demo-user'@'localhost';
+------------------------------------------------------------------------------------------------------------------+ | Grants for demo-user@localhost | +------------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'demo-user'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' | | GRANT SELECT, UPDATE, DELETE ON `testDB`.* TO 'demo-user'@'localhost' | +------------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)
完成更改后,请务必刷新权限。
更改根用户
您可能需要采取的另一个步骤是更改根登录名。如果攻击者试图访问根 MySQL 登录名,他们将需要执行查找用户名的额外步骤。
可以使用以下命令更改 root 登录名:
rename user 'root'@'localhost' to 'newAdminUser'@'localhost';
我们可以使用与用户数据库相同的查询来查看变化:
select user,host,password from mysql.user;
再次强调,我们必须清除权限才能使这些更改发生:
FLUSH PRIVILEGES;
请记住,从现在起,当您想要执行管理任务时,您必须以新创建的用户名登录 MySQL:
mysql -u newAdminUser -p
结论
虽然这绝不是 MySQL 和 MariaDB 安全实践的详尽列表,但它应该可以很好地介绍在保护数据库时必须做出的决策类型。
有关配置和安全的更多信息,请参阅 MySQL 和 MariaDB 网站及其各自的手册页。您选择使用的应用程序也可能提供安全建议。