王博士 Dr. WANG

给自己的服务器装上 Tailscale,打通 Mac / Windows / Linux / iPhone 的共享文件夹

为什么会有这篇文章:一个”随时随地接着干”的需求

先说这件事的起点。我长期用 DeepSeek Harness(dsh) 干活,最大的诉求是:

随时随地都能用上它,而且各个端要同步。

于是我干脆在服务器上装了一个 dsh,把所有 dsh 项目统一放到服务器的同一个目录下。这样我只需远程登录服务器的 dsh,就能继续各种工作,而其他任何设备随时看到的都是同一份文件——不用再折腾”哪台机器是新的”这种问题。

有了这个”工作台在服务器上”的基础,跨设备共享一个文件夹就成了自然而然的下一件事:把这一台常开的服务器变成家里所有设备都能读写的中枢。下面的技术方案就是围绕这个需求展开的。

最近把家里一台常开的 Linux 服务器接入了 Tailscale,并用它搭了一个能在 Mac、Windows、Linux 和 iPhone 之间互通的共享文件夹。整个过程不算复杂,但中间踩了几个坑(尤其是防火墙把内网访问也挡了),这里把完整流程和踩坑记录整理出来,方便以后复用。

为什么选 Tailscale + Samba

需求很简单:家里有几台设备,想有一个统一的文件夹,谁改都能实时同步到同一份数据。方案对比下来:

  • Tailscale(方案 A 的网络层):基于 WireGuard 的点对点 VPN,把散落在各处的设备组成一个加密的 tailnet(虚拟局域网)。没有公网 IP 也能异地访问、流量全程加密、自动打洞。
  • Samba(SMB)(文件层):Mac、Windows、Linux、iOS 全都原生支持 SMB 协议,一台中央服务器存一份数据,三端挂载读写,最省心。

Syncthing 每端各存一份、自动双向同步,有离线副本的优点,但占多份空间;对”共用一份公共文件夹”的场景,Samba 中央共享更直接。

第一步:给服务器装 Tailscale

1. 安装

官方提供了一个安装脚本(Ubuntu / Debian 系):

curl -fsSL https://tailscale.com/install.sh | sh

装完启动守护进程并查看版本:

sudo systemctl enable --now tailscaled
tailscale version

2. 认证登录(两种方式)

方式一:交互式登录:直接 sudo tailscale up,会打印一个一次性链接,浏览器打开登录你的 Tailscale 账号即可。

方式二:使用预共享认证密钥(推荐,可脚本化):在 Tailscale 控制台「设置 → 密钥 → 生成认证密钥」拿到 tskey-auth-...

sudo tailscale up --auth-key=tskey-auth-你的密钥

登进去之后 tailscale status 就能看到这台服务器,以及 tailnet 里的其他设备:

100.66.124.116   ejiayan           powerpk4342@   linux
100.114.167.35   iphone-15-plus    powerpk4342@   iOS
100.90.112.30    jerry             powerpk4342@   windows
100.103.186.34   powermacbook-pro  powerpk4342@   macOS

认准服务器分配的 tailnet IP(这里是 100.66.124.116),后面挂载全靠它。

第二步:在服务器上部署 Samba 共享

1. 安装 Samba

sudo apt-get install -y samba smbclient

2. 建立共享目录

sudo mkdir -p /srv/share
sudo chown ubuntu:ubuntu /srv/share
sudo chmod 2775 /srv/share

3. 编辑 /etc/samba/smb.conf

追加一个共享段(共享名 share,指向上面那个目录):

[global]
   workgroup = WORKGROUP
   server string = %h server (Samba, Ubuntu)
   server role = standalone server
   log file = /var/log/samba/log.%m
   max log size = 1000
   server min protocol = SMB2_10

[share]
   path = /srv/share
   browseable = yes
   read only = no
   writeable = yes
   public = no
   valid users = ubuntu
   create mask = 0664
   directory mask = 2775
   force user = ubuntu
   force group = ubuntu

4. 设置 Samba 用户密码

Samba 有自己独立的密码库,系统用户要单独 smbpasswd 一下才能用于登录共享:

