加速外部访问NAS:无需域名建立tailscale derp中继服务
背景
对于NAS玩家,随时随地,而不仅仅是在家庭局域网内,访问自己的NAS是的普遍需求。
实际使用中,使用Tailscale实现设备间安全连接时,直连并不总是稳定可靠。为了提高Tailscale网络的稳定性和性能, 需要自建DERP中继服务器。
参考过的教程
本文与参考教程区别
- 教程1需要域名,本文无需
- 教程2需要付费的FinalSHELL工具,本文使用更广泛接受的VS Code。
- 包含了实践教程1、2过程中遇到的新问题和解决方法
- 用简化方法达成教程1、2中的部分步骤
- 非docker方案,无需docker修改和重新打包
前置准备
阿里云ECS Ubuntu 22.04 LTS
开始
使用VS Code连接到阿里云ECS
在本地计算机上,打开终端或命令提示符。
进入 SSH 配置文件所在的目录:
- 在 Windows 上,SSH 配置文件通常位于
C:\Users\<your-username>\.ssh\
目录下。 - 在 macOS 和 Linux 上,SSH 配置文件通常位于
~/.ssh/
目录下。
- 在 Windows 上,SSH 配置文件通常位于
打开或创建一个名为
config
的文件(如果该文件不存在)。可以使用任何文本编辑器打开该文件,如 VS Code、记事本等。在
config
文件中,添加以下内容:1
2
3
4Host myremotehost
HostName your-remote-host-ip-or-domain
User your-username
IdentityFile path/to/your/private/key- 将
myremotehost
替换为你想要给远程主机起的别名,可以是任何易记的名称。 - 将
your-remote-host-ip-or-domain
替换为远程主机的 IP 地址或域名。 - 将
your-username
替换为你在远程主机上的用户名。 - 将
path/to/your/private/key
替换为你的私钥文件的实际路径。
例如:
1
2
3
4Host myserver
HostName 192.168.0.100
User john
IdentityFile ~/.ssh/id_rsa- 将
保存
config
文件并关闭编辑器。在 VS Code 中,安装 “Remote - SSH” 插件(如果尚未安装)。
在 VS Code 中,打开命令面板(可以按
F1
或Ctrl+Shift+P
),然后输入 “Remote-SSH: Connect to Host”。在出现的列表中,选择你在
config
文件中定义的远程主机别名(如myremotehost
或myserver
)。VS Code 将使用你指定的私钥文件尝试连接到远程主机。如果连接成功,你将看到一个新的 VS Code 窗口,其中打开了远程主机上的文件夹。
现在,你已经成功使用私钥通过 VS Code 的 SSH Remote 插件连接到了远程主机。你可以在 VS Code 中编辑、保存和运行远程主机上的文件和项目了。
如果在连接过程中遇到任何问题,请确保:
- 私钥文件的路径是正确的。
- 私钥文件具有正确的权限设置(通常为
600
或400
)。 - 远程主机上启用了 SSH 服务,并且防火墙允许 SSH 连接。
如果问题仍然存在,你可以尝试使用 ssh -i path/to/your/private/key your-username@your-remote-host-ip-or-domain
命令在终端中手动连接到远程主机,以排查可能的问题。
安装tailscale
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
启动,然后授权加入tailscale网络
安装Golang
卸载旧版:sudo rm -rf /usr/local/go
。
在自己的本地主机上下载最新版Golang Download and install - The Go Programming Language。
在tailscale设置中启用Taildrop · Tailscale Docs,右键
在远程主机上运行 sudo tailscale file get .
,接收的文件在当前目录。
解压Go到相应目录:sudo tar -C /usr/local -xzf $HOME/go<最新版本号>.linux-amd64.tar.gz
配置Golang自动运行
sudo code ~/.profile
末尾粘贴以下代码配置GO的路径,并保存
1 | export GOROOT=/usr/local/go |
使新配置生效:sudo source ~/.profile
输入go version
,如出现版本信息,则配置成功。
安装 tailscale derp 服务
建立目录:sudo mkdir -p /usr/local/gopath/bin
分别输入并回车以下两行代码,设置go代理+安装
go env -w GOPROXY=https://goproxy.cn,direct
go install tailscale.com/cmd/derper@main
修改 derp 以跳过域名需求
通过 VS code 访问文件 /usr/local/gopath/pkg/mod/tailscale.com@v1.67.0-pre.0.20240510224123-fc1ae97e1037/cmd/derper/cert.go
如果你安装的tailscale版本、在profile中配置的go目录(tailscale derp下载在go 目录下面)不同,请做相应的修改。也可以使用VS Code搜索该文件。
对cert.go做如下修改并保存:
重新编译修改过的derp
切换到cert.go该文件的路径下
重新编译修改过的derp:go build -o /etc/derp/derper
在/etc/derp路径下检查derper以验证编译结果。
自签域名(不会被验证)
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout /etc/derp/derp.myself.com.key -out /etc/derp/derp.myself.com.crt -subj "/CN=derp.myself.com" -addext "subjectAltName=DNS:derp.myself.com"
这个命令生成了一个自签名的SSL/TLS证书,使用RSA算法和4096位私钥,有效期为10年。证书的主题和主题备用名称都设置为 derp.myself.com。生成的私钥和证书分别保存在 /etc/derp/derp.myself.com.key 和 /etc/derp/derp.myself.com.cn.crt 文件中。
配置修改后的Derp并启动
code /etc/systemd/system/derp.service
输入以下配置用于启动derp服务(已经配置了只允许tailscale 客户端连接 –verify-clients)
1 | [Unit] |
启用derp服务:systemctl daemon-reload
systemctl restart derp
检查derp状态systemctl status derp
设置开机自启systemctl enable derp
打开阿里云ECS所属的安全组的相应端口(比如示例中设置的33445)
网页中输入阿里云ip : “https://xxx.xxx.xxx.xxx:33445“ ,出现“Client sent an HTTP request to an HTTPS server.”字样则成功。
在tailscale控制台中启动配置好的derp中继
https://login.tailscale.com/admin/acls/file
1 | // Example/default ACLs for unrestricted connections. |
本地机器在命令行中运行tailscale netcheck
tailscale status
,看到自己的derp即成功。
可以通过tailscale ping xxx.xxx.xxx.xxx
判断流量路径。
在开始搭建之前,我们需要准备一台阿里云ECS实例,并且配置好VS Code的Remote-SSH插件,以便于远程管理服务器。接下来,我们将在ECS上安装Tailscale客户端,并配置Subnet Router和Exit Node,以实现不同的流量转发策略。
搭建DERP服务器的核心步骤包括:编译安装Derp可执行文件、生成自签名SSL/TLS证书、创建Systemd服务文件等。在这个过程中,我们需要安装Go编译环境,并且合理配置Derp服务器的各项参数,如监听端口、证书路径等。
完成搭建后,我们还需要在Tailscale管理控制台添加Derp节点,并在客户端连接该节点,以验证服务器的可用性。同时,我们还要学会如何检查Derp服务的运行状态,以及排查可能出现的问题,如服务无法启动、节点间无法连通等。
在实践过程中,我遇到了一些技术难点,例如:配置Go环境变量、生成兼容Derp的自签名证书、编写正确的Systemd服务文件等。通过不断尝试和查阅资料,我逐一解决了这些问题,并总结出了一套完整的搭建流程。
其他几种方法实现外网访问NAS及优缺点对比
Tailscale vs. Zerotier ONE
优势:
同为无需将自己的NAS暴露在公网上带来的方案,安全性均较高。
- 简单性: Tailscale更易于设置和使用,用户友好。
- 可能的性能优势:Tailscale 使用 WireGuard 协议,该协议以简单、高效、易于审计而闻名,这有助于其性能优势。这通常可以使 Tailscale 更快,特别是在设备不在同一子网中的配置中(WunderTech )。另一方面,ZeroTier 采用自己的基于 UDP 的协议,该协议可能无法与 WireGuard 的速度相匹配,但可提供强大的性能以及设置私有根服务器的灵活性(WunderTech )( TechCult )。
参考:无公网IP搞定群晖+ZEROTIER ONE实现内网穿透_NAS存储_什么值得买
Tailscale vs. DDNS、Quick Connect
优势: 同为实现外网访问NAS的方案,Tailscale在多个关键领域表现优于DDNS,具体优势如下:
- 简单性: Tailscale的设置和使用过程更为简单直接。用户只需在NAS上安装Tailscale客户端,并登录账户即可实现设备间的自动连接,无需手动处理IP地址和端口转发设置。
- 安全性: Tailscale利用WireGuard协议,为数据传输提供端到端加密,大大增强了通信的安全性。相比之下,DDNS需通过端口转发实现远程访问,这可能会暴露网络端口给潜在的网络攻击。
- 稳定性: Tailscale的连接稳定性更优,不受动态IP变化的影响。DDNS服务依赖于及时的IP地址更新,如果DNS更新有延迟,可能会导致服务中断。
- 管理与维护: Tailscale提供中央管理界面,用户可以轻松管理设备和权限配置。DDNS配置较为分散,每次IP变更可能都需要手动检查和调整设置。
Tailscale vs. 公网IP
优势:
- 安全:无需暴露家庭NAS在公网上。
- 易用和门槛: 不是所有地区和运营商均可以提供固定的公网IP,但Tailscale开箱即用。
- 成本: 固定的公网IP通常需要较高的费用。
劣势: 直连可能更稳定高速。
Tailscale with subnet router
subnet router 子网路由
- 配置相对复杂,需要仔细规划子网划分和路由规则。
- 可能需要调整现有网络的IP地址分配。
Tailscale with Exit Node
- 优势:
- 配置简单,将所有流量转发到指定节点,无需考虑子网划分。
- 适合为整个Tailscale网络提供统一的出口。
- 劣势:
- 所有流量都经过Exit Node,可能导致网络性能下降和出口节点压力增大。
- 出口节点故障可能影响整个网络的连通性。
- 隐私性相对较低,Exit Node可以监视和控制所有流量。