Tailscale纯IP的双栈DERP和Headscale协调服务器搭建

参考

视频: Tailscale玩法之内网穿透、异地组网、全隧道模式、纯IP的双栈DERP搭建、Headscale协调服务器搭建

视频网盘备份: 内网穿透工具ZeroTier,从简单到复杂的玩法,无保留,一期全放送

搭建教程从视频的8分35秒开始

derp搭建官方教程: Custom DERP Servers · Tailscale Docs

derp搭建: DERP servers · Tailscale Docs

headscale 官方网站: Headscale

headscale 开源项目: juanfont/headscale: An open source, self-hosted implementation of the Tailscale control server

headscale-ui 开源项目: gurucomputing/headscale-ui: A web frontend for the headscale Tailscale-compatible coordination server

官方安装文档: Official releases - Headscale

搭建流程

1
2
3
4
5
6
# 查看架构
uname -m
# 更新一下软件
apt update && apt upgrade
# 安装需要工具
apt install -y wget git openssl curl

DERP 搭建

打开33445端口(tcp),3478端口(udp),其中33445端口可以更改

  • 安装go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# go官网:https://go.dev/dl/
# 获取go最新版本
wget https://go.dev/dl/go1.23.3.linux-amd64.tar.gz

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

# 检验go是否安装成功,输出版本号则成功
export PATH=$PATH:/usr/local/go/bin
go version

# 将go加入系统变量
echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile
source /etc/profile

# 更改go使用国内代理源
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
  • 拉取编译derper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 拉取编译derper中转服务器
go install tailscale.com/cmd/derper@main

# 结束后去下面文件夹
/root/go/pkg/mod/tailscale.com@v1.xxxxxxxxxx/cmd/derper

# 编辑cert.go文件,将下面三行注释
if hi.ServerName != m.hostname{
return nil, fmt.Errorf("cert mismatch with hostname: %q", hi.ServerName)
}

# 然后进入/root/go/pkg/mod/tailscale.com@v1.xxxxxxxxxx/cmd/derper文件夹
cd /root/go/pkg/mod/tailscale.com@v1.xxxxxxxxxx/cmd/derper

# 对derper编译,并输出到指定目录下
go build -o /etc/derp/derper

# 之后 cd 回到根目录
cd

# 检查是否存在derper
ls /etc/derp
  • 自签域名
1
2
# 自签域名命令,域名随便改,也可以不改
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"
  • 将derper变成服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 需要打开33445端口(tcp),3478端口(udp),其中33445端口可以更改
# 输入以下代码将derper变成服务并启用derper,其中33445端口是https端口,33446端口是http端口(没用,防止端口冲突)
cat > /etc/systemd/system/derp.service <<EOF
[Unit]
Description=TS Derper
After=network.target
Wants=network.target
[Service]
User=root
Restart=always
ExecStart=/etc/derp/derper -hostname derp.myself.com -a :33445 -http-port 33446 -certmode manual -certdir /etc/derp
RestartPreventExitStatus=1
[Install]
WantedBy=multi-user.target
EOF
  • 启动derper
1
2
3
4
5
6
7
8
9
# 自启动derper服务
systemctl enable derp

# 启用derper服务
systemctl start derp

# 查看derper状态(是否启动成功)
systemctl status derp

  • 检查中转服务器是否搭建成功
1
2
# 浏览器输入下面链接(注意是https协议),应该可以看到中转服务器在运行
https://ip:33445
  • Access Contorls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 去官方管理界面Access Contorls中写入如下命令
// Example/default ACLs for unrestricted connections.
{
// Declare static groups of users. Use autogroups for all users or users with a specific role.
// "groups": {
// "group:example": ["alice@example.com", "bob@example.com"],
// },
// *************************主要是以下部分****************************
"derpMap": {
"OmitDefaultRegions": true,
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "Myself",
"RegionName": "Myself Derper",
"Nodes": [
{
"Name": "901a",
"RegionID": 901,
"DERPPort": 33445,
"IPv4": "服务器IP",
"InsecureForTests": true,
},
],
},(使用官方ipv6代码放这,注意换行,不需要则不放)
},
},
// *************************主要是以上部分***************************
// Define the tags which can be applied to devices and by which users.
// "tagOwners": {
// "tag:example": ["autogroup:admin"],
// },

