介绍
在 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]”部分中的“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";
如果我们再次检查,我们可以看到 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; 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)
完成更改后,请始终刷新权限。
更改根用户
您可能需要采取的另一步骤是更改 root 登录名。 如果攻击者试图访问根 MySQL 登录,他们将需要执行查找用户名的附加步骤。
可以使用以下命令更改 root 登录名:
rename user 'root'@'localhost' to 'newAdminUser'@'localhost';
我们可以使用我们一直用于 User 数据库的相同查询来查看更改:
select user,host,password from mysql.user;
同样,我们必须刷新权限才能使这些更改发生:
FLUSH PRIVILEGES;
请记住,从现在开始,当您希望执行管理任务时,您必须以新创建的用户名登录 MySQL:
mysql -u newAdminUser -p
结论
尽管这绝不是 MySQL 和 MariaDB 安全实践的详尽列表,但它应该很好地介绍了在保护数据库时必须做出的各种决策。
有关配置和安全性的更多信息可以在 MySQL 和 MariaDB 网站以及它们各自的手册页中找到。 您选择使用的应用程序也可能会提供安全建议。