
玩飞牛NAS的朋友八成在Docker部署Zerotier这件事上栽过跟头。容器起来了后台显示在线甚至Web管理页都能打开但你想通过SSH远程登录飞牛主机却一直卡在连接超时或者Permission denied。我一开始也以为是Zerotier没弄好反复重装容器、改网络模式折腾两天才发现问题根本不在Zerotier而在SSH的权限配置上。这篇文章就把我踩过的坑复盘一遍用三步把SSH权限理顺让飞牛DockerZerotier这条远程访问链路真正可用。适合刚在飞牛上部署完Zerotier、又恰好被SSH访问卡住的朋友对照操作。1. 部署前必须搞清的几个点Docker部署Zerotier与SSH访问的关系1.1 飞牛NAS上Zerotier容器的正确起法很多教程会让你直接docker run -d --name zerotier --networkhost zerotier/zerotier:latest但真要实现远程SSH访问还缺几个关键参数。飞牛的系统底层是Debian跑Docker时对/dev/net/tun的支持需要显式声明。我实测可用的启动命令是这样的docker run -d \ --name zerotier \ --restart unless-stopped \ --network host \ --device /dev/net/tun \ --cap-add NET_ADMIN \ --cap-add SYS_ADMIN \ -v /var/lib/zerotier-one:/var/lib/zerotier-one \ zerotier/zerotier:latest几个参数一个一个说--device /dev/net/tun是让容器能用TUN虚拟网卡缺了它Zerotier创建虚拟接口会失败--cap-add NET_ADMIN是给容器操作路由表的权限不然加入网络后数据包转发不起来--network host这一步尤其重要飞牛上如果用bridge模式Zerotier的流量要被NAT一次容易出现能连但速度不稳、甚至单向不通的情况。host模式让容器直接复用宿主机网络栈虚拟网卡挂在宿主机上这样Zerotier分配的IP直接就是飞牛主机的一个IPSSH访问逻辑最简单。注意如果你之前用普通bridge模式部署过先把它停掉删掉。不删干净会出现两个Zerotier实例抢网卡的情况后面怎么配都白搭。容器起来后用docker exec -it zerotier zerotier-cli join 你的网络ID然后在Zerotier后台把该设备授权。这一步大部分人都能做对问题往往出在“网络已经显示OK但SSH还是连不上”。1.2 访问链路拆解为什么SSH会卡在权限上我们不妨把整条访问链路拆开看。你的笔记本通过Zerotier客户端连入虚拟局域网后要访问飞牛NAS需要经过这么几步笔记本上的Zerotier虚拟网卡 → Zerotier网络路由 → 飞牛宿主机上的Zerotier虚拟网卡zt开头的接口→ 宿主机SSH服务sshd→ 系统账号认证。前面几段只要Zerotier管理后台显示在线基本都能通。真正容易出问题的是最后两段第一sshd是否监听在Zerotier网卡的IP上第二sshd是否允许来自Zerotier网段的用户登录以及账号的认证方式是否被卡住。很多默认安装的OpenSSH配置里设置了只监听具体地址或者干脆禁用了root登录加上密钥权限不对远端一连就是Connection refused或者Permission denied (publickey)。我把这类问题统称为“SSH权限配置问题”也是这篇文章要解决的核心。还要补充一个常见误解有人以为Zerotier容器起来后自己就拥有了一个“SSH通道”可以直接访问飞牛。其实Zerotier只负责把两台设备“拉进同一个局域网”至于飞牛上有没有SSH服务、SSH允许谁登录那是OpenSSH的管辖范围。所以Zerotier管通不通SSH管能不能进。两者是协作关系不是替代关系。1.3 实际操作前先备好这几样东西动手改配置之前务必确认以下三样东西就位不然容易改到一半失去访问能力。第一飞牛本地的终端入口。飞牛的Web管理界面自带“SSH终端”功能也可以接显示器键盘直接进命令行。这一步很关键因为远程SSH一旦改错你还能用本地终端救回来。没有这个兜底不建议直接改sshd_config。第二一台用于测试的远端设备。可以是手机、笔记本或另一台NAS装上Zerotier客户端并成功加入同一个网络。测试设备最好能跑命令行SSH客户端方便观察详细的握手日志。第三想清楚认证方式。短期排查建议先开密码认证确认链路通后再换密钥。长期使用建议只用密钥登录密码认证只在需要时临时打开。提前规划能省很多事不然一次“密码正确但登录被拒”就能让你怀疑人生。2. 三步搞定SSH权限配置核心操作2.1 第一步确认Zerotier网络通不通排除路由干扰别一上来就改SSH配置先确认底层网络是通的。在远端电脑上ping一下飞牛在Zerotier网络里的IP比如10.244.x.x。如果ping不通再看本地和飞牛的路由表。飞牛侧查看Zerotier虚拟网卡ip addr show | grep zt如果发现没有zt开头的接口说明容器里的tun设备没生效。检查一下宿主机上是否存在/dev/net/tunls -l /dev/net/tun如果不存在需要手动创建设备节点mkdir -p /dev/net mknod /dev/net/tun c 10 200 chmod 600 /dev/net/tun如果接口存在再看路由ip route | grep zt正常会有一条类似10.244.0.0/16 dev ztxxxx的路由。如果没有说明Zerotier容器没把路由配上或者容器内没启用IP转发。执行一下sysctl -w net.ipv4.ip_forward1 echo net.ipv4.ip_forward1 /etc/sysctl.conf改完重启Zerotier容器再查看路由。如果仍然没有多半是容器缺少NET_ADMIN权限回到1.1节重新用完整参数创建容器。ping通之后顺手测一下SSH端口是否可达。Linux测试工具用ncnc -zv 10.244.x.x 22如果22端口通了说明从远端到飞牛的TCP链路没问题问题锁定在SSH认证。如果端口不通继续往下看可能是sshd没在跑或者防火墙拦截了。2.2 第二步修正sshd_config与账号权限先确认sshd进程在跑systemctl status sshd飞牛系统一般叫ssh或sshd都是systemd管理。如果没启动直接启动systemctl start sshd systemctl enable sshd接下来编辑/etc/ssh/sshd_config。先备份这是铁律cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak然后逐项检查这几个参数Port 22 ListenAddress 0.0.0.0 PermitRootLogin yes PubkeyAuthentication yes PasswordAuthentication yes AllowUsers youruser建议先临时把PasswordAuthentication设为yes方便排查。确认能连上后再切成密钥登录。对于Zerotier场景最稳妥的做法是单独为虚拟网段加一条匹配规则。比如你的Zerotier网段是10.244.0.0/16可以在sshd_config末尾加Match Address 10.244.*.* AllowUsers youruser PasswordAuthentication yes这样外部物理网段走原来的强认证Zerotier网段单独放开安全性和便利性都能兼顾。注意Match块内的AllowUsers是追加还是覆盖OpenSSH的行为是如果全局AllowUsers和Match块内AllowUsers都存在那么登录用户必须同时满足全局和匹配块的限制。所以建议只用一种方式要么全局写要么Match里写避免逻辑混乱。改完后先检查语法sshd -t没有输出就代表配置没问题。然后重启服务systemctl reload sshdreload对已有连接影响小推荐reload。如果reload失败再restart。2.3 第三步重置密钥权限、重启SSH并验证如果你用的是密钥登录权限不对是SSH拒绝访问的头号原因。生成密钥这一步推荐在客户端做ssh-keygen -t ed25519 -C yournamezerotier然后把公钥传到飞牛上。手动复制也行cat ~/.ssh/id_ed25519.pub把输出追加到飞牛上对应用户的~/.ssh/authorized_keys里。如果ssh-copy-id可用直接ssh-copy-id -i ~/.ssh/id_ed25519.pub youruser10.244.x.x -p 22在服务器端检查密钥文件权限chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys如果是用root登录检查/root/.ssh的权限。另外私钥在客户端这边也要处理Linux/Mac上私钥文件权限必须为600或更严格Windows上如果用Bitvise或VSCode的Remote-SSH私钥路径不要放在有特殊权限的目录里最好放到用户目录下并确保当前用户能读。验证方法有两种。一种是远端执行ssh -v youruser10.244.x.x打开详细日志看到Authentication succeeded就算成功。另一种是在飞牛上实时看日志journalctl -u sshd -f连一次看一次哪里卡住一目了然。最常见的日志就是User youruser from 10.244.x.x not allowed because not listed in AllowUsers看到这句话就知道是AllowUsers没配好。3. 踩坑实录飞牛系统下最容易忽略的权限细节3.1 密钥权限不是越大越好0600/0700的讲究我在飞牛上遇到过一件怪事authorized_keys明明有内容权限也设成了600但SSH一直报Permission denied。后来用ls -lZ一看发现目录被SELinux上下文标记错了。飞牛虽然默认没开SELinux但如果你装了宝塔、或者手动启用过AppArmor目录上下文会乱。最直接的办法是关掉或调整SELinuxsetenforce 0当然正经做法是restorecon -R -v /root/.ssh把上下文恢复回去。试过之后密钥登录立刻生效。至于权限记住一个原则目录是700文件是600别信什么“为了省事就777”。SSH对权限非常敏感私钥或授权文件多一个组权限直接拒绝。另外家目录本身的权限也很重要如果用户家目录是775甚至777SSH同样会拒绝读取authorized_keys。标准做法chmod 755 /home/youruser chmod 700 /home/youruser/.ssh chmod 600 /home/youruser/.ssh/authorized_keys还有Windows用户容易忽略的一个点在Windows上生成或传输私钥后如果放开给Everyone可读用Windows自带OpenSSH连接时会直接报“UNPROTECTED PRIVATE KEY FILE”。解决方法是右键私钥文件 → 属性 → 安全 → 高级 → 禁用继承然后只保留当前用户的完全控制权限。3.2 容器与宿主机SSH端口冲突的处理另一种情况更隐蔽飞牛上本来跑着别的Docker容器占用了22端口或者你的Zerotier容器因为用了host网络把容器内的sshd绑到了宿主机的22端口上导致飞牛原生的sshd起不来。用ss -tlnp | grep :22看看到底是谁在监听。如果发现是某个Docker容器里的sshd而外部SSH连进来走的是那个容器的SSH那权限配置自然要在那个容器里做而不是宿主机。这个坑很容易让人绕远路。我建议在飞牛上把宿主机SSH端口改成一个不常用的高位端口比如22022然后Zerotier网络里访问也用这个端口。这样既能避开冲突又减少被扫描的风险。改法很简单sshd_config里改Port然后重启sshd别忘了防火墙放行。改端口之后飞牛自带的“远程SSH”功能可能也要同步更新端口设置否则在Web终端里点“SSH连接”还是会默认走22。这个问题我在飞牛0.8.x版本里遇到过改完端口后Web终端连不上后来找到系统设置里的SSH端口选项改成一致才恢复。3.3 防火墙与SELinux对Zerotier网卡的拦截飞牛系统自带防火墙ufw或者firewalld默认可能只放行了局域网和Docker端口Zerotier网卡的流量会被拦掉。如果你已经确认SSH配置没问题但远程还是连不上八成是防火墙。先看当前状态ufw status如果启用了加一条ufw allow from 10.244.0.0/16 to any port 22022 proto tcp用firewalld的话是firewall-cmd --permanent --add-rich-rulerule familyipv4 source address10.244.0.0/16 port port22022 protocoltcp accept firewall-cmd --reload别小看这一步我遇到过放行了22但没放行新改的22022结果折腾半天。另外如果Zerotier机器里的IP是IPv6还得检查ip6tables规则类似。很多Zerotier网络默认给设备分配的是IPv4但也有人启用了IPv6。IPv6的链路和IPv4独立端口测试一个通一个不通优先怀疑IPtables。SELinux方面飞牛默认是disabled但如果你在BIOS里开启了安全启动或者手动装过某些安全模块SELinux会变成enforcing。检查一下getenforce如果是Enforcing先临时放开SSH端口策略semanage port -a -t ssh_port_t -p tcp 22022如果连SELinux都不想用直接setenforce 0临时关掉定位问题后再决定是否永久关闭。3.4 别忘了PAM和Shell环境SSH登录失败还有一种容易被忽视的原因PAM配置错误或用户的Shell无效。sshd_config里有UsePAM yesPAM会读取/etc/pam.d/sshd。如果这个文件被第三方软件改坏即使密钥认证成功最终也会在session阶段被踢掉。日志里常常出现pam_unix(sshd:session): session closed for user youruser。排查时先看用户Shell存不存在grep youruser /etc/passwd正常应该是/bin/bash、/bin/sh或/usr/sbin/nologin等合法路径。如果被改成不存在的路径登录必然失败。修改方式usermod -s /bin/bash youruser另外家目录的owner必须是用户自己不能是root或其他人。用ls -ld /home/youruser查看如果owner不对执行chown -R youruser:youruser /home/youruser。4. 常见问题排查表与我的几点心得体会4.1 高频问题速查表这里整理一张表遇到问题直接对照现象可能原因处理方式ping通但SSH超时sshd未监听Zerotier网卡检查ListenAddress改成0.0.0.0或具体IPPermission denied (publickey)密钥权限太大 / 密钥不在authorized_keys重置密钥权限确认公钥正确User xxx not allowed because not listed in AllowUserssshd_config中AllowUsers限制在AllowUsers中加入用户或Match段Connection refusedsshd未启动 / 端口被容器占用启动sshd或改端口确认监听能登录但执行命令卡住MTU问题将Zerotier虚拟网卡MTU降为1400容器重启后虚拟网卡消失缺少tun设备或内核模块确认/dev/net/tun存在重装zerotier容器密钥登录提示UNPROTECTED PRIVATE KEY FILEWindows私钥权限太大禁用继承只保留当前用户完全控制密码正确但登录失败PAM配置错误 / Shell无效检查UsePAM、/etc/passwd中的Shell改完配置sshd起不来配置语法错误sshd -t检查恢复备份远端能连但Web终端连不上改端口后Web终端配置未同步在飞牛设置中同步SSH端口表格里最后一条也算经典虽然不属于SSH权限但经常和SSH访问问题一起出现。本机确实能看到zt网卡但路由不稳定MTU设成1400往往能解决一批“能ping通但SSH卡在协议协商”的怪问题。4.2 排查SSH问题的一把“瑞士军刀”遇到SSH问题不要盲目重启服务。我习惯按顺序用这几个命令基本三分钟内能定位80%的故障。第一在当前生效配置上找问题sshd -T | grep -E permitrootlogin|allowusers|port|listenaddress|passwordauthentication|pubkeyauthentication这个命令直接输出sshd实际生效的参数不会因为注释或行尾空格产生误解。比如你看配置里写了Port 22但实际监听的是22022那多半是服务器上有多个sshd_config或者被Include覆盖了。第二客户端详细连接日志ssh -vvv youruser10.244.x.x -p 22022三个v能看到密钥协商过程和认证方法。如果日志停在Next authentication method: publickey说明之前password被拒绝了检查PasswordAuthentication有没有开如果停在kex_exchange_identification说明连接建立后服务端没响应多半是MTU或防火墙问题。第三抓包确认数据是否到达宿主机。在飞牛上tcpdump -i ztxxxx port 22022 -nn远端发起SSH连接时如果tcpdump有输出说明Zerotier链路正常如果没有说明数据根本没到飞牛这一层问题出在Zerotier路由或授权。这个命令能直接切断“Zerotier问题”和“SSH问题”的争论。4.3 几条保命建议第一改sshd_config前先备份。不要嫌麻烦一个空格错误就可能导致sshd拒绝启动。我在生产机器上因为多写了一个ListenAddress后面的空格直接SSH全挂最后是靠物理终端救回来的。第二飞牛的Web终端和本地物理终端都能进系统但Web终端在SSH没挂的时候才能用。建议在改SSH配置前先确认自己能通过飞牛自带的“SSH终端”功能连上主机否则远程改坏了你连上去修复的通道都没有。第三Zerotier后台的“Managed Routes”里如果需要跨网段访问一定要写对网段比如10.244.0.0/16 via 10.244.0.1。写错会导致远端设备认为飞牛在另一个子网SSH直接不可达。第四定期清理~/.ssh/authorized_keys里不用的公钥。我在公司内部维护过几台飞牛时间一长里面全是离职同事的公钥既不安全又容易让自己被误伤。建议改成AuthorizedKeysCommand配合LDAP或HTTP接口管理不过这是后话了先把单机跑通再说。其实我现在的习惯是Zerotier网络里只跑一个端口比如把飞牛的SSH映射成一个固定端口然后在sshd_config里用Match块限定来源IP再配合fail2ban稳得一批。一开始觉得SSH权限配置是个小事情但被它卡了两天后发现这里面藏着的是对Linux用户体系、PAM、SELinux、systemd的一个综合理解。把这套理顺之后再玩NAS上的各种容器远程访问基本不会再遇到无头苍蝇式的排查了。最后分享一个检查小技巧在飞牛上执行sshd -T | grep -E permitrootlogin|allowusers|port|listenaddress能直接看到当前生效的SSH配置不用猜。遇到SSH问题先跑这条命令比翻文档快多了。希望这篇能帮你少走弯路早点把Zerotier这条链路玩起来。