为 MySQL 设置 VPS

为 MySQL 设置 VPS

我们的 VPS 设置方式是,所有数据库都可以通过本地主机和用户名/密码/数据库名称从任何域访问。

这是通常的设置吗,或者应该有某种方式来“监禁”每个用户,以便他们无法访问本地主机上的其他数据库?

谢谢,马克

答案1

正如 Caleb 提到的,在设置 MySQL 时,最好像其他系统一样,运行最低权限系统 - 除非不同的应用程序相关,否则它们没有理由访问彼此的数据库。如果一些相关,那么他们应该被授予特定的,有限的他们需要访问其他数据库中的表的权限,但仅此而已。

我假设你说

可以通过 localhost 从任何域访问

您的意思是您正在运行多域 Apache 安装(或类似安装),这意味着您的所有应用程序都在同一台机器上运行,因此,从 MySQL 的角度来看,每个用户都是一个'username'@'localhost'用户,所以您只能通过用户名指定用户。

需要注意的是,由于 MySQL 权限的工作方式,在有远程用户的情况下,这'user1'@'abc.example.com'实际上是完全不同的用户'user1'@'xyz.example.com'尽管'user1'@'localhost'共享用户名确实会大大增加您设置权限的灵活性(或者使事情变得非常混乱,这取决于您的观点)。如果可以的话,最好在不同的虚拟机上运行数据库服务器 - 当然这不是必须的。

添加数据库用户的常见、易于使用(但不安全)的方法往往是这样的:

GRANT ALL ON *.* TO `user1`@`localhost`;

这只是授予该用户GLOBAL在任何数据库上执行任何操作的权限。

这很糟糕,原因显而易见,但也并不那么明显。*.*包括mysql数据库本身 - 它允许您执行任何事物您喜欢与其他用户、设置等共享权限,应避免这种情况。ALL语句的一部分授予GLOBAL范围内可用的所有权限 - 这意味着他们可以执行诸如SHOW PROCESSLIST和之类的操作KILL <query-id>。这似乎没什么问题(“他们为什么要这样做?”)但正如 Caleb 所说 - 如果应用程序受到攻击,它连接的数据库用户就是攻击者“用来对付”您的用户。

对上述内容的一个简单改进是使用如下语句为每个数据库分配权限:

GRANT ALL ON `user1_database`.* TO `user1`@`localhost`;

这将授予所有级别DATABASE的权限- 这很重要,因为它排除了上面列出的所有强大的权限,所以现在用户最坏的情况是删除自己的数据库。user1user1_databaseGLOBAL

这种方法的进一步改进是为每个应用程序创建至少两个用户。一个拥有GRANT ALL数据库权限(用于管理),另一个由 Web 应用程序本身使用,该用户仅拥有所需的权限,并且仅拥有需要访问的对象。当您进行更改和额外测试时,这显然需要相当多的额外工作,但做得好可以大大减少系统受到损害时可能造成的损害。

我通常有一个标准用户,以及另一个带有_wwwWeb 应用程序后缀的用户。

你可以使用 MySQL 的通配符权限来简化其中的一些操作,并让用户可以创建自己的数据库(匹配特定的模式)并

例子

-- Create a user that has ALL privileges on databases beginning with 'user1_' 
-- This is our application admin user 
-- it can create any database that matches the pattern

GRANT ALL ON `user1\_%`.* TO `user1`@`localhost`;

-- Create a "safe" version of this user with just the ability to modify data
-- This is a generic approach and could be applied at object level per-database

GRANT SELECT, INSERT, UPDATE, DELETE ON `user1\_%`.* TO `user1_www`@`localhost`;

示例中创建管理员用户的方式是共享环境中的常用方法 - 它允许用户创建数据库,而无需分配任何GLOBAL权限,以便他们看不到其他用户的数据库。

答案2

您应该使用 MySQL 权限表来设置更细粒度的权限,以便每个应用程序(甚至是应用程序的组件)只能访问其功能所需的数据库或表。这将减少隐私侵犯的潜在问题,减少发生安全漏洞时的损失,甚至有助于在测试期间发现软件中的错误。

答案3

正如 @simon 和 @caleb 提到的,授予全局权限是很常见的,但这并不意味着它是一种好的做法,我使用这个“宏”(这是我根据 serverfault 或 SO 上的另一篇文章拼凑起来的,但我不记得是哪一个了)来获得权限:


SET @usr = '\'username\'@\'localhost\'';
SET @pwd = '\'longpassword\'';
SET @db = 'database';
set @query = CONCAT('revoke all privileges on *.* from ', @usr);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;
set @query = CONCAT('drop user ', @usr);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;
set @query = CONCAT('create user ', @usr, ' identified by ', @pwd);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;
set @obj = CONCAT(@db, '.tablename');SET @query = CONCAT('GRANT select ON ', @obj, ' TO ', @usr, ' identified by ', @pwd);PREPARE stmt FROM @query;EXECUTE stmt;DEALLOCATE PREPARE stmt;

删除“撤销”、“删除”和“创建”行,并根据需要更改表名和权限。正如@caleb 所建议的那样,它允许以最少的麻烦创建细粒度的权限。

相关内容