[读书笔记]High Performance MySQL–第十章

Chapter 10. Security

10.1 Account Basics
MySQL 中账户由三部分构成:用户名、密码和地点。来自不同地点但用户名相同的用户被视为完全不同的用户,这和 UNIX 的用户机制不同。

在与 MySQL 连接时,它要做三种安全检查:认证、授权和访问控制。授权应用于全局性的权限,访问控制则应用于具体的查询。

10.1.1 Privileges
访问控制由一些权限构成。这些权限控制如何使用和处理 MySQL 各种对象:数据库、表、列和索引。这些权限包括:Select、Insert、Update、Index、Alter、Create、Grant、References。需要提醒是这些权限并不适用于所有的对象。

10.1.1.1 Global privileges
全局性的权限包括:Reload、Shutdown、Process、File、Super。

提醒的是 FILE 权限非常危险,不要轻易授权它。下面是一个例子:
CREATE TABLE test (test TEXT);
LOAD DATA INFILE “/etc/passwd” into TABLE test;
SELECT * FROM test;
如此这般,系统地口令文件内容就被泄露。事实上,只要是 MySQL 可读的文件,拥有 FILE 权限的用户同样可以读到它。

10.2 The Grant Tables
Grant 表是 MySQL 安全系统的核心。你要十分小心地配置它,才能给用户所需的和恰当的权限。

下面简介这五个 Grant 表,它们的顺序也是 MySQL 作安全检查时咨询它们的顺序:
User 表包含全局权限和加密过的密码。它决定哪个主机和用户可以连接到服务器。
Host 表在单主机的基础上来分配数据库级别权限的,它不考虑用户。另外,此表不受 Grant 和 Revoke 命令的影响。
Db 表在数据库的级别来上设置权限。
Tablespriv 表在表级的级别上来设置权限。
Columns
priv 表设置列级别权限。这里设置的权限应用于特定数据库中特定表的特定列。

10.2.1 Privilege Checks
MySQL 会检查每个查询来确定用户是否有权限来执行。此种检查通过按照特定的次序咨询 Grant 表来实现的。表中的权限设置可能会被稍后所检查表的权限推翻。

10.2.2 The user Table
MySQL 的 user 表包含了用户的认证信息和其全局权限设置。换句话说,user 表相当於 MySQL 的 “/etc/passwd”。User 表的主键是由字段 User 和 Host 组成,这就意味着一个用户可能有多条主机不同的记录。

10.2.2.1 Host matching
MySQL 权限系统的基本规则是最匹配的记录胜出。MySQL 在 user 表中基於 Host 和 User 字段排序,也就是不含通配符的主机名和 IP 地址排在靠前的位置。

10.3 Grant and Revoke
MySQL 中改变权限所推荐的方法是使用 GRANT REVOKE 命令。它们方便易行且无须弄清楚 grant 表和哪些匹配规则。

10.3.1 Grant Mechanics

10.3.1.1 System administrator account
一般情况下,你应该有两个重要的管理员。系统管理员维护物理服务器,包括操作系统,登陆帐号等。另外一个就数据库管理员维护数据库服务。

处於安全的原因,你可以限制 root 帐号对数据库的访问:
mysql> REVOKE ALL PRIVILEGES ON . FROM ‘root’@’localhost’;

10.3.1.2 Database administrator account
下面一个例子是给与来自任何主机的用户 raymond 所有的权限:
mysql> GRANT ALL PRIVILEGES ON . TO ‘raymond’@’%’ IDENTIFIED BY ‘27skuw!’
-> WITH GRANT OPTION;

10.3.1.3 Average employee account
下面的例子产生一个普通帐户:
mysql> GRANT INSERT,UPDATE PRIVILEGES ON widgets.orders
-> TO ‘tera’@’%.widgets.example.com’
-> IDENTIFIED BY ‘rachel!94’;

10.3.1.4 Logging, write-only access
设置一个只写的用户来记录日志:
mysql> GRANT INSERT ON logs.* TO ‘logger’@’%.widgets.example.com’
-> IDENTIFIED BY ‘blah0halb’;

10.3.1.5 Operations and monitoring
建立一个监视和操作的用户:
mysql> GRANT PROCESS, SHUTDOWN on .
-> TO ‘noc’@’monitorserver.noc.widgets.example.com’
-> IDENTIFIED BY ‘q!w@e#r$t%’;

10.3.2 Common Problems and Limitations

