MySQL 默认端口暴露公网极度危险,安全起点是禁止暴露:绑定地址设为127.0.0.1或内网IP,云安全组精确限制源IP,系统防火墙兜底,删除'root'@'%'等高危账号,严格按最小权限创建业务用户。

MySQL 默认端口暴露在公网等于裸奔
云服务器上装完 MySQL 就能连?错。默认 3306 端口一旦开放到 0.0.0.0/0,几小时内就会被扫描器盯上,暴力破解、弱口令爆破、甚至直接写入 Webshell 的案例非常普遍。
真正安全的起点不是“怎么加固 MySQL”,而是“不让它暴露”。必须确保:MySQL 绑定地址不是 0.0.0.0,防火墙和云平台安全组共同拦截非信任来源。
- 检查
my.cnf或mysqld.cnf中的bind-address—— 生产环境应设为127.0.0.1或内网 IP(如172.16.0.5),绝不能是0.0.0.0 - 重启后用
ss -tlnp | grep :3306验证监听地址是否已收缩 - 即使绑定了内网 IP,也必须配安全组 —— 因为云主机的网络栈在内核层之上,安全组是第一道过滤
安全组只放行跳板机或应用服务器的 IP
云厂商控制台里的安全组,本质是网络层 ACL,比系统防火墙更前置。很多人误以为“只开 3306 端口”就够了,其实关键在源 IP 范围。
典型错误:填 0.0.0.0/0 或 10.0.0.0/8 这类大网段;正确做法是精确到单个 IP 或最小 CIDR。
- 如果应用和 DB 在同一 VPC 内,优先用内网 IP + 安全组规则(例如:源
172.16.10.22,协议 TCP,端口3306) - 若需从本地调试,临时加一条规则,用你当前公网 IP(不是家庭宽带动态 IP,而是运营商分配的真实出口 IP),用完立即删
- 阿里云/腾讯云的安全组不支持域名或标签,别试图填
jump-server—— 只认 IP 或 CIDR - 注意安全组规则有顺序,拒绝规则要放在允许之后(部分云平台默认隐式拒绝)
iptables/nftables 不能省,它是最后一道本地防线
安全组可能被误配、被绕过(比如用了弹性公网 IP 直接绑定),或者你用的是轻量应用服务器这类不提供安全组的实例。这时候系统级防火墙就是兜底。
别依赖 MySQL 自身的账号权限做网络隔离 —— 它管不了连接建立前的 SYN 包。
- 用
iptables -A INPUT -p tcp --dport 3306 -s 172.16.10.22 -j ACCEPT放行指定 IP - 紧接着加
iptables -A INPUT -p tcp --dport 3306 -j DROP拒绝其他所有 - CentOS 8+/Ubuntu 20.04+ 默认用
nftables,等效命令是nft add rule inet filter input tcp dport 3306 ip saddr != 172.16.10.22 drop - 规则要持久化:
iptables-save > /etc/iptables/rules.v4或启用nftables.service
MySQL 用户权限必须按最小原则重置
很多被黑的实例,根源不是端口暴露,而是存在 'root'@'%' 这种万能账号。哪怕端口只对内网开放,一个高权限远程账号也等于把锁孔交出去。
重点不是“能不能连”,而是“连上来能干什么”。部署后第一件事就是清理用户表。
- 登录后执行
SELECT user,host FROM mysql.user;,删掉所有host是%的非必要账号 - 新建业务账号时,明确指定 host:
CREATE USER 'app'@'172.16.10.22' IDENTIFIED BY 'strong-pass'; -
GRANT SELECT,INSERT,UPDATE ON mydb.* TO 'app'@'172.16.10.22';—— 别用GRANT ALL,尤其别给DROP或FILE - 执行
FLUSH PRIVILEGES;生效,但注意:MySQL 8.0+ 大多数权限变更无需此命令
真正的难点不在规则怎么写,而在于谁来维护这些 IP 白名单 —— 应用扩容、跳板机轮换、CI/CD 临时接入,都会让静态 IP 规则迅速失效。自动同步机制(比如通过 Terraform 管理安全组 + Ansible 同步 iptables)比手动配置可靠得多,但多数小团队直接跳过了这步。










