作为无 root 权限用户添加内网服务器到 Tailnet 中

在访问实验室服务器时,使用学校提供的 VPN 有点麻烦(每个账号同时只允许一个 VPN 登录),所以我打算把服务器登录到预先架设的 Tailnet 中,这样只要登录了 Tailnet 就可以直接访问服务器了!

不过这里有个问题:我不是系统管理员,所以不能使用 sudo apt intsall tailscale 之类的方法直接安装 Tailscale 到系统中;必须使用有限的用户权限安装 Tailscale 服务,而且最好能够在开机时就启动服务,这样才足够方便!

在非 root 用户下运行 Tailscale 并登录到 Tailnet

首先需要在没有 root 权限的用户账号下运行 Tailscale,并登录到 Tailnet 才行。很明显,我们不能安装 Tailscale,所以需要使用静态二进制文件,可以在 Tailscale 发布的软件列表中找到并安装:

1
2
3
4
5
6
7
8
# 创建文件夹
mkdir tailscale && cd tailscale
# 在这里使用的是 Tailscale 1.84.0 amd64 版本
wget https://pkgs.tailscale.com/stable/tailscale_1.84.0_amd64.tgz
# 解压
tar -xvf tailscale_1.84.0_amd64.tgz
# 把包里的东西都挪到外面来
mv tailscale_1.84.0_amd64/* . && rm -r tailscale_1.84.0_amd64*

现在的 tailscale 文件夹中有应该两个可执行文件:tailscaletailscaled

接下来需要启动 tailscaled 服务,注意这里需要指定使用用户空间,否则默认会使用没有权限的路径创建 socket 造成错误:

1
2
# 指定一个有读写权限的位置创建 socket
./tailscaled --socket=/tmp/tailscaled.sock --tun=userspace-networking &

如果没有报错,那么 tailscaled 服务应该已经成功启动了。

接下来,需要使用 tailscale 认证并登录到 Tailnet:

1
./tailscale --socket=/tmp/tailscaled.sock login --login-server=$YOUR_LOGIN_SERVER

$YOUR_LOGIN_SERVER 替换成自己搭建的 Headscale 服务器地址,或者直接删掉 --login-server 参数,这样会使用官方的授权平面。访问给出的 URL 并按照指示操作,应该就可以把设备注册到 Tailnet 上了!

自动登录

虽然上面给出的命令可以登录到 Tailnet,但是我们的服务器应该更懂事一些,能够自动登录到 Tailnet 上。使用 systemd 可以将自动启动服务和登录的功能作为服务注册,这样一来每次登录时就可以自动运行了!

获取 authkey

首先需要获取一个登录 authkey,这样才方便自动登录,否则每次登录都需要访问 URL 手动登录。所需的 authkey 可以从用户页面中生成并获取。

在自建的 Headscale 控制台可以生成任意时刻过期的 authkey;虽然在官网只能生成最多 90 天过期的,不过可以在设置页面对单独的设备设置不过期。

定义服务并注册

接下来需要编写 .service 文件,描述启动 tailscaled 和使用 tailscale 登录的过程。新建 ~/.config/systemd/user/tailscaled.service~/.config/systemd/user/tailscale-connect.service 两个文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ~/.config/systemd/user/tailscaled.service
[Unit]
Description=Tailscale node agent (User Mode)
Documentation=https://tailscale.com/kb/
After=network.target

[Service]
Type=simple
# tailscaled 二进制文件路径
ExecStart=/home/member/tailscale/tailscaled \
--socket=/tmp/tailscaled.sock \
--tun=userspace-networking
Restart=on-failure
RestartSec=5

[Install]
WantedBy=default.target
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ~/.config/systemd/user/tailscale-connect.service
[Unit]
Description=Connect to Headscale using Tailscale (User Mode)
Documentation=https://tailscale.com/kb/
# 确保在 tailscaled 启动后运行
After=tailscaled.service
Requires=tailscaled.service

[Service]
Type=oneshot
RemainAfterExit=yes
# tailscale 二进制文件路径
ExecStart=/home/member/tailscale/tailscale \
--socket=/tmp/tailscaled.sock \
up \
--authkey=$YOUR_AUTH_KEY \
--login-server=$YOUR_LOGIN_SERVER

[Install]
WantedBy=default.target

这样会使得 tailscaled 在网络初始化后启动,而 tailscale-connect 会在 tailscaled 启动后使用 authkey 登录到服务器上。

然后,注册并启动服务:

1
2
3
systemctl --user daemon-reload
systemctl --user enable tailscaled && systemctl --user enable tailscale-connect
systemctl --user start tailscaled && systemctl --user start tailscale-connect

接下来可以通过 status 检查运行状态:

1
2
3
4
# 检查 tailscaled 状态
systemctl --user status tailscaled
# 检查 tailscale-connect 状态
systemctl --user status tailscale-connect

如果 tailscaled 的状态是 active (running),而 tailscale-connect 的状态是 active (exited),就说明服务成功启动了。

开机自启

现在还有个问题:之前使用了systemctl --user 进行操作,注册的服务只会在用户登录时才自动运行;在用户的会话全部退出时,tailscaled 就会被杀掉,导致设备下线。

所以需要进行设置,使得服务在系统启动时就执行,并且避免在会话退出时进程被终止。在这里可以使用 linger 进行设置,虽然有些 LLM 告诉我需要 sudo 权限,但是我实际使用时用用户权限也没有问题:

1
loginctl enable-linger

同样可以使用 loginctl 对设置进行验证:

1
loginctl show-user member | grep Linger

如果发现 Linger=yes,那么说明使用 systemctl --user 设置的内容也可以在系统启动时启动了。

这样一来,服务器就可以在系统启动时自动登录 Tailnet,使得我们能够在只使用外网时也能访问了!