如何在 Linux VPS 中保护 MySQL 和 MariaDB 数据库
介绍
在 Linux 和类 Unix 系统上有许多 SQL 数据库语言的实现。 MySQL 和 MariaDB 是在服务器环境中部署关系数据库的两个流行选项。
但是,与大多数软件一样,如果配置不正确,这些工具可能会成为安全隐患。本教程将指导您完成一些基本步骤,您可以采取这些步骤来保护您的 MariaDB 或 MySQL 数据库,并确保它们不会为您的 VPS 敞开大门。
为了简单和说明,我们将在 Ubuntu 12.04 VPS 实例上使用 MySQL 服务器。然而,这些技术可以应用于其他 Linux 发行版,也可以与 MariaDB 一起使用。
初始设置
MySQL 让您有机会在安装过程中迈出迈向安全的第一步。它将要求您设置根密码。
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]”部分中的“绑定地址”设置。此设置应设置为您的本地环回网络设备,即“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 表,我们将看到 demo 用户现在有一个密码:
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)
如果您查看“主机”字段,您会看到我们仍然有一个“%”,这是一个表示任何主机的通配符。这不是我们想要的。让我们将其更改为“本地主机”:
UPDATE mysql.user SET Host='localhost' WHERE User="demo-user";
如果我们再次检查,我们可以看到 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 privileges”命令实现我们指定的权限。然后,我们可以查询用户有哪些授权:
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 网站以及它们各自的手册页中找到。您选择使用的应用程序也可能会提供安全建议。