headscale组网自建derp中继节点,国内也可以

之前发过自建headscale组网服务器:https://zsxwz.com/2023/04/12

使用自己的服务器,可以使用的功能就更多了,比如自建derp中继节点,默认的中继节点都没有国内的,所以速度可能也不是太理想,如果使用国内的服务器考虑备案,如果不使用国内服务器,可以考虑日韩新加坡香港等亚太地区节点,延迟稍微低一点。

首先是有备案域名的情况,先解析你的域名到你服务器ip

1、自建中继需要域名,虽然可能有不用域名的方法,但是自签证书之类的也麻烦。申请证书可以使用acme.sh脚本。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#安装nginx,后面反代也用得到
apt install nginx
systemctl stop nginx
#下载脚本
curl https://get.acme.sh | sh
#安装依赖
apt install socat
#申请证书,headscale.xxx.com换成你自己的域名,这里申请的是let's的免费证书
bash /root/.acme.sh/acme.sh --issue -d "headscale.xxx.com" --standalone -k ec-256 --server letsencrypt
systemctl restart nginx
#安装nginx,后面反代也用得到 apt install nginx systemctl stop nginx #下载脚本 curl https://get.acme.sh | sh #安装依赖 apt install socat #申请证书,headscale.xxx.com换成你自己的域名,这里申请的是let's的免费证书 bash /root/.acme.sh/acme.sh --issue -d "headscale.xxx.com" --standalone -k ec-256 --server letsencrypt systemctl restart nginx
#安装nginx,后面反代也用得到
apt install nginx

systemctl stop nginx

#下载脚本
curl  https://get.acme.sh | sh
#安装依赖
apt install socat

#申请证书,headscale.xxx.com换成你自己的域名,这里申请的是let's的免费证书
bash /root/.acme.sh/acme.sh --issue -d "headscale.xxx.com" --standalone -k ec-256 --server letsencrypt

systemctl restart nginx

2、derp中继服务,可以使用docker。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#headscale.xxx.com_ecc根据你自己的域名修改
docker run -dit \
--restart always \
--name derper \
--hostname derper \
-p 12345:12345 \
-p 3478:3478/udp \
-v /root/.acme.sh/headscale.xxx.com_ecc:/app/certs \
-e DERP_CERT_MODE=letsencrypt \
-e DERP_ADDR=:12345 \
-e DERP_DOMAIN=headscale.xxx.com \
ghcr.io/yangchuansheng/derper:latest
#headscale.xxx.com_ecc根据你自己的域名修改 docker run -dit \ --restart always \ --name derper \ --hostname derper \ -p 12345:12345 \ -p 3478:3478/udp \ -v /root/.acme.sh/headscale.xxx.com_ecc:/app/certs \ -e DERP_CERT_MODE=letsencrypt \ -e DERP_ADDR=:12345 \ -e DERP_DOMAIN=headscale.xxx.com \ ghcr.io/yangchuansheng/derper:latest
#headscale.xxx.com_ecc根据你自己的域名修改

docker run -dit \
--restart always \
  --name derper \
  --hostname derper \
  -p 12345:12345 \
  -p 3478:3478/udp \
  -v /root/.acme.sh/headscale.xxx.com_ecc:/app/certs \
  -e DERP_CERT_MODE=letsencrypt \
  -e DERP_ADDR=:12345 \
  -e DERP_DOMAIN=headscale.xxx.com \
  ghcr.io/yangchuansheng/derper:latest

网页监听12345端口,可以根据自己需求修改。headscale默认stun监听3478端口,记得服务器放行12345和3478端口。

浏览器打开:http://你服务器的ip或者域名:12345,即可查看derp服务是否运行

