tailscale+headscale+derper+acme内网穿透

内网穿透的方法更改

之前一直是用 frp 作为内网穿透的工具,用起来的有一些不方便的地方,但是总比没有强
最近研究生考试刚结束,期末考试也结束了,留在学校没事干,就用 frp 内网穿透看放在家里的 NAS 上的番剧
就这么看了几天,突然脑子转过来了,查了一下用作中转服务的服务器的流量,这不看不知道,一看吓一跳,短短几天用掉了100-200G的流量,这我怎么受得了
于是我就找到了之前看到过的 ZeroTier,在一个国内的服务器上搭建后,虽然内网穿透是实现了,但是走的是中转流量,这不还是要用掉大量的流量看番吗???
随即放弃 ZeroTier 方案,于是就找到了 tailscale
tailscale 用起来挺不错的,只是它的服务器搭建在国外,国内没有,所以速度会很慢,于是就想着自己搭建一个国内的管理器

前提知识储备

tailscale的工作由协调服务器和中转服务器完成,协调服务器用于让已验证的tailscale客户端建立p2p连接,中转服务器用于保证连接的正常进行
在网络通畅的情况下,协调服务器会让两个tailscale客户端完成p2p连接的建立,两台客户端建立连接完成后,就可以愉快的进行数据交换了,没有中转服务器的事,但是问题就是出在这,如果p2p连接建立失败,那么就需要中转服务器进行中转,以达到连接建立的目的
如果直接使用tailscale官方的服务,那么什么都不需要搭建,安装好tailscale客户端执行登录命令就可以连接

1
tailscale up

但是,如果不想使用tailscale官方的服务,那么就需要自己搭建了
此处搭建的中转服务器就是DERP服务,协调服务器就是headscale服务器

准备工作

我用的方案是最简单的方案,一台derper服务器,一台headscale,分别搭建在两个VPS上,这样不容易产生端口冲突的问题(因为我碰到了这样的问题),于是先准备如下材料

1
2
3
域名*1   derper搭建时需要
VPS*2 一台用作搭建derper,一台用作搭建headscale
Linux客户端 用作tailscale客户端

域名可以在namesilo上购买,一个 .top 的域名也就1、2美元一年
并创建一个 A 记录指向用于搭建derper的服务器的IP地址

搭建derper的服务器放行 3478(UDP) 端口,放行任意一个高位 TCP 端口(此处我使用的是12150端口)
搭建headscale服务器放行任意一个高位 TCP 端口(此处我用的是37125端口)

搭建derp服务

derper服务需要使用域名,虽然有不使用域名的方案,但是我还没用,先要域名解析到derper服务器

acme 申请证书

安装acme.sh

1
curl  https://get.acme.sh | sh

安装 socat

1
apt update && update && apt install socat -y

使用acme申请letsencrypt免费证书

1
~/.acme.sh/acme.sh --issue -d 域名 --standalone -k ec-256 --server letsencrypt

创建 /opt/derper 目录

1
mkdir /opt/derper

并导出证书到此处

1
~/.acme.sh/acme.sh --installcert -d 域名 --fullchainpath /opt/derper/域名.crt --keypath /opt/derper/域名.key --ecc

安装golang

按照 go.dev 官网的方法,安装最新的golang
下载最新的golang包

1
wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz

删除可能残留的golang并安装最新的golang

1
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz

将golang添加到环境变量中,可以将下列语句添加到 /etc/profile

1
export PATH=$PATH:/usr/local/go/bin

如果添加了,source一下

1
source /etc/profile

查看是否安装成功

1
go version

安装derp

首先将derp项目拉到本地,同时会把已将编译好的二进制也拉过来

1
go install tailscale.com/cmd/derper@main

将编译好的derp放到 /opt/derper

1
cp ~/go/bin/derper /opt/derper

编辑 /etc/systemd/system/derper.service 文件,写入如下内容

1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=Start Derper
After=network.target
Wants=network.target
[Service]
User=root
Restart=always
ExecStart=/opt/derper/derper -hostname forheade.top -a :12150 -http-port 12151 -certmode manual -certdir /opt/derper
RestartPreventExitStatus=1
[Install]
WantedBy=multi-user.target

其中 ExecStart 中的 -a 后面的参数就是derper服务器防火墙需要放行的端口,而 -http-port 仅为了防止端口冲突,随便设置一个就好了,如果这个服务器是一个人用的,可以追加 --verify-clients 参数,只允许验证过的客户端使用这个derper服务器

