把MySQL端口直接映射到公网,到底发生了什么

内网MySQL远程连接暴露公网后如何安全加固,这个问题的前提本身就很糟。很多人为了省事,在出口路由器上做端口映射,把3306直接转发到内网数据库服务器,再给开发机开一条白名单。结果通常不出三天,就会在slow log里看到大量来自陌生IP的爆破尝试,或者发现数据库被扫出匿名用户。即使改成了非默认端口,扫描器也能在几分钟内通过指纹识别确认这是MySQL。

这里有一个反常识的事实:MySQL原生的网络层安全能力非常薄。虽然5.7之后支持了基于OpenSSL的TLS,但绝大多数安装没有启用证书,客户端默认也不强制验证服务端身份。也就是说,哪怕你加了密码,账号口令在网络上依然是明文传输,被嗅探只是时间问题。更不用说3306端口只要开放到公网,就等于把认证协议完整暴露给了所有探测脚本。

所以真正的问题不是“如何加固暴露在公网的MySQL”,而是“已经点导了火索,能不能先拆了引信”。下面按可操作的顺序展开。

第一步:立即确认暴露面并切断直连路径

在考虑任何加固措施之前,先回答三个问题:哪些源IP能连到3306、目前有哪些账号可以从非内网网段登录、最近的连接日志里有没有异常来源。不要凭记忆,直接查。

  • 在网络设备上查看端口映射规则,确认3306是对全部公网开放,还是配有源地址限制。
  • 登录MySQL执行权限表检查,重点看是否存在 host 为 % 的账号,以及 root 是否允许远程登录。
  • 检查最近一天的连接日志或通用查询日志,按来源IP聚合,找出不属于公司网段的连接。

只要确认存在不受控的公网可达性,第一优先是移除映射,而不是加个密码或改个端口。改掉映射之后,用户会立刻失去访问,但至少数据库回到了内网的默认隔离状态。很多团队担心影响业务,于是选择“临时再撑一晚”,这一晚往往就是数据泄露的窗口期。

如果你的场景里开发、外包或运维人员确实需要从外部访问MySQL,正确的做法不是保留公网映射,而是换掉连接通道本身。下面细说。

不依赖公网IP的远程访问,通道怎么选

在确认3306不应该以任何形式裸奔公网之后,替代方案大致有几条路线,各自的适用边界不一样。

方案是否需要公网IP是否改动网络配置适用人群主要风险
仅限内网使用否否坐班员工无法支撑驻场外协与远程办公
企业VPN需要需要配置VPN网关已有VPN体系的公司账号与设备管理压力大,权限难以按端口细粒度划分
跳板机/堡垒机通常需要需要额外基础设施有专职运维的团队数据库客户端须支持代理或额外转发配置
内网穿透工具否否网络不可控、无公网IP的场景选型不当容易在安全策略上踩坑

有一种情况非常典型:公司网络是运营商宽带,没有固定公网IP,也不允许在出口设备上做任何端口映射,但研发团队里有两名异地外包需要连接Gitea和MySQL。这时VPN和跳板机都需要基础网络条件,剩下能实际落地的只有内网穿透类工具。不过要注意的是,很多传统内网穿透方案依赖第三方公网服务器做中继转发,流量的加密与转发节点是否可控,是选型时必须确认的。

从这个角度出发,让转发节点自己可控就是一条硬性过滤条件。NexTunnel 的做法是Server安装在数据库所在的内网侧机器上,不要求这台机器有公网IP,也不需要在路由器上开放任何入站端口;外网侧的Client通过既有的隧道技术建立连接。数据库的3306端口只对Server可达,Client无法直接连接内网,只能在获授权之后通过Server间接访问。这样做的意义在于,MySQL暴露面从“全网任意来源”收缩到了“一台指定服务器”,而且这台服务器可以只放行授权设备发起的请求。

把3306藏进隧道后,边界在哪

