安全配置

最后更新: 2026-01-22 作者: MySQL Team
页面目录

第十四章:安全配置


14.1 用户管理

创建用户

-- 基本语法
CREATE USER 'username'@'host' IDENTIFIED BY 'password';

-- 示例
CREATE USER 'app'@'localhost' IDENTIFIED BY 'AppPass123!';
CREATE USER 'app'@'192.168.1.%' IDENTIFIED BY 'AppPass123!';
CREATE USER 'app'@'%' IDENTIFIED BY 'AppPass123!';

修改用户

-- 修改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPassword123!';

-- 或
SET PASSWORD FOR 'username'@'host' = 'NewPassword123!';

-- 重命名用户
RENAME USER 'old_user'@'host' TO 'new_user'@'host';

-- 锁定/解锁用户
ALTER USER 'username'@'host' ACCOUNT LOCK;
ALTER USER 'username'@'host' ACCOUNT UNLOCK;

删除用户

DROP USER IF EXISTS 'username'@'host';
DROP USER 'user1'@'host', 'user2'@'host';

查看用户

-- 查看所有用户
SELECT User, Host, Account_locked FROM mysql.user;

-- 查看用户权限
SHOW GRANTS FOR 'username'@'host';
SHOW GRANTS FOR CURRENT_USER;

14.2 权限管理

授予权限

-- 基本语法
GRANT privilege_type ON db_name.table_name TO 'username'@'host';

-- 常用权限
-- ALL PRIVILEGES: 所有权限
-- SELECT, INSERT, UPDATE, DELETE: 数据操作
-- CREATE, DROP, ALTER: 数据定义
-- INDEX, REFERENCES: 索引和约束

-- 示例:授予数据库所有权限
GRANT ALL PRIVILEGES ON mydb.* TO 'app'@'localhost';

-- 示例:授予特定权限
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app'@'localhost';
GRANT SELECT ON mydb.readonly_table TO 'reader'@'%';

-- 示例:授予存储过程执行权限
GRANT EXECUTE ON PROCEDURE mydb.my_procedure TO 'app'@'localhost';

-- 示例:授予列级权限
GRANT SELECT (id, name, email), UPDATE (name, email) ON mydb.users TO 'app'@'localhost';

撤销权限

REVOKE privilege_type ON db_name.table_name FROM 'username'@'host';

-- 示例
REVOKE DELETE ON mydb.* FROM 'app'@'localhost';
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'app'@'localhost';

刷新权限

FLUSH PRIVILEGES;

权限层级

层级 说明
Global *.* 所有数据库
Database db_name.* 指定数据库
Table db_name.table_name 指定表
Column 列级权限
Routine db_name.proc_name 存储过程/函数

14.3 密码策略

MySQL 8.0 密码验证

-- 查看密码策略
SHOW VARIABLES LIKE 'validate_password%';

-- 配置参数
-- validate_password.length: 最小长度
-- validate_password.mixed_case_count: 大小写字母数
-- validate_password.number_count: 数字个数
-- validate_password.special_char_count: 特殊字符数
-- validate_password.policy: 策略级别

设置密码策略

-- 临时设置
SET GLOBAL validate_password.length = 8;
SET GLOBAL validate_password.mixed_case_count = 1;
SET GLOBAL validate_password.number_count = 1;
SET GLOBAL validate_password.special_char_count = 0;

-- 配置文件设置
[mysqld]
validate_password.length = 8
validate_password.mixed_case_count = 1
validate_password.number_count = 1
validate_password.policy = LOW

14.4 网络安全

限制连接来源

-- 只允许本地连接
CREATE USER 'app'@'localhost';

-- 允许特定 IP
CREATE USER 'app'@'192.168.1.100';
CREATE USER 'app'@'192.168.1.%';     -- IP段
CREATE USER 'app'@'192.168.%.%';     -- B类网段

-- 禁止远程 root 登录
CREATE USER 'root'@'localhost';
DROP USER 'root'@'%';

SSL/TLS 配置

-- 检查 SSL 状态
SHOW VARIABLES LIKE 'have_ssl';
SHOW VARIABLES LIKE 'ssl_%';

-- 强制 SSL 连接
[mysqld]
require_secure_transport = ON
ssl_ca = /path/to/ca.pem
ssl_cert = /path/to/server-cert.pem
ssl_key = /path/to/server-key.pem

防火墙配置

# CentOS/RHEL
firewall-cmd --permanent --add-service=mysql
firewall-cmd --reload

# 只允许特定 IP 访问 3306 端口
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="3306" protocol="tcp" accept'

# Ubuntu/Debian
ufw allow from 192.168.1.0/24 to any port 3306

14.5 敏感数据保护

加密存储

-- 使用 AES 加密
INSERT INTO secrets (name, data) VALUES ('api_key', AES_ENCRYPT('secret_value', 'encryption_key'));
SELECT AES_DECRYPT(data, 'encryption_key') FROM secrets WHERE name = 'api_key';

-- MySQL 8.0 内置函数
INSERT INTO secrets (name, data) VALUES ('api_key', TO_BASE64(AES_ENCRYPT('secret_value', SHA2('encryption_key', 256))));

数据脱敏

-- 创建视图隐藏敏感字段
CREATE VIEW user_public AS
SELECT id, username, email,
       CONCAT(LEFT(phone, 3), '****', RIGHT(phone, 4)) AS phone,
       CONCAT(LEFT(id_card, 6), '********', RIGHT(id_card, 4)) AS id_card
FROM users;

-- 授予视图权限
GRANT SELECT ON mydb.user_public TO 'app'@'localhost';

行级安全

-- 创建安全视图
CREATE VIEW my_orders AS
SELECT * FROM orders WHERE user_id = CURRENT_USER_ID();

-- 或使用存储过程
CREATE PROCEDURE get_my_orders()
BEGIN
    SELECT * FROM orders WHERE user_id = CONNECTION_ID();
END;

14.6 审计日志

通用查询日志

-- 启用通用查询日志
SET GLOBAL general_log = 'ON';
SET GLOBAL general_log_file = '/var/log/mysql/query.log';

-- my.cnf 配置
[mysqld]
general_log = 1
general_log_file = /var/log/mysql/query.log
log_output = FILE

MySQL Enterprise Audit

-- 安装审计插件
INSTALL PLUGIN audit_log SONAME 'audit_log.so';

-- 配置
[mysqld]
audit_log = ON
audit_log_file = /var/log/mysql/audit.log
audit_log_policy = ALL
audit_log_rotate_on_size = 100M

查询审计表

-- 查看审计日志
SELECT * FROM mysql.audit_log;

14.7 安全加固建议

# 1. 初始化安全配置
mysql_secure_installation

# 2. 禁止 load_file 和 load data
SET GLOBAL local_infile = 0;

# 3. 禁用 symbol_links
symbolic-links = 0

# 4. 禁止使用 mysql 命令历史
rm -f ~/.mysql_history
ln -s /dev/null ~/.mysql_history

# 5. 修改默认端口
[mysqld]
port = 3307

# 6. 禁止 root 远程登录
# 在 mysql.user 表中删除 root@'%' 记录

# 7. 定期更新密码
ALTER USER 'app'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;

# 8. 最小权限原则
# 只授予应用程序需要的最小权限

14.8 本章小结

✅ 用户管理:创建、修改、删除用户
✅ 权限管理:GRANT/REVOKE 精细控制
✅ 密码策略:强密码要求和定期更换
✅ 网络安全:SSL/TLS、防火墙、IP限制
✅ 敏感数据:AES加密、数据脱敏
✅ 审计日志:记录所有操作行为