// Define access control lists for users, groups, autogroups, tags,
// Tailscale IP addresses, and subnet ranges.
"acls": [
// Allow all connections.
// Comment this section out if you want to define specific restrictions.
{"action": "accept", "src": ["*"], "dst": ["*:*"]},

// Allow users in "group:example" to access "tag:example", but only from
// devices that are running macOS and have enabled Tailscale client auto-updating.
// {"action": "accept", "src": ["group:example"], "dst": ["tag:example:*"], "srcPosture":["posture:autoUpdateMac"]},
],

// Define postures that will be applied to all rules without any specific
// srcPosture definition.
// "defaultSrcPosture": [
// "posture:anyMac",
// ],

// Define device posture rules requiring devices to meet
// certain criteria to access parts of your system.
// "postures": {
// // Require devices running macOS, a stable Tailscale
// // version and auto update enabled for Tailscale.
// "posture:autoUpdateMac": [
// "node:os == 'macos'",
// "node:tsReleaseTrack == 'stable'",
// "node:tsAutoUpdate",
// ],
// // Require devices running macOS and a stable
// // Tailscale version.
// "posture:anyMac": [
// "node:os == 'macos'",
// "node:tsReleaseTrack == 'stable'",
// ],
// },

// Define users and devices that can use Tailscale SSH.
"ssh": [
// Allow all users to SSH into their own devices in check mode.
// Comment this section out if you want to define specific restrictions.
{
"action": "check",
"src": ["autogroup:member"],
"dst": ["autogroup:self"],
"users": ["autogroup:nonroot", "root"],
},
],

// Test access rules every time they're saved.
// "tests": [
// {
// "src": "alice@example.com",
// "accept": ["tag:example"],
// "deny": ["100.101.102.103:443"],
// },
// ],
}

注意: aaa.com要换成自己的,端口33445也要根据实际情况更换

注意: 只需要在官方管理界面Access Contorls中加入如下部分代码,并做相应更改

1
2
3
4
5
*************************主要是以下部分****************************

代码

*************************主要是以上部分****************************
  • 检查是否连接中转服务器
1
2
3
4
5
6
7
8
9
# 查看是否已经连接中转服务器
tailscale netcheck

# 查看中转服务器是不是正常状态,没报错是正常的,出错找之前的步骤
tailscale status


# tailscale ping 工具,ping通则正常
tailscale ping 分配的内网ip
  • 设置ipv6

ipv6 直连第一种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

#ipv6 直连,将下面的代码放入(可以不放)
#放下面的代码,则是屏蔽官方中转服务器,将香港的id是20注释掉(查看id的网站: https://login.tailscale.com/derpmap/default)
"1": null,
"2": null,
"3": null,
"4": null,
"5": null,
"6": null,
"7": null,
"8": null,
"9": null,
"10": null,
"11": null,
"12": null,
"13": null,
"14": null,
"15": null,
"16": null,
"17": null,
"18": null,
"19": null,
"20": null,
"21": null,
"22": null,
"23": null,
"24": null,
"25": null,

ipv6 直连第二种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 给服务器配置一个ipv6
# 打开
https://tunnelbroker.net

# 点击
Create Regular Tunnel

# IPv4 Endpoint (Your side) 中填写云服务器公网ip
# 注意要打开云服务器的icmp协议,使服务器可以被ping通
# 选择需要的地区之后点 Create Tunnel
# 需要等一会不要着急
# 之后点 Example Configurations 选择系统
# 注意得到的配置文件
# local ipv4 (这个ipv4要用服务器的私有地址)
# 之后复制代码备用
# 之后回到服务器如下文件夹
/etc/network
# 找到interfaces文件修改

# 把刚复制的代码粘贴到
# The primary network interface
auto etho
iface etho inet dhcp
# 的下面

# 然后reboot重启服务器
# 重新登录服务器

# 测试ipv6是否能使用
ping6 240C::6666

# 去官方管理界面Access Contorls中写入如下命令
"derpMap": {
"OmitDefaultRegions": true,
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "Myself",
"RegionName": "Myself Derper",
"Nodes": [
{
"Name": "901a",
"RegionID": 901,
"DERPPort": 33445,
"IPv4": "服务器IP",
"IPv6": "服务器IP",
"InsecureForTests": true,
},
],
},
},
},

# 关闭 tailscale
tailscale down

# 启用 tailscale
tailscale up

# 可以再 tailscale ping 一下测试是否成功

防止白嫖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 服务器安装 tailscale
curl -fsSL https://tailscale.com/install.sh | sh

# 然后
tailscale up
# 将云服务器加入tailscale网络中

