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

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

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

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

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

#安装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。

#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反代。

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节点配置:

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配置,禁用默认的节点,使用自己的节点配置。

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服务端哪个之间延迟低,就连接哪里。

#查看,是否使用了自建derp节点
tailscale netcheck

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

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

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

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 放到可以直链访问的服务器上。

先添加一个节点信息。

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配置

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)

{
  // 这里是其他的原有的一些 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/)中对您的这篇博文进行了引用。再次感谢,互联网因你而精彩。

留言

* - 必填