3、配置nginx反代。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
nano /etc/nginx/conf.d/headscale.conf
#添加以下内容
#headscale.xxx.com根据你自己的情况修改
server {
listen 80;
listen [::]:80;
server_name headscale.xxx.com;
return 301 https://headscale.xxx.com$request_uri;
location /nginx_path {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name headscale.xxx.com;
root /root/wwwroot/html;
index index.html;
ssl_certificate /root/.acme.sh/headscale.xxx.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/headscale.xxx.com_ecc/headscale.xxx.com.key;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Public-Key-Pins 'pin-sha256="amMeV6gb9QNx0Zf7FtJ19Wa/t2B7KpCF/1n2Js3UuSU="; pin-sha256="6YBE8kK4d5J1qu1wEjyoKqzEIvyRY5HyM/NB2wKdcZo="; max-age=2592000; includeSubDomains';
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=60s;
resolver_timeout 60s;
location / {
proxy_redirect off;
proxy_pass http://127.0.0.1:12345; #端口
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /nginx_status {
access_log off;
allow 127.0.0.1;
deny all;
}
}
#重启以下nginx服务
systemctl restart nginx
nano /etc/nginx/conf.d/headscale.conf #添加以下内容 #headscale.xxx.com根据你自己的情况修改 server { listen 80; listen [::]:80; server_name headscale.xxx.com; return 301 https://headscale.xxx.com$request_uri; location /nginx_path { stub_status on; access_log off; allow 127.0.0.1; deny all; } } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name headscale.xxx.com; root /root/wwwroot/html; index index.html; ssl_certificate /root/.acme.sh/headscale.xxx.com_ecc/fullchain.cer; ssl_certificate_key /root/.acme.sh/headscale.xxx.com_ecc/headscale.xxx.com.key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers on; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header Public-Key-Pins 'pin-sha256="amMeV6gb9QNx0Zf7FtJ19Wa/t2B7KpCF/1n2Js3UuSU="; pin-sha256="6YBE8kK4d5J1qu1wEjyoKqzEIvyRY5HyM/NB2wKdcZo="; max-age=2592000; includeSubDomains'; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 1.1.1.1 valid=60s; resolver_timeout 60s; location / { proxy_redirect off; proxy_pass http://127.0.0.1:12345; #端口 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /nginx_status { access_log off; allow 127.0.0.1; deny all; } } #重启以下nginx服务 systemctl restart nginx
nano /etc/nginx/conf.d/headscale.conf

#添加以下内容
#headscale.xxx.com根据你自己的情况修改

server {
    listen 80;
    listen [::]:80;
    server_name headscale.xxx.com;
    return 301 https://headscale.xxx.com$request_uri;
    location /nginx_path {
        stub_status on;
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name headscale.xxx.com;
    root /root/wwwroot/html;
    index index.html;

    ssl_certificate       /root/.acme.sh/headscale.xxx.com_ecc/fullchain.cer;
    ssl_certificate_key   /root/.acme.sh/headscale.xxx.com_ecc/headscale.xxx.com.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header Public-Key-Pins 'pin-sha256="amMeV6gb9QNx0Zf7FtJ19Wa/t2B7KpCF/1n2Js3UuSU="; pin-sha256="6YBE8kK4d5J1qu1wEjyoKqzEIvyRY5HyM/NB2wKdcZo="; max-age=2592000; includeSubDomains';

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 1.1.1.1 valid=60s;
    resolver_timeout 60s;

    location / {
      proxy_redirect off;
      proxy_pass http://127.0.0.1:12345; #端口
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /nginx_status {
        access_log off;
        allow 127.0.0.1;
        deny all;
    }
}

#重启以下nginx服务
systemctl restart nginx

浏览器打开你的域名:https://headscale.xxx.com,查看是否正常访问。

4、修改headscale使用自己的中继,默认中继节点没有国内的,也是到处乱窜,所以不是很稳定。

headscale搭建看往期教程就好了,就不赘述了。

修改headscale配置,添加derp节点配置:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
nano /etc/headscale/derp.yaml
#添加以下内容
regions:
900:
regionid: 900
regioncode: xwz
regionname: AWS_TOKYO
nodes:
- name: 900a
regionid: 900
hostname: headscale.xxx.com #换成你自己的
stunport: 3478
stunonly: false
derpport: 443
nano /etc/headscale/derp.yaml #添加以下内容 regions: 900: regionid: 900 regioncode: xwz regionname: AWS_TOKYO nodes: - name: 900a regionid: 900 hostname: headscale.xxx.com #换成你自己的 stunport: 3478 stunonly: false derpport: 443
nano /etc/headscale/derp.yaml

#添加以下内容

regions:
  900:
    regionid: 900
    regioncode: xwz
    regionname: AWS_TOKYO
    nodes:
      - name: 900a
        regionid: 900
        hostname: headscale.xxx.com  #换成你自己的
        stunport: 3478
        stunonly: false
        derpport: 443

DERP 配置文件的详细实例参考:https://github.com/juanfont/headscale/blob/main/derp-example.yaml

修改headcale配置,禁用默认的节点,使用自己的节点配置。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
nano /etc/headscale/config.yaml
#主要修改这几项
derp:
server:
enabled: false #保持 false,不激活 headscale 自带的 derp。
# 配置 DERP 节点项
paths:
- /etc/headscale/derp.yaml
# List of externally available DERP maps encoded in JSON
urls:
# - https://controlplane.tailscale.com/derpmap/default
auto_update_enabled: true
update_frequency: 24h
nano /etc/headscale/config.yaml #主要修改这几项 derp: server: enabled: false #保持 false,不激活 headscale 自带的 derp。 # 配置 DERP 节点项 paths: - /etc/headscale/derp.yaml # List of externally available DERP maps encoded in JSON urls: # - https://controlplane.tailscale.com/derpmap/default auto_update_enabled: true update_frequency: 24h
nano /etc/headscale/config.yaml

#主要修改这几项

derp:
  server:
    enabled: false #保持 false,不激活 headscale 自带的 derp。

  # 配置 DERP 节点项
  paths:
    - /etc/headscale/derp.yaml

  # List of externally available DERP maps encoded in JSON
  urls:
  #  - https://controlplane.tailscale.com/derpmap/default

  auto_update_enabled: true
  update_frequency: 24h

最后重启一下headscale服务即可。一般来说,一个headscale客户端,和中继derp节点和headscale服务端哪个之间延迟低,就连接哪里。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#查看,是否使用了自建derp节点
tailscale netcheck
#ping测试一下
tailscale ping 组网后局域网ip
#查看,是否使用了自建derp节点 tailscale netcheck #ping测试一下 tailscale ping 组网后局域网ip
#查看,是否使用了自建derp节点
tailscale netcheck

#ping测试一下
tailscale ping 组网后局域网ip

没有备案域名的情况,由于derp只能使用ssl,因此可以自签ip证书。不过一些小商家可能连443端口,不管有没有域名解析到服务器怕是都要备案,自己测试国内腾讯云可以正常使用443,其他的不清楚,估计大厂都可以。也可以使用其他端口。

5、搭建derp中继,使用的是这位大佬的自签ip证书:https://github.com/yangchuansheng/ip_derper

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
docker run --restart always \
--name derper -p 12345:12345 -p 3478:3478/udp \
-v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \
-e DERP_ADDR=:12345 \
-e DERP_HTTP_PORT=12346 \
-e DERP_CERTS=/app/certs \
-e DERP_VERIFY_CLIENTS=false \
-d dockerproxy.com/yangchuansheng/ip_derper:latest
docker run --restart always \ --name derper -p 12345:12345 -p 3478:3478/udp \ -v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \ -e DERP_ADDR=:12345 \ -e DERP_HTTP_PORT=12346 \ -e DERP_CERTS=/app/certs \ -e DERP_VERIFY_CLIENTS=false \ -d dockerproxy.com/yangchuansheng/ip_derper:latest
docker run --restart always \
  --name derper -p 12345:12345 -p 3478:3478/udp \
  -v /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock \
  -e DERP_ADDR=:12345 \
  -e DERP_HTTP_PORT=12346 \
  -e DERP_CERTS=/app/certs \
  -e DERP_VERIFY_CLIENTS=false \
  -d dockerproxy.com/yangchuansheng/ip_derper:latest

记得放行12345和3478端口。

浏览器打开,http://你服务器ip:12345,当然自签证书,浏览器打开肯定会显示证书错误的。

6、修改headscale使用自己的中继。

这种情况只能使用json格式的配置文件,需要是可以直链访问的链接,derp.json 放到可以直链访问的服务器上。

先添加一个节点信息。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
nano derp.json
#添加以下内容
{
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "xwz随意",
"RegionName": "Inner Mongolia随意填",
"Nodes": [
{
"Name": "901a",
"RegionID": 901,
"DERPPort": 12345,
"HostName": "xxx.xxx.xxx.xxx你服务器ip",
"IPv4": "xxx.xxx.xxx.xxx你服务器ip",
"InsecureForTests": true
}
]
}
}
}
nano derp.json #添加以下内容 { "Regions": { "901": { "RegionID": 901, "RegionCode": "xwz随意", "RegionName": "Inner Mongolia随意填", "Nodes": [ { "Name": "901a", "RegionID": 901, "DERPPort": 12345, "HostName": "xxx.xxx.xxx.xxx你服务器ip", "IPv4": "xxx.xxx.xxx.xxx你服务器ip", "InsecureForTests": true } ] } } }
nano derp.json


#添加以下内容
{
  "Regions": {
    "901": {
      "RegionID": 901,
      "RegionCode": "xwz随意",
      "RegionName": "Inner Mongolia随意填",
      "Nodes": [
        {
          "Name": "901a",
          "RegionID": 901,
          "DERPPort": 12345,
          "HostName": "xxx.xxx.xxx.xxx你服务器ip",
          "IPv4": "xxx.xxx.xxx.xxx你服务器ip",
          "InsecureForTests": true
        }
      ]
    }
  }
}

修改headscale配置

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
nano /etc/headscale/config.yaml
#主要修改这几项
derp:
server:
enabled: false #保持 false,不激活 headscale 自带的 derp。
# 配置 DERP 节点项
#paths:
# - /etc/headscale/derp.yaml
# List of externally available DERP maps encoded in JSON
urls:
- http://xxx.xxx/derp.json #你derp节点配置直链
# - https://controlplane.tailscale.com/derpmap/default
auto_update_enabled: true
update_frequency: 24h
nano /etc/headscale/config.yaml #主要修改这几项 derp: server: enabled: false #保持 false,不激活 headscale 自带的 derp。 # 配置 DERP 节点项 #paths: # - /etc/headscale/derp.yaml # List of externally available DERP maps encoded in JSON urls: - http://xxx.xxx/derp.json #你derp节点配置直链 # - https://controlplane.tailscale.com/derpmap/default auto_update_enabled: true update_frequency: 24h
nano /etc/headscale/config.yaml

#主要修改这几项

derp:
  server:
    enabled: false #保持 false,不激活 headscale 自带的 derp。

  # 配置 DERP 节点项
  #paths:
  #  - /etc/headscale/derp.yaml

  # List of externally available DERP maps encoded in JSON
  urls:
     - http://xxx.xxx/derp.json  #你derp节点配置直链
  #  - https://controlplane.tailscale.com/derpmap/default

  auto_update_enabled: true
  update_frequency: 24h

然后重启以下headscale就可以了

7、如果不用headscale,直接使用账号登录官方tailscale,可以添加中继到Access Control,哪个中继快连哪个。

有公网ip或者局域网内走直连,没有则走中继。

网页登录 TailScale 账号,打开 控制台的 Access Control 页面,添加这样一段注释(也就是在原来的 json 里加个 “derpMap” 的 key)

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
// 这里是其他的原有的一些 key
"derpMap": {
// "OmitDefaultRegions": true,
"Regions": {
"900": {
"RegionID": 900,
"RegionCode": "my-derp",
"RegionName": "这里一般写机房的位置(纯标示用)",
"Nodes": [
{
"Name": "自己的derp",
"RegionID": 900,
"DERPPort": 12345, //端口根据自己的修改
"STUNPort": 3478,
"HostName": "你的ip或者域名",
"IPv4": "如果是域名这行就不要,如果是ip和上面一行一样",
"InsecureForTests": true,
},
],
},
},
},
}
{ // 这里是其他的原有的一些 key "derpMap": { // "OmitDefaultRegions": true, "Regions": { "900": { "RegionID": 900, "RegionCode": "my-derp", "RegionName": "这里一般写机房的位置(纯标示用)", "Nodes": [ { "Name": "自己的derp", "RegionID": 900, "DERPPort": 12345, //端口根据自己的修改 "STUNPort": 3478, "HostName": "你的ip或者域名", "IPv4": "如果是域名这行就不要,如果是ip和上面一行一样", "InsecureForTests": true, }, ], }, }, }, }
{
  // 这里是其他的原有的一些 key
  "derpMap": {
    // "OmitDefaultRegions": true,
    "Regions": {
      "900": {
        "RegionID":   900,
        "RegionCode": "my-derp",
        "RegionName": "这里一般写机房的位置(纯标示用)",
        "Nodes": [
          {
            "Name":     "自己的derp",
            "RegionID": 900,
            "DERPPort": 12345, //端口根据自己的修改
            "STUNPort": 3478,
            "HostName": "你的ip或者域名",
            "IPv4": "如果是域名这行就不要,如果是ip和上面一行一样",
            "InsecureForTests": true,
          },
        ],
      },
    },
  },
}

评论 1

  1. Doublefire.Chen

    “这种情况只能使用json格式的配置文件”
    这句话太关键了,我在网上找了好久,只有你这篇教程提到了这个关键信息
    我之前一直用yaml配置,始终没有成功(日志显示TLS handshake error form ……:write: connection reset by peer,客户端使用tailscale netcheck也不能成功连接服务器),直到看了您的教程,使用了json进行配置,终于成功了
    太感谢了,为您点赞👍👍👍
    我也在我的教程(https://doublefire.chen.bbb.enterprises/2023/10/05/A-great-intranet-penetration-solution%E2%80%94%E2%80%94Self-hold-Tailscale-HeadScale/)中对您的这篇博文进行了引用。再次感谢,互联网因你而精彩。

留言

取消回复
0 out of 65525
* - 必填