# 修改derper服务
nano /etc/systemd/system/derp.service
# 在
ExecStart=/etc/derp/derper -hostname derp.myself.com -a :33445 -http-port 33446 -certmode manual -certdir /etc/derp
# 后面加入
--verify-clients
# 修改之后的是
ExecStart=/etc/derp/derper -hostname derp.myself.com -a :33445 -http-port 33446 -certmode manual -certdir /etc/derp --verify-clients

# crtl+x 然后 y 然后回车保存

# 重新加载服务
systemctl daemon-reload

# 重新启用 derp 服务
systemctl restart derp

搭建 headscale

打开自行设定的端口(tcp)

  • headscale 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 下载安装包(v0.23.0这部分需要自行调整,amd64亦然,在headscale 开源项目网站中找)
wget --output-document=headscale.deb \ https://github.com/juanfont/headscale/releases/download/v0.23.0/headscale_0.23.0_linux_amd64.deb

# 安装 headscale
sudo dpkg --install headscale.deb

# 开机自启
sudo systemctl enable headscale

# 编辑配置文件
nano /etc/headscale/config.yaml

# 修改:
server_url: http://服务器ip:端口
# 注意: 端口随意设置,将服务器端口(tcp)打开
# 将 ip_prefixes 中的 ipv6 部分注释掉
# crtl+x 然后 y 然后回车保存
  • nginx 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 安装 nginx (安装过宝塔的应该安装过)
apt install -y nginx

# 到如下目录编辑 nginx 配置文件
/etc/nginx/sites-available
# 编辑 default 文件,粘贴下面的代码,注意将`端口`改为上面设置的端口
map $http_upgrade $connection_upgrade {
default keep-alive;
'websocket' upgrade;
'' close;
}
server {
listen 端口;
listen [::]:端口;
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;

}

location /web {
index index.html;
alias /var/www/web;
}
}

  • headscale-ui 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 下载ui
wget https://github.com/gurucomputing/headscale-ui/releases/download/2024.10.10/headscale-ui.zip

# 解压压缩包到指定为止
unzip -d /var/www headscale-ui.zip

# 启动 headscale
systemctl start headscale

# 重启 nginx
systemctl restart nginx

# 创建api秘钥用来给ui授权(可重复创建)
headscale apikeys create --expiration 9999d

# 登录ui
http://服务器ip:端口/web

# 粘贴秘钥
Settings - Headscale Api Key 中粘贴刚才的秘钥 - Test Server Settings

# 创建用户
User View - Hide New User - 名称随意
  • 加入headscale 协调服务器
1
2
3
4
5
6
7
8
9
10
11
12
# 修改客户端默认登录地址就可以登录对客户端进行授权
# Linux 加入 headscale 协调服务器方法
tailscale logout
tailscale up --login-server=http://云服务器IP:端口
# 回车之后出现的字符 从 nodekey 开始复制
# 进入ui
Device View - New Device - 秘钥粘贴到 Device Key - Select User选择创建的

# 举例 mac 客户端加入 headscale 协调服务器方法
# 登录之后显示一串字符 将 --key 后面的复制
# 进入ui
Device View - New Device - 秘钥粘贴到 Device Key - Select User选择创建的

以上在 headscale 中还是使用 tailscale 官方中转服务器

使用自己的中转服务器需要进行以下设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 创建自定义中转服务器配置文件
touch /var/www/derp.json

# 找到文件编辑,粘贴以下内容,注意根据自己搭建的中转服务器更改
{
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "Myself",
"RegionName": "Myself Derper",
"Nodes": [
{
"Name": "901a",
"RegionID": 901,
"DERPPort": 33445,
"IPv4": "IP地址",
"IPv6": "IP地址",
"InsecureForTests": true
}
]
}
}
}

# 编辑 nginx 配置文件,粘贴如下内容,粘贴在刚刚编辑 nginx 配置文件内容后紧挨着
server {
listen 80;
listen [::]:80;

server_name 127.0.0.1;

root /var/www;
index index.html index.htm index.nginx-debian.html;
location /d {
alias /var/www;
autoindex on;
}
location / {
try_files $uri $uri/ =404;
}
}

# 在编辑 headscale 配置文件
# 在 urls 后粘贴
- http://127.0.0.1/d/derp.json
# 注释掉官方的地址

# 重启 nginx 和 headscale
systemctl restart nginx
systemctl restart headscale

由于防白嫖功能打开,将中转服务器改为自己的后,无法连通中转服务器

要连通中转服务器,需要将云服务器加入 headscale 协调服务器中

加入方法如 Linux 加入 headscale 协调服务器方法