启动并设置开机启动derp

1
systemctl enable --now derper.service

浏览器访问 域名:12150 可以看到derper搭建完成

搭建headscale

headscale是用于连接建立的服务器,流量要求比较小,搭建的headscale可以顺便安装一个ui,不过用处不大,命令行足够了

安装headscale服务

headscale release中找到适合的deb包,下载到服务器上

安装

1
2
wget https://github.com/juanfont/headscale/releases/download/v0.23.0-alpha2/headscale_0.23.0-alpha2_linux_amd64.deb
dpkg --install headscale_0.23.0-alpha2_linux_amd64.deb

设置开机自启动

1
systemctl enable headscale.service

修改headscale配置文件

编辑 /etc/headscale/config.yaml 文件,修改如下配置,端口记得防火墙放行

1
server_url: http://本服务器IP地址:37125

设置反向代理

安装nginx

1
apt update && apt upgrade && apt install nginx -y

编辑 /etc/nginx/sites-available/default 文件,添加如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
map $http_upgrade $connection_upgrade {
default keep-alive;
'websocket' upgrade;
'' close;
}

server {
listen 37125;
listen [::]:37125;
server_name 本服务器的IP地址;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $server_name;
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
}
}

这样就可以启动nginx和headscale了

1
2
systemctl restart nginx
systemctl restart headscale

headscale使用自己搭建的derp服务器

编辑 /etc/headscale/derp.yaml 文件,添加如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
regions:
901:
regionid: 901
regioncode: DERP
regionname: MYDERP
nodes:
- name: DERP_SERVER_1
regionid: 901
hostname: derper服务器的域名
stunport: 3478
stunonly: false
derpport: 12150

在编辑 /etc/headscale/config.yaml 文件,修改如下配置

1
2
3
4
5
# 将官方的json配置注释掉,有自己的derp服务器就不用官方的了
urls: []
# 使用刚才写好的配置
paths:
- /etc/headscale/derp.yaml

重启headscale服务

1
systemctl restart headscale

tailscale客户端加入headscale中

headscale先创建用户,以便tailscale客户端注册验证

1
headscale user create <username>

tailscale客户端执行如下命令加入headscale协调服务器中,并验证

1
sudo tailscale up --login-server http://headscale的服务器的IP地址:37125

这回跳出一个网址,复制该网址到浏览器打开,会获得一串验证密钥

在headscale端执行验证命令即可

1
headscale nodes register --user <username> --key <key-string>

连接完成后,可以通过命令查看连接的状态

1
2
tailscale status
tailscale netcheck

可能会遇到的问题

如下是我碰到的几个问题以及它们的解决方案

derper无法连接的问题

首先先看一下是否正确搭建了derper服务,如果都没问题,看看是否在搭建derper服务时,添加了 --verify-clients 参数
如果是因为添加了 --verify-clients 参数的原因导致的,那么 derper 服务器也安装 tailscale 并注册到 headscale 中就可以了

DNS 覆盖(overwriting)问题

目前只出现在了 Arch Linux 的 tailscale 客户端上,原因是 dhcpcd 服务器会修改 DNS 的配置导致的,所有做如下修改即可
不允许dhcpcd修改resolve.conf配置,修改 /etc/dhcpcd.conf 文件,添加如下配置

1
nohook resolv.conf

重启dhcpcd服务

1
systemctl restart dhcpcd

不允许NetworkManager修改resolve.conf配置,修改 /etc/NetworkManager/NetworkManager.conf 文件,添加如下配置

1
2
[main]
dns=none

重启服务NetworkManager服务

1
systemctl restart NetworkManager

让systemd-resolved来管理resolve.conf配置

1
2
ln -rsf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
systemctl enable --now systemd-resolved

重启tailscale服务

1
systemctl restart tailscaled

考完研了,又有大把的时间可以折腾了(ゝ∀・)b
该说折腾了个tailscale是省了流量吗,毕竟为了搭建tailscale用了整整3天,踩了好多的坑,做梦都在敲命令(☍﹏⁰)
然后折腾着折腾着,我已经到家了,不需要内网穿透,直接用内网就能不用流量开看了(。ŏ_ŏ)
嘛,至少我有学会了个新技能不是吗
不过这个假期也不能全拿来折腾了,还得准备考研复试和毕业设计呢( º﹃º )