在ecs上安全部署mysql,核心是必须完成三件事:关掉默认远程访问、改掉初始密码、限制root登录范围;漏掉任何一项,数据库就等于裸奔在公网。

直接说结论:在ECS上安全部署MySQL,核心不是“装上就行”,而是必须完成三件事——关掉默认远程访问、改掉初始密码、限制root登录范围。漏掉任何一项,数据库就等于裸奔在公网。
为什么不能跳过 mysql_secure_installation?
MySQL 5.7+ 安装后自动生成的 root 初始密码只在 /var/log/mysqld.log 里出现一次,且强制要求重置。跳过这步直接用 mysql -uroot -p 连,大概率报错 ERROR 1045 (28000): Access denied for user 'root'@'localhost' ——因为密码已过期,连本地都登不进去。
更关键的是,mysql_secure_installation 默认会:删匿名用户、禁用 root 远程登录、删 test 库、重载权限表。这些不是“可选优化”,是基础防线。
- 如果手动执行
GRANT ALL ON *.* TO 'root'@'%',等于主动打开后门 - 不删 test 库,攻击者可能利用其默认权限构造注入
- 不重载权限表(
FLUSH PRIVILEGES),新规则根本不会生效
远程访问必须用独立账号,别碰 root
生产环境绝对禁止用 root 账号远程连接。阿里云安全组放行了 3306 端口后,只要 MySQL 允许 'root'@'%',公网扫描器几秒就能撞出密码。
正确做法是创建最小权限账号:
CREATE USER 'appuser'@'%' IDENTIFIED BY 'YourPass123!';<br>GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'appuser'@'%';<br>FLUSH PRIVILEGES;
注意点:
-
'appuser'@'%'中的%表示任意IP,如只需某台应用服务器访问,应写成'appuser'@'192.168.1.100' - 密码必须含大小写字母+数字+特殊符号,MySQL 8.0 的
validate_password插件会拦截弱密码 -
GRANT语句末尾的分号不能漏,否则权限不生效
ECS安全组和MySQL绑定地址要双向收紧
很多人只记得在阿里云控制台放行 3306 端口,却忘了 MySQL 自身默认只监听 127.0.0.1。结果是:安全组开了,MySQL 拒绝所有外部连接,连自己都连不上。
解决方法是改 /etc/my.cnf:
bind-address = 0.0.0.0<br># 或更安全的写法:<br># bind-address = 172.16.0.10 # 填ECS内网IP
但必须同步做两件事:
- 安全组入方向规则,把授权对象从
0.0.0.0/0改成具体应用服务器的公网或内网IP - MySQL 账号限定来源,比如
'appuser'@'172.16.1.5',而不是'appuser'@'%' - 重启服务:
systemctl restart mysqld,别只 reload 配置
最易被忽略的细节:MySQL 8.0 默认启用 caching_sha2_password 认证插件,老版本客户端(比如某些 Python pymysql 低版本)连不上,报错 Authentication plugin 'caching_sha2_password' cannot be loaded。真遇到,得在创建用户时显式指定插件:CREATE USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'YourPass123!';。











