如何安全开放MySQL远程访问并防止公网暴露?

来源:网站运营作者:本地能跑头衔:程序员
导读:本期聚焦于本地能跑创作的《如何安全开放MySQL远程访问并防止公网暴露?》,敬请观看详情。远程连接MySQL时,只把bind-address改成0.0.0.0再放行3306端口,是否意味着业务可以正常访问了?从可用性角度确实如此,但从安全角度看,这等于把数据库服务直接摆到公网入口。攻击者通过端口扫描发现MySQL后,会尝试弱口令爆破或利用已知漏洞。相对稳妥的做法不是完全禁止远程访问,而是分层次收敛攻击面。本文从监听与防火墙配置、账户主机白名单、最小权限授予、强制SSL/TLS传输以及连接失败审计几个环节展开,结合可执行的SQL命令和配置文件片段,说明如何在不影响正常业务的前提下,把远程访问风险降下来。

开放MySQL远程访问,往往是为了让应用服务器、报表工具或运维脚本能够从其他主机连接数据库。但这个操作如果只停留在修改配置和放行端口,很容易把3306端口暴露到公网。端口一旦被扫描到,攻击者会尝试弱口令登录、枚举账户,甚至借助未及时修复的漏洞发起攻击。管理远程访问安全不是简单禁止外部连接,而是把监听范围、网络来源、账户权限、传输加密和异常行为监控逐层收紧。本文会围绕这些层面展开,给出适合生产环境的配置思路。

如何安全开放MySQL远程访问并防止公网暴露?

第一层:收紧监听地址与网络入口

MySQL是否对外提供服务,首先由监听地址决定。很多发行版安装后默认只监听127.0.0.1,这种情况下远程客户端根本无法建立TCP连接。但也有一些环境为了方便,把bind-address设置为0.0.0.0,甚至注释掉该项,导致数据库对所有网卡开放。检查当前监听状态可以先执行SHOW VARIABLES LIKE 'bind_address';,确认变量值。如果业务确实需要跨主机访问,应该把监听地址设置为内网网卡IP,而不是通配地址。例如应用服务器与数据库服务器同处192.168.10.0/24网段,配置文件可以这样调整。

[mysqld]
bind-address = 192.168.10.5
# 如需仅本机访问,保持 127.0.0.1 即可

监听地址只是第一道门,第二道门是主机防火墙。即使MySQL绑定到内网地址,如果防火墙对3306端口完全放行,任何能到达该网段的设备都可以尝试连接。更合理的做法是只允许业务子网或指定管理主机访问。以iptables为例,可以先允许来源网段,再默认拒绝其他来源的3306连接。防火墙规则需要根据实际部署调整来源地址,避免直接写0.0.0.0/0。如果业务必须从公网接入,优先考虑VPN或SSH隧道,而不是把数据库端口直接暴露给公网。

# 仅允许 192.168.10.0/24 访问本机 3306
iptables -A INPUT -p tcp -s 192.168.10.0/24 --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP

修改配置后需要重启MySQL服务,再用ss -lntp | grep 3306或netstat -lntp | grep 3306确认监听地址是否已经从0.0.0.0变为内网IP。有些运维习惯改变默认端口来降低扫描命中率,这可以过滤一部分批量扫描,但不能作为主要防护手段。端口变更只能降低噪音,真正能挡住攻击的还是来源限制和后续的账户策略。

第二层:用账户主机白名单替代泛匹配

MySQL的账户身份由用户名和来源主机共同确定,也就是说appuser从192.168.10.8登录与从任意主机登录,在权限系统中是两个不同账户。主机部分支持精确IP、通配符和子网掩码。很多远程访问风险来自使用'%'作为主机白名单,例如创建'appuser'@'%',这意味着任何一个IP都可以尝试用该用户名登录。只要密码足够弱,数据库就可能被拖走。因此,业务账户的Host列应尽量写成具体IP或受限网段,管理账户尤其不能使用'%'。

CREATE USER 'appuser'@'192.168.10.%' IDENTIFIED BY 'Str0ngPassw0rd!';
GRANT SELECT,INSERT,UPDATE,DELETE ON appdb.* TO 'appuser'@'192.168.10.%';

创建用户后还要检查权限是否膨胀。很多教程为了方便直接给ALL PRIVILEGES ON *.*,这样该账户可以访问所有库表,还能执行管理命令。对普通业务账户来说,按库、按操作类型授权才是正确做法。即便业务确实需要跨库读取,也应明确列出库名,而不是使用通配库。授权最小化不仅能降低被攻破后的损失,也能避免开发测试时误操作影响系统表。