10.3.2.1 Can’t revoke specific privileges
MySQL 没有提供并行的系统来限制权限(就像 UNIX 系统中 host.allow 和 host.deny)。所以你不能限制用户特定的权限,除非你不赋予他。

10.3.2.2 Host and database matching can’t exclude matches

这给用户也带来了不方便,但从 MySQL 的观点来看,你不需要限制权限,你只要不赋予它权限。

下面这个例子,限制用户只不能从一特定的主机访问:
mysql> GRANT ALL PRIVILEGES ON . TO raymond@”%”
-> EXCEPT raymond@insecure.example.com;
这个命令行不通地。要实现它除非从网络层阻挡或者建立此特定主机的记录并加上用不知晓的密码。

10.3.2.3 Privileges don’t vanish when objects do
举个例子:
mysql> GRANT ALL PRIVILEGES ON mydb.* TO raymond;
然后
$ mysqladmin drop my
db
此时, raymond 依然保留对 mydb 的权限,这是个安全隐患。假如以后你要建立 mydb,那么你仍然要 raymond 拥有对 mydb 的权限吗?所以,当你删除一个数据库后,最好取消掉在 Grant 表中相应的权限:
mysql> DELETE FROM db where Db=’my
db’;
mysql> DELETE FROM tablespriv where Db=’mydb’;
mysql> DELETE FROM columnspriv where Db=’mydb’;
mysql> FLUSH PRIVILEGES;

10.4 Operating System Security

10.4.1 Guidelines
不要使用特权用户来运行 MySQL。
即时更新操作系统。
限制不必要的数据库主机登陆。
对服务器进行安全审计。

10.5 Network Security

10.5.1 Localhost-Only Connections
如果 MySQL 和应用程序在同一主机上,那我们可以无须网络的支持。 skip-networking 选项可以让 MySQL 不监听 Tcp 接口。

Localhost 对于 MySQL 客户端函数库具有特殊的意思,它表示用本地的套接口来连接 MySQL 而不是 Tcp 的套接口。

10.5.2 Firewalling
有防火墙当然好,双保险。

10.5.2.1 No default route
也可以考虑在防火墙保护下的 MySQL 服务器不设置默认路由。这样,即使防火墙失效,外部的主机尝试访问服务器,应答的 tcp 包也不会返回到外部那些主机。

10.5.3 MySQL in a DMZ
我觉得没什么必要,成本似乎太高。

10.5.4 Connection Encryption and Tunneling

10.5.4.1 Virtual private networks
VPN 当然是一个好的解决方案。

10.5.4.2 SSL in MySQL
在 MySQL 4.1 版本,它本身已经支持 SSL 。检查服务器是否启用 SSL
mysql> SHOW VARIABLES LIKE ‘have_openssl’;

10.5.4.3 SSH tunneling
举个例子:
$ ssh -N -f -L 4406:db.example.com:3306
然后
$ mysql -h 127.0.0.1 -P 4406

10.5.5 TCP Wrappers
MySQL 在 UNIX 上可以得到 Tcp wrapper 的支持,编译的时候启用—with-libwrap 选项:
$ ./configure—with-libwrap=/usr/local/tcp_wrappers
然后在 /etc/host.deny 里有如此内容:

deny all connections

ALL: ALL
修改 /etc/host.allow:

allow mysql connections from hosts on the local network

mysqld: 192.168.1.0/255.255.0.0 : allow

10.5.6 Automatic Host Blocking
服务器变量 maxconnectionerrors 表述了在连接的主机被封之前,可以进行多少次错误的连接。当主机被封,MySQL 会在错误日志记录:
Host ‘host.badguy.com’ blocked because of many connection errors.
Unblock with ‘mysqladmin flush-hosts’

10.6 Data Encryption
哈希算法是不可逆的。MySQL 提供了四个哈希函数:PASSWORD, ENCRYPT, SHA1, 和 MD5

例子:
INSERT INTO user_table (user, pass) VALUE (‘jzawodn’, MD5 )

SELECT *

FROM user_table

WHERE user = ‘$username’

AND pass = MD5

10.6.2 Encrypted Filesystems
加密文件系统的缺点在于对 CPU 的开销,另外在备份的时候也麻烦些。

10.6.3 Application-Level Encryption
这部分不感兴趣。

10.6.4 Source Code Modification
GPL 下直接修改源码也是一个方案。

10.7 MySQL in a chrooted Environment
好处在于安全性,编译的时候要这样:
$ ./configure—prefix=/chroot/mysql
然后
chroot /chroot/mysql
现在根目录实际上就是 /chroot/mysql 了。

Post a Comment