数据库安全从来不是单点配置,而是网络、账号、数据多层防御的结果。MySQL作为最常用的关系型数据库,默认安装往往偏向易用而非安全,若直接投入生产,极易成为攻击入口。下面从实际部署角度拆解关键设置。

一、网络层隔离与访问限制
最基础也最容易被忽视的一步,是让MySQL尽量不出现在公网。很多入侵事件的根源,就是数据库端口被直接映射到了外网。我们应当修改配置文件,将监听地址绑定到内网IP,避免0.0.0.0的全网监听。
在Linux环境下,MySQL的配置文件通常位于/etc/mysql/my.cnf或/etc/my.cnf。通过指定bind-address,可以限制接收连接的网卡。同时配合防火墙只放行应用服务器的IP,能大幅缩小暴露面。
[mysqld] # 仅监听内网地址,禁止公网直接访问 bind-address = 192.168.0.1 # 关闭域名反向解析,提升连接效率也减少信息泄露 skip-name-resolve
除了绑定地址,还要禁止远程root登录。root账号权限极高,一旦密码薄弱被爆破,整个实例都会沦陷。应创建业务专属账号,并限制其来源主机。
用防火墙进一步收敛端口
即便bind-address配置正确,仍建议用iptables或云安全组做二层限制。例如只允许应用网段访问3306端口,其他全部拒绝。这种冗余设计能在配置误改时提供兜底。
# 仅允许192.168.0.0/24访问3306 iptables -A INPUT -p tcp -s 192.168.0.0/24 --dport 3306 -j ACCEPT iptables -A INPUT -p tcp --dport 3306 -j DROP
二、账号权限最小化
权限控制的核心原则是:每个应用使用独立账号,且只拥有对应库表的必要权限。很多老系统图省事,所有服务共用root,一旦某个服务被注入,攻击者就能顺手导出全库。
创建账号时应显式指定来源主机,并使用强密码。MySQL 5.7之后默认安装了validate_password插件,可强制密码复杂度。我们还可以设置密码过期,倒逼定期轮换。
-- 创建仅限内网访问的应用账号 CREATE USER 'app_user'@'192.168.0.%' IDENTIFIED BY 'StrongPass#2024!'; -- 只授予某库增删改查,不碰其他库 GRANT SELECT, INSERT, UPDATE, DELETE ON shop_db.* TO 'app_user'@'192.168.0.%'; -- 强制90天改密 ALTER USER 'app_user'@'192.168.0.%' PASSWORD EXPIRE INTERVAL 90 DAY; FLUSH PRIVILEGES;
定期审计账号权限也很有必要。通过查询mysql.user和mysql.db表,能发现残留的废弃账号或过量授权。对于长期不用的账号,应及时回收。
收回危险权限
FILE、SUPER、PROCESS等全局权限普通应用绝不需要。FILE权限可让攻击者用INTO OUTFILE写恶意文件,SUPER能kill线程甚至改binlog格式。授权时务必逐项核对。
-- 查看某账号拥有的全局权限 SHOW GRANTS FOR 'app_user'@'192.168.0.%'; -- 若有多余权限则回收 REVOKE FILE, SUPER ON *.* FROM 'app_user'@'192.168.0.%';
三、传输与存储加密
明文传输的数据库流量在局域网被抓包也会泄露凭证和记录。启用SSL后,客户端与服务器之间的通信会被加密。MySQL自带ssl相关命令生成证书,配置后强制特定用户使用SSL连接。
除了传输层,静态数据加密可借助InnoDB表空间加密或磁盘级LUKS。前者对备份文件也生效,适合合规要求高的场景。不过加密会带来少量性能开销,需结合业务评估。
-- 要求应用账号必须走SSL ALTER USER 'app_user'@'192.168.0.%' REQUIRE SSL; -- 创建加密表空间(需提前开启keyring) CREATE TABLE secret_info ( id INT PRIMARY KEY, data VARCHAR(200) ) ENCRYPTION='Y';
开启SSL时,服务端配置需在my.cnf指明证书路径。重启后可用STATUS命令确认SSL字段为Cipher,说明握手成功。
备份文件同样要保护
mysqldump导出的sql文件往往含全量数据,若明文落盘等于变相泄密。可用openssl管道加密后再传对象存储,恢复时反向解密。
mysqldump -u root shop_db | openssl enc -aes-256-cbc -out shop.sql.enc openssl enc -d -aes-256-cbc -in shop.sql.enc | mysql -u root shop_db
四、审计与日志溯源
安全设置做完并非一劳永逸。开启慢查询日志与通用查询日志(测试环境)有助于发现异常语句。企业版有审计插件,社区版可用init-connect配合binlog做轻量记录。
二进制日志不仅用于主从复制,也是事后溯源的利器。设定合理的expire_logs_days,既保留线索又避免磁盘被写满。发现可疑IP频繁失败登录,应立刻加入黑名单。
[mysqld] slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 log_bin = mysql-bin expire_logs_days = 14
综合来看,MySQL最安全的设置不是某一个参数,而是把网络收敛、账号收权、加密传输和持续审计拼成闭环。按上述步骤逐项落地,就能把绝大多数自动化扫描和拖库攻击挡在门外。