对于已经存在的宽松账户,可以通过RENAME USER或重新创建来收敛Host范围。但要注意,RENAME USER只修改账户定义,不修改已授予的权限,所以如果权限本身过大,还需要执行REVOKE回收。管理员还应该定期查询mysql.user表,重点观察哪些账户的Host为'%',以及是否存在空密码账户。下面的语句可以快速列出普通用户及来源。

SELECT user, host, plugin
FROM mysql.user
WHERE user NOT IN ('mysql.sys','mysql.session','mysql.infoschema');

root账户尤其要限制来源。某些云镜像或快速安装脚本会生成root@'%',这是非常危险的配置。如果发现类似账户,应将其改回本地地址,或者直接锁定。远程管理数据库时,不应该让root从公网直连,而是通过SSH登录到数据库服务器后再使用本地连接,这样能把root暴露面降到最低。

-- 如果存在 root@'%',改回本地来源
RENAME USER 'root'@'%' TO 'root'@'localhost';

第三层:强制TLS传输加密并统一认证插件

即使来源IP和账户都做了收敛,如果密码和查询结果在网络上明文传输,依然可能被内网嗅探。MySQL支持TLS加密连接,服务端启用后,客户端与数据库之间的认证信息和查询数据都能被加密。全局强制开启可以在配置文件中设置require_secure_transport为ON,并指定CA、证书和私钥路径。证书可以用企业CA签发,也可以使用自签证书,但自签证书在生产环境需要客户端信任相应CA。

[mysqld]
require_secure_transport = ON
ssl-ca = /etc/mysql/certs/ca.pem
ssl-cert = /etc/mysql/certs/server-cert.pem
ssl-key = /etc/mysql/certs/server-key.pem

除了全局开关,还可以对单个账户强制要求SSL。例如对远程业务账户执行ALTER USER ... REQUIRE SSL;,这样即使用户密码被截获,登录过程也会因为缺少加密通道而失败。客户端连接串则需要开启SSL模式。不同语言的驱动参数不同,但核心都是要求服务端证书可被验证。连接后可以执行SHOW STATUS LIKE 'Ssl_cipher';确认当前连接是否已经进入加密状态。如果返回空值,说明连接仍然没有使用TLS。

ALTER USER 'appuser'@'192.168.10.%' REQUIRE SSL;
SHOW STATUS LIKE 'Ssl_cipher';

认证插件同样影响远程访问安全。MySQL默认的caching_sha2_password比旧版mysql_native_password更安全,但部分老旧驱动或工具可能无法兼容。遇到兼容性问题时,不应该简单把所有账户改回旧插件。正确做法是升级客户端驱动或使用支持新插件的连接库,并在内网环境统一标准。如果确实为了兼容必须使用旧插件,至少要把该账户限制在受控网段,并开启TLS,弥补旧插件在密码交换上的不足。

第四层:审计登录失败并控制连接频率

再严密的配置也需要通过日志验证效果。MySQL错误日志会记录认证失败事件,管理员应定期关注Access denied类信息。如果短时间内出现大量失败登录,通常意味着有人在尝试爆破密码。社区版可以通过连接控制插件CONNECTION_CONTROL实现失败次数限制和延迟惩罚。该插件会记录每个来源地址的连续失败次数,超过阈值后自动延迟后续连接请求,从而增加暴力破解成本。

INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so';
INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so';
SET GLOBAL connection_control_failed_connections_threshold = 5;
SET GLOBAL connection_control_min_connection_delay = 60000;

上述配置表示同一来源连续失败5次后,连接请求将被延迟至少60秒。阈值设置要结合业务场景,不要过低导致正常用户输错密码后长时间无法登录,也不要过高给了攻击者足够多的尝试窗口。Windows平台的插件文件后缀通常是connection_control.dll,Linux平台则是connection_control.so。安装后可以通过查询information_schema.plugins确认插件状态。

除了防爆破,还应该定期检查当前连接和空闲连接。执行SHOW PROCESSLIST;可以观察是否有异常来源、长时间运行的SQL或异常高并发。对于业务不活跃的连接,可以通过wait_timeout和interactive_timeout合理缩短存活时间,避免空闲连接被长期占用,也减少凭据泄露后被人利用的时间窗口。远程访问安全是一个组合策略,单靠某一项无法解决所有问题,只有网络、账户、加密和审计同时配合,才能把风险控制在可接受范围。

MySQL远程访问数据库安全权限管理修改时间:2026-09-25 02:22:16

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0925/61539.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。