我去年给一台群晖 DS920+ 装了 MySQL 和 phpMyAdmin,当时的出发点很简单:手上有几套小项目的数据要统一管理,不想每次都打开电脑进桌面版工具,平时用浏览器点点就能维护库表结构。真正被卡住的,是后面的远程访问——人在外面的时候,想安全地看一眼数据库,结果家里宽带根本分不到公网 IP,路由器上做端口映射也没有意义。后来把方案拆开做,发现“无需公网 IP”这件事并没有想象中那么玄乎,关键是把访问路径梳理清楚。这篇帖就把我当时从 Docker 部署到远程访问的全过程整理出来,重点覆盖群晖 DSM 7 环境的操作习惯、QuickConnect 与 IPv6 两条免公网 IP 的访问姿势,以及一批我实际踩过的坑。
1. 为什么没有公网 IP 会让远程访问变得麻烦
先说结论:没有公网 IP 的核心问题是“外面找不到你”。
国内不少家宽用户拿到的是一个运营商大网内部的私有地址,比如 100.64.x.x 这类 CGNAT 地址段。路由器的公网口是这个地址,你的 NAS 在局域网里是 192.168.x.x,中间隔了两层网络地址转换。就算你在路由器里把 3306 端口映射出去,外部客户端连过来的请求根本到达不了路由器——因为运营商那一层没有给你留独立的公网 IPv4 出口。
这种情况不是个例,很多城市的新装宽带默认都这样。于是大家一提到远程访问 NAS,第一反应就是“得有公网 IP”,否则就只能局域网里用。
但实际解决办法不止一条。群晖自己就有 QuickConnect 这套官方中转机制,可以让你在外网通过一个固定的 ID 连回 DSM,全程不需要你在路由器上做任何端口映射。另外,如果你运营商分配了 IPv6 地址,那又是一条完全不同的路:设备自己就有公网 IPv6 址,外部只要能解析到这个地址,就能直接建立连接,不需要公网 IPv4。
所以把远程访问这件事做好的第一步,是先搞清楚你手里有哪些可用资源:
- 有没有公网 IPv4(哪怕动态 IP 也行)
- 有没有 IPv6 地址
- 愿不愿意依赖群晖官方的 QuickConnect 中转
我自己的情况是 IPv4 完全没有,运营商只给了 IPv6。所以最终方案是 QuickConnect 走 Web 管理,IPv6 走数据库客户端直连。两条路配合,基本覆盖了日常所有远程操作场景。
2. 动手前先想清楚:你要连的是 Web 页面还是数据库端口
远程访问 MySQL 这个需求,拆开来看其实是两件不一样的事,很多人没细想就直接去开端口,后面才出问题。
第一种:远程打开 phpMyAdmin 的 Web 管理页面。这个本质上是在访问一个 HTTP 服务。你需要在浏览器里输入一个 URL,然后登录进去,看看表结构、跑几条 SQL、导出数据。操作界面和本地用的时候一模一样。
第二种:用 Navicat、DBeaver 或者命令行 mysql 客户端来连接 3306 端口。这是数据库客户端协议连接,不是浏览器能搞定的。它走的是 MySQL 自己的 TCP 协议,和你网页上 phpMyAdmin 的访问方式完全不同。
两种方式对应到网络配置上,差异非常大:
| 访问形态 | 工具示例 | 本地预览地址 | 远程能否走 QuickConnect |
|---|---|---|---|
| Web 页面 | phpMyAdmin | http://NAS_IP:8081 | 可以,QuickConnect 可中转 HTTP 页面 |
| 数据库协议 | DBeaver / Navicat / mysql CLI | NAS_IP:3306 | 不可以,QuickConnect 不中转 MySQL TCP 协议 |
为什么要强调这个区别?因为群晖 QuickConnect 能帮你转发的,基本上限定在 DSM 的 Web 相关服务范围里。你通过 QuickConnect 登录 DSM 后,能在浏览器里打开套件页面,但 QuickConnect 不会替你转发一个原始 TCP 的 3306 端口。也就是说,如果远程访问目标是“打开 phpMyAdmin 网页”,用 QuickConnect 很合适;如果目标是“用数据库客户端直连 3306”,那就得考虑 IPv6 或者其他组网方式。
我当时习惯是:日常管理用 phpMyAdmin 网页端,临时跑数据迁移或者要导出大数据量时,才用数据库客户端走 IPv6 直连。两种方式互补,没有必要只押在一条路上。
3. 本地先跑通:群晖上容器化部署 MySQL + phpMyAdmin
远程访问的前提是本地已经把服务跑起来。群晖 DSM 7 之后的容器方案叫 Container Manager,其实就是 Docker 的图形化界面。如果你手头的系统还是旧版 Docker 套件,操作逻辑也差不多,只是入口名字不同。
我这里采用 docker-compose 的方式组织,因为 MySQL 和 phpMyAdmin 天然需要两个容器配合,compose 能把它们放在同一个虚拟网络里,互相用服务名通信,省去写死 IP 的麻烦。
3.1 项目目录与 compose 文件准备
在 NAS 的共享文件夹里创建一个目录,例如/docker/mysql-stack。然后新建一个docker-compose.yml,内容可以参考下面这份:
version: "3" services: db: image: mysql:8.0 container_name: syno-mysql restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: "YourRootPass_2024" MYSQL_DATABASE: appdb MYSQL_USER: appuser MYSQL_PASSWORD: "AppUserPass_2024" command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_unicode_ci - --default-authentication-plugin=mysql_native_password volumes: - /volume1/docker/mysql-stack/data:/var/lib/mysql ports: - "3306:3306" pma: image: phpmyadmin:latest container_name: syno-pma restart: unless-stopped depends_on: - db environment: PMA_HOST: db PMA_PORT: 3306 PMA_ARBITRARY: 0 UPLOAD_LIMIT: 256M ports: - "8081:80"这里有几点操作层面的取舍值得展开说明。
MySQL 的 data 目录必须映射到 NAS 存储空间里。不映射的话,容器一删,数据全没。我把数据放在/volume1/docker/mysql-stack/data,和 compose 文件放在一起,备份的时候直接打包这个文件夹就能拿到全部数据库。
default-authentication-plugin=mysql_native_password是老 MySQL 客户端兼容旧认证协议的需求。phpMyAdmin 新版和 MySQL 8 默认的 caching_sha2_password 配合没问题,但如果你的远程工具比较老,建议保留这个参数,兼容性广一些。
phpMyAdmin 里的PMA_HOST一定要写成db,这是 compose 网络内部的服务名,不能写成127.0.0.1,否则容器内部解析不到 MySQL 地址。很多新手在这里栽跟头。
3.2 在 Container Manager 中导入项目
在 DSM 的 Container Manager 里,左侧找到“项目”,点击“新增”。名称随意,比如mysql-stack。路径选择刚才创建/docker/mysql-stack目录,软件套件选择“使用现有 docker-compose.yml”,然后下一步会直接读取到文件内容。应用之后,系统会自动拉取镜像、创建网络、启动容器。
如果你的 DSM 是 Docker 套件的老版本,操作稍微不同:先手动创建两个容器,网络选择桥接,MySQL 容器先起,然后 phpMyAdmin 的PMA_HOST填 MySQL 容器的内网 IP,可以通过docker inspect查。这个我试过,能用,但维护麻烦,不建议长期用。
3.3 启动后的例行验证
容器起来之后,不要急着去搞远程访问,先在本地确认几个关键点。
浏览器访问http://NAS_IP:8081,能看到 phpMyAdmin 登录页。用 compose 里配置的appuser登录,能进去就说明 Web 层没问题,数据库连接正常。
再用命令行验证一下 MySQL 端口监听是否正常:
docker exec -it syno-mysql mysql -uappuser -p能进 MySQL 命令行,说明容器内部服务正常。接下来看一下端口从宿主机是否能访问:
telnet 127.0.0.1 3306能看到 MySQL 的版本 banner 信息,就说明端口映射生效了。这一步虽然基础,但能帮你把“容器问题”和“网络问题”快速区分开。
4. 免公网 IP 的访问,收拢成两条最可行的路线
本地跑通之后,进入正题:如何在没有任何公网 IPv4 的前提下,从外部访问这套 PHP 服务。我的经验是两条路线搭配使用,不要只盯着一根稻草。
4.1 路线一:QuickConnect 官方中继,适合 Web 管理场景
QuickConnect 是群晖官方提供的远程连接服务。它不需要你在路由器上做任何端口映射,也不要求有公网 IP。原理上,你的 NAS 开机后会主动和群晖的中继服务器保持一条长连接,外网客户端访问时,也是先连到中继服务器,再由中继把请求安全地引导到你的 NAS 上。整个过程你只要登录同一个 Synology 账号就行。
配置步骤:
- 打开 DSM 的“控制面板 > 外部访问 > QuickConnect”。
- 启用 QuickConnect,登录 Synology 账号。
- 设定一个专属的 QuickConnect ID,比如
my-nas-database。之后你在外面访问的地址就是https://quickconnect.to/my-nas-database。 - 同步勾选“启用 DSM 的 QuickConnect”,确保 DSM 本身能远程打开。
但这个配置默认只能打开 DSM 主页,phpMyAdmin 容器跑在 8081 端口,QuickConnect 并不会自动把端口暴露出去。需要在 DSM 里再补一个“入口映射”。
在“控制面板 > 登录门户 > 高级”标签页里,找到类似“自定义入口”或“别名设置”的功能。新增一条规则,把某个路径或子域名映射到http://127.0.0.1:8081。不同的 DSM 版本界面文字略有差异,但核心思路就是:你希望在 QuickConnect 域名后面拼上什么路径,最终就把这个路径转发到哪个本地端口。
这个功能在 DSM 里本身是给套件用的,现在用来转发容器端口,效果一样。做完之后保存,然后退出 DSM 后台,用手机流量打开https://quickconnect.to/你的ID/phpmyadmin,如果能看到 phpMyAdmin 登录页,就成了。
要注意的是,QuickConnect 这套机制适合“偶尔打开网页看一眼”的场景。因为它经过群晖中继服务器,网络路径比你直连要长一截,大量的数据导出导入时会明显变慢。但好处也很突出:不用在路由器上做任何配置,安全性由群晖统一负责,登录过程全走 HTTPS。
4.2 路线二:IPv6 地址直连,数据库客户端的正道
如果你的运营商像我家一样,只发了 IPv6 没给公网 IPv4,那其实你手里的设备是“有公网地址”的,只是这个地址是 IPv6 形式。手机流量现在基本都支持 IPv6,也就是说,只要配对成功,你可以从外面直接连回 NAS 的 3306 端口,不需要任何中转。
先确认 NAS 有没有 IPv6 地址。打开“控制面板 > 网络 > 网络接口”,选中你的 LAN 口,查看 IPv6 地址栏。如果显示类似240e:xxxx:xxxx:xxxx::xxxx的地址,那恭喜,你已经具备直连条件了。如果空着,去“网络 > IPv6”里把启用 IPv6 打开,获取方式一般选自动,DSM 会通过 SLAAC 或 DHCPv6 拿地址。
拿到 IPv6 地址后,从外网客户端测试连通性:
ping6 240e:xxxx:xxxx:xxxx::xxxx能通就继续。在 DBeaver 或 Navicat 的连接配置里,主机名直接填 NAS 的 IPv6 地址,端口 3306,协议选 MySQL,就能连上。客户端工具一般不需要额外设置,IPv6 地址带冒号,填进去即可。
这里必须提醒一个安全问题:IPv6 地址虽然长,但它全网可达。你开着 3306,就等于把这端口暴露在整个 IPv6 公网里。很多扫描器专门扫 IPv6 网段,弱口令的 MySQL 撑不了多久。
所以 IPv6 直连路线只建议用在有较强安全基础的前提下。下面第 5 章会展开说安全设置。
4.3 两条路线如何选
总结一下我的选择逻辑:
| 场景 | 推荐路线 | 理由 |
|---|---|---|
| 临时开网页维护库表 | QuickConnect | 配置最简单,手机浏览器直接访问,全 HTTPS |
| 用客户端跑 SQL、导数据 | IPv6 直连 | 直连性能好,不走中转,适合大数据量 |
| 只有 IPv4 没有 IPv6 | QuickConnect + 其他局域网工具 | 运营商没给 IPv6 时,客户端直连这条路走不通,只能靠中继 |
如果你的群晖是黑群晖或者别的 NAS 系统,QuickConnect 可能用不了,那远程访问这条路就会窄很多。这种情况一般得靠路由器上已有的 IPv6 或者额外自建组网工具解决,这里不展开。
5. 远程连 MySQL 的安全底线设置
数据库不是普通文件,远程暴露的风险比 NAS 套件大得多。别人拿到你 phpMyAdmin 的登录页,爆破字典一轮打过来,弱口令基本活不过一天。所以我把安全设置当作整个项目里最重要的一块,比远程配置优先级更高。
5.1 密码是第一道门,设置要注意几个细节
compose 文件里的 MySQL 密码是明文的,谁看到文件谁就能连数据库。对于个人 NAS 场景,至少要把密码改掉,并保证不低于 16 位。我的习惯是生成随机密码,用密码管理器存好,不手动编一个“好记”的密码。
MySQL 安装完成后,登录 root 账户,删掉默认的匿名账户:
DELETE FROM mysql.user WHERE user=''; FLUSH PRIVILEGES;然后确认 root 只允许从本地登录:
SELECT user, host FROM mysql.user;root 的 host 应该是localhost,不要是%。如果远程客户端想要一个管理账户,专门建一个新的,给它独立的授权范围,别拿 root 到处用。
5.2 MySQL 端口不要裸奔
默认的 3306 端口映射到宿主机后,任何能访问你网络的人都能瞄到这个端口。就算你设置了强密码,也不值得冒险。
如果走 IPv6 直连,DSM 的防火墙一定要启用。打开“控制面板 > 安全 > 防火墙”,新增规则,把 DSCP 或端口相关的设置控制好。规则示例:
- 动作:允许
- 协议:TCP
- 端口:3306、8081
- 来源 IP:只填你常用的远程 IPv6 地址或前缀
如果你远程设备 IPv6 前缀会变,可以写成/64前缀白名单,比自己手动加具体地址宽松一些,但总比全放开来得安全。
5.3 phpMyAdmin 尽量走 HTTPS
QuickConnect 本身就是 HTTPS 传输,不存在明文问题。但如果你用 IPv6 直连 8081 端口,这个端口默认是 HTTP 的,密码在网络上就是明文传输,非常不建议。
我实际操作中把 phpMyAdmin 的远程 8081 端口只限制在内网和可信 IPv6 范围,外包出去主要走 QuickConnect 那条 HTTPS 链路。这样即使密码不够强,至少不会被中间人截获。
5.4 定期检查登录日志
Docker 容器的日志里能看到连接记录。远程访问生效后,隔三差五去 Container Manager 里看一眼 MySQL 容器的日志:
docker logs syno-mysql --tail 50如果发现大量来自陌生 IP 的连接尝试,就需要重新评估防火墙规则是否太宽。这个习惯我保持了半年,期间拦掉了两轮来自 IPv6 扫描段的爆破,都是因为地址段白名单没写细。
6. 实测踩坑:从本地到远程最久卡住的几处
这部分内容最实用,都是我在配置过程中耽误过时间的地方。写出来帮大家少走弯路。
6.1 坑一:phpMyAdmin 登录报 1045 Access denied
第一次装好的时候,本地用 root 登录 phpMyAdmin 报 1045。排查了一圈,发现是 MySQL 8 默认的认证插件和 phpMyAdmin 某些版本不兼容导致的问题。
解决办法是在 compose 文件的 MySQL 启动命令里加--default-authentication-plugin=mysql_native_password,然后重建容器:
docker compose down docker compose up -d注意这个操作会重建容器,但数据卷还在,不会丢数据。重建后重新创建数据库用户,或者把已有用户改为mysql_native_password认证:
ALTER USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY '密码';6.2 坑二:远程客户端连接 3306 报 2003 错误
报 2003 的意思是客户端连不上服务端,不是密码错误。这种情况依次排查几个位置:
- 防火墙是否放行 3306。
- MySQL 容器是否成功映射端口,在 NAS 上执行
docker ps看端口列。 - MySQL 是否监听在
0.0.0.0。默认配置一般没问题,但如果你自定义过bind-address,要确认不是127.0.0.1。
我遇到的是防火墙优先级问题。DSM 防火墙规则默认是自上而下匹配,我在规则列表前面加了一条“拒绝所有”,结果把后面的放行规则全压住了。调整顺序之后立刻通了。
6.3 坑三:QuickConnect 页面打不开自定义入口
QuickConnect 域名能正常打开 DSM 首页,但拼上自定义路径后一直 404。
排查时发现,DSM 的“登录门户”高级规则里,Source 栏要配置成对应的 QuickConnect 地址,而不是留空。我当时留空了源地址,系统默认只对局域网生效,外部访问自然找不到入口。把源地址补全为 QuickConnect 的域名后问题解决。
另外,如果 DSM 开了双重验证,QuickConnect 登录后还要过一遍手机验证码。这个本来不是问题,但用脚本自动检查远程页面时会频繁被验证码卡住,后来我就把自动化检测改成走 IPv6 直连了。
6.4 坑四:重启 NAS 后 IPv6 地址变了
NAS 重启后,DHCPv6 或 SLAAC 重新分配地址,IPv6 地址可能变化,导致客户端配置里的旧地址失效,连接不上。
处理思路是给 NAS 在路由器里绑定一个固定的 IPv6 后缀,或者使用 DHCPv6 的固定 DUID 绑定。路由器设置了固定分配后,重启后地址能保持不变。如果路由器不支持,那就只能每次变化后去 DSM 后台看一眼在用的地址,改客户端配置,虽然麻烦但不至于无解。
最后再分享一个小建议
整个方案跑通之后,我把 3306 端口的全网络暴露最终关掉了。为什么?因为对我这种个人维护的小项目来说,直接用数据库客户端远程写数据的频率并不高,网页端 phpMyAdmin 已经能满足 90% 的需求,剩下那 10% 的场景,临时用 IPv6 放行一下,用完再关,比常年开着安心得多。
最后给准备照着做的朋友一个建议:先别急着折腾远程访问,把你本地这套容器栈的安全配置做扎实——强密码、独立管理用户、防火墙白名单、定期看日志,这些才是整个方案里最省心的长期保障。网络通路踩通了,远程访问反而就是一层窗户纸。