提供:ZStack 云计算
Linux 与 Unix 类系统之上存在着大量 SQL 数据库语言实现方案。MySQL 与 MariaDB 正是其中最为流行的两种选项。
然而,与大多数软件一样,这些工具如果未经正确配置也可能面临安全风险。在本教程中,我们将了解如何利用一系列基本步骤保证其安全。
为了内容的简单与直观,我们将在 Ubuntu 12.04 VS 实例上使用 MySQL 服务器。不过这些技术也适用于其它 Linux 发行版以及 MaraDB。
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"(yes)即可。
如此一来,任何人在默认情况下都无法登录至 MySQL,管理员账户远程登录机制被禁用、部分不安全的测试数据库被移除,同时对当前运行的 MySQL 实例更新以应用上述变更。
要保护 MySQL 及其它各类系统的安全,最重要的就是只在必要时提供访问权限。具体来讲,数据安全也可以归结为便利与安全间的权衡。
在本教程中,我们将尽可能偏向安全方面。
MySQL 的主配置文件为 "my.cnf",其在 Ubuntu 上位于 "/etc/mysql/" 目录当中,在其它 VPS 中则位于 "/etc/" 目录。
我们变更此文件中的部分设置以锁定 MySQL 实例。
以 root 权限打开该文件,如果大家所使用的系统与本教程不同,可利用以下命令变更其路径:
- sudo nano /etc/mysql/my.cnf
这里首先检查 "bind-address" 设定,其位于 "[mysqld]" 部分内。此设定应当被设置为本地闭环网络设备,即 "127.0.0.1"。
- bind-address = 127.0.0.1
这能够确保 MySQL 不接收任何本地设备之外的连接。
如果大家需要通过其它设备访问此数据库,可以考虑通过 SSH 接入以进行数据库查询、本地管理并通过 SSH 隧道发送结果。
接下来我们要修复的问题是允许在 MySQL 内部访问底层文件系统。这可能引发安全问题,因此应当在非必要时加以关闭。
在该文件的同一部分内,添加以下指令以禁用加载本地文件的能力:
- local-infile=0
如果大家拥有充足的存储空间且数据库本身规模不大,则可以记录更多信息以检测异常活动。
过于频繁的记录可能造成性能影响,因此大家需要对此做出权衡。
大家可以在同一 "[mysqld]" 部分内设定 log 变量:
- 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 -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 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)
如果大家查看 "Host" 字段,则会发现我们仍然拥有一个 "%",这一通配符可代表任意主机。我们需要将其变更为 "localhost":
- UPDATE mysql.user SET Host='localhost' WHERE User="demo-user";
再次检查,可以看到 User 表现在拥有了正确的字段设置。
- SELECT User,
- Host,
- Password FROM mysql.user;
如果我们的表当中包含任何空白用户,则应当将其移除。
要将其移除,我们可以使用以下命令以移除访问表中的空白用户:
- 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)
在完成任何变更时,请务必记得刷新权限。
另外需要变更 root 登录名称。如果攻击者尝试进行 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 网站以获取更多配置与安全信息。另外,大家选择使用的各类应用也会提供与之相关的安全建议。
本文来源自 DigitalOcean Community
来源: http://blog.csdn.net/zstack_org/article/details/70242820