给自己的服务器装上 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。
总结
- Tailscale 用认证密钥一键接入,服务器拿到 tailnet IP。
- Samba 承载共享,三端 + iPhone 原生协议无需装客户端。
- smbd 对点到点接口绑定位不可靠 → 用 nftables 防火墙控流量,并写成开机自启。
- 防火墙记得把”内网网段”一起放行,否则内网反而连不上。
至此,一台服务器 + 一套 Samba,Mac / Windows / Linux / iPhone 都能读写同一个文件夹,家里家外都能通过 tailnet 加密访问。以后可以继续叠 Syncthing 做多端本地同步,或加子网路由器把整段内网都纳入 tailnet。