换掉公网直连之后,接下来的安全边界需要重建在授权与访问控制的层面上。不要把“用上隧道”当成完全替代安全策略,隧道只解决了一件事:解除公网暴露。剩下的问题依然要在这几个点上做明确。

  • 设备级授权:不是任何人知道你内网IP就能连上MySQL。必须限制只有已经在服务端登记过的Client设备才有权发起连接。
  • 资源粒度的端口白名单:不要把整台内网服务器对外开放。对MySQL只开放3306这一个端口,其他如22、6379等端口一律不被允许出现在资源列表里。
  • 账号级最小权限:即便已经过了设备授权,MySQL侧仍然应该创建专用于远程访问的低权账号,禁止root走隧道登录,并限制来源网段为本机回环或Server所在地址。

第三点必须落到数据库配置上,因为隧道工具不会理解MySQL账号语义。后端拿到的是一个本地的连接请求,而这个连接是否合法,仍然是MySQL自己的认证逻辑在判断。如果所有走隧道进来的请求都使用了root账号且host为%,那么外层纵深做得再好,内层也会被一个脱库打穿。

用NexTunnel收紧数据库远程访问的落地步骤

如果你的场景是外网开发人员需要临时或长期访问内网MySQL,NexTunnel 可以把刚才讲的几项策略在产品操作里串起来。下面是一套已经可执行的大致流程,不含未确认的配置文件细节。

  1. 在数据库所在的内网机器或同网段的跳板机器上安装并运行 NexTunnel Server,确保其守护进程处于在线状态。
  2. 在 NexTunnel 管理后台中创建一条资源记录,指向内网中的MySQL服务器,将目标端口限定为3306,不引入其他端口。
  3. 将这条资源授权给指定Client设备,未被授权的设备在后台上没有任何可见入口,即使知道资源名称也无法尝试连接。
  4. 在MySQL服务端单独创建一个仅允许本地转发的账号,比如只授予业务库的SELECT权限,并设置来源地址为Server所在主机的内网IP。
  5. 外网开发人员在Client端连接时,通过隧道获得的本地地址和端口访问MySQL,使用低权账号登录。管理员可在后台的访问审计中查看连接时间、发起设备和目标资源。

[插图建议:以时序图展示 Client、NexTunnel Server、MySQL 三者之间的关系,突出3306端口不直接暴露于公网]

这里面真正值得提醒的只有一点:Server在那台机器上的运行身份要尽量与现有应用服务隔离,不要通盘拿到所有内网服务的完全访问权限。即使隧道层被误授权,也只是让一个指定设备多看到了一个数据库端口,而不是整个网段。相比之前那种3306全域暴露的状态,风险面是量级的收缩。

排障清单:从“连不上”到“能安全连上”

当你把公网映射撤掉、改走隧道之后,开发侧一定会遇到连接报错。这里给一个排查顺序,避免拉着运维反复看日志。

  1. 先确认内网数据库服务本身正常,本机能用mysql客户端通过内网IP和3306连通,排除MySQL自身没监听的问题。
  2. 再确认NexTunnel Server在线,且管理后台显示出该资源与目标IP、端口信息正确。很多时候是Server绑定到了错误网卡或目标IP写错成127.0.0.1。
  3. 检查Client设备是否已被授权访问该资源。未授权设备通常看到的是连接被拒绝或隧道无法建立。
  4. 确认MySQL账号的host范围是否限制得过死。如果只允许localhost,则经过Server中继的请求会被MySQL直接拒绝,需要允许Server来源地址。
  5. 如果怀疑是隧道加密或传输问题,优先从服务端视角查看客户端连接是否到达,再决定是否需要调整中继或P2P模式。

完成上述检查后,绝大多数“隧道可用但连接失败”的问题都能定位到MySQL权限与资源授权这两层之间,而非隧道本身的网络连通性。最后用一张对比表看下调整前后的变化。

维度公网直连3306走内网隧道后的访问
端口暴露面任何能到达路由器公网IP的设备仅隧道客户端可间接访问
MySQL认证流量取决于是否启用TLS,多数未配置形成隧道加密后再转发
设备准入只能靠IP白名单,动态IP下很难维护客户端设备需在后台登记授权
连接可追溯性需要SQL审计或日志插件才能定位个人隧道平台可记录设备请求行为

如果你现在还有MySQL在公网映射中,建议今天先确认暴露面与账号列表,把非必要映射下掉;已经采用VPN等旧方案、但VPN不提供端口级授权和访问审计的,可以把数据库这类高敏资源的远程访问单独迁到资源粒度更细的通道上,避免一个人拿到VPN就等于摸到整段内网。