sudo smbpasswd -a ubuntu

5. 重启并验证

sudo systemctl enable --now smbd
sudo systemctl restart smbd
smbclient -L 100.66.124.116 -U ubuntu

能看到 share 这个共享,就说明服务器端 OK 了。

踩坑一:SMB 只监听了 127.0.0.1

一开始为了”只允许 tailnet 访问”,我在配置里加了 bind interfaces only = yes + interfaces = tailscale0。结果 ss -tlnp 一看,smbd 只绑到 127.0.0.1,外网/局域网全都连不上。

原因是 tailscale0 是 POINTOPOINT 且 /32 的点到点接口,Samba 按接口名或按 IP 绑定这类接口不可靠。解决办法:让 smbd 正常监听 0.0.0.0(所有接口),再由防火墙控制谁能访问 445 端口,而不是让 smbd 自己绑接口。

第三步:用防火墙把 SMB 限定到 tailnet

Ubuntu 这里用的是 nftables,在 ip filter INPUT 链最前面插一条规则:只放行来自 tailnet 网段和内网的 SMB,其余一律 drop:

sudo nft insert rule ip filter INPUT ip saddr != { 100.64.0.0/10, 127.0.0.0/8 } tcp dport { 139, 445 } drop
  • 100.64.0.0/10:Tailscale 默认分配的 CGNAT 网段(所有 tailnet 设备 IP 都在这个范围)
  • 127.0.0.0/8:本机回环,允许本地测试

nftables 规则重启后不持久,我用一个 systemd oneshot 开机服务在启动时重新插入,并写成幂等(先删旧的再插,避免每次开机累积重复规则)。

第四步:各端挂载

Mac(访达)

访达 → 前往 → 连接服务器(Cmd+K)
smb://100.66.124.116/share

Windows(映射网络驱动器)

\\100.66.124.116share
# 或命令映射成盘符 Z:(开机自动重连)
net use Z: \\100.66.124.116share /user:ubuntu /persistent:yes

Linux

sudo apt-get install -y cifs-utils
sudo mkdir -p /mnt/share
sudo mount -t cifs //100.66.124.116/share /mnt/share 
  -o username=ubuntu,password=你的密码,iocharset=utf8,vers=3.0

iPhone

iOS 自带的「文件」App 原生支持 SMB:浏览 → 右上角「⋯」→ 连接服务器,填 smb://100.66.124.116/share,选「注册用户」,输入 ubuntu 和密码即可,不用装第三方 App。iOS 的连接是”按需”的,浏览侧边栏里会保留这个服务器入口。

踩坑二:内网 IP 反而连不上

所有设备都连好后,有一台 Windows 通过内网 IP\\192.168.1.120share)却连不上。排查后原因正是那条防火墙规则:它只放行了 tailnet 网段和回环,而内网的源地址(192.168.1.x)不在放行范围,被 drop 了。

解决办法:把内网网段也加进放行列表:

sudo nft insert rule ip filter INPUT ip saddr != { 100.64.0.0/10, 192.168.1.0/24, 127.0.0.0/8 } tcp dport { 139, 445 } drop

这样同局域网设备能用 192.168.1.120 访问,tailnet 异地设备继续用 100.66.124.116。注意:放行内网意味着同一 WiFi 下所有人都能尝试连(但还是要密码),有不信任设备可以再收紧到只放行固定 IP。

总结

  1. Tailscale 用认证密钥一键接入,服务器拿到 tailnet IP。
  2. Samba 承载共享,三端 + iPhone 原生协议无需装客户端。
  3. smbd 对点到点接口绑定位不可靠 → 用 nftables 防火墙控流量,并写成开机自启。
  4. 防火墙记得把”内网网段”一起放行,否则内网反而连不上。

至此,一台服务器 + 一套 Samba,Mac / Windows / Linux / iPhone 都能读写同一个文件夹,家里家外都能通过 tailnet 加密访问。以后可以继续叠 Syncthing 做多端本地同步,或加子网路由器把整段内网都纳入 tailnet。