收起左侧

docker搭建tailscale进行异地p2p组网

3
回复
900
查看
[ 复制链接 ]

1

主题

1

回帖

0

牛值

江湖小虾

2025-5-19 15:08:37 显示全部楼层 阅读模式

前言

为什么选用tailscale?

  1. 笔者有异地组网需求,目前尝试过frp stcp做穿透、wireguard组网,经过一段时间的使用,稍微总结一下:使用frp用stcp发布服务,客户端连接,确实是个很好的办法,但是配置终究太麻烦,需要安装客户端、在添加了穿透之后每个客户端需要独立配置等等;wireguard可能是当下最好的组网技术,低占用、linux内核级支持、配置简单(wireguard-ui),这些都是它的优点,可是有一个十分致命的点,它是中心化的,流量都需要过一遍server进行转发,这无异于极大的增加了服务器的带宽压力且增加了流量的延迟。经过这一段时间的查阅资料,发现了tailscale这个基于wireguard的项目,他的工作原理可以通过官网进行查看,与此同时又发现了headscale这个对tailscale server的开源实现。
  2. 这里可能有人就要问了,为什么在tailscale官方免费提供了3用户100台设备连接、提供acl、p2p、sso的情况下,要选择自建headscale呢,当然是为了固定IP,毕竟随机分配的地址可太难受了。
  3. 如果您觉得tailscale官方提供的设备数量足够你使用且无自定义ip的需求,那么你仍然可以使用tailscale官方提供的服务,但仍建议您自建一个derp(tailscale中继服务器),因为官方未在大陆地区提供derp服务,存在人数较多及访问延迟较高的情况。

服务器占用的端口列表

说明:此处占用端口列表为docker容器映射到本地的端口,你也可以使用docker启动一个nginx,这样子就不用占用服务器本地的端口了,本文采用物理机安装nginx进行反代的方式。

端口类型 实际对外端口号 容器端口号 需要反代 用途 所属服务
TCP 58080 8080 需要 headscale server headscale
TCP 57070 7070 需要 headscale web ui headscale
TCP 56060 6060 需要 headscale derp derp server
UDP 3478 3478 不需要 headscale derp stun derp server

前提条件

  1. 你需要一台具备公网IP的服务器和该服务器防火墙修改权限
  2. 一个域名且带有SSL证书(可以使用acme.sh申请免费证书),需要占用两个子域
  3. 一些基础的计算机网络知识 注意:请将本文全文所涉及到的域名:hs.example.com(headscale-server及ui)、hsderp.example.com(中继)修改为自己的域名,后续将不再另行说明。
  4. 本文将使用docker compose的方式安装headscale、derp、headscale-ui。

安装docker

注意:该项内容来源于清华大学开源软件镜像站

Docker 提供了一个自动配置与安装的脚本,支持 Debian、RHEL、SUSE 系列及衍生系统的安装。 以下内容假定 您为 root 用户,或有 sudo 权限,或知道 root 密码; 您系统上有 curl 或 wget

export DOWNLOAD_URL="https://mirrors.tuna.tsinghua.edu.cn/docker-ce"
# 如您使用 curl
curl -fsSL https://get.docker.com/ | sh
# 如您使用 wget
wget -O- https://get.docker.com/ | sh

docker compose文件

本文中compose文件仅部署headscale、headscale-ui、derp、client,请按需进行修改。

注意,要提前配置好config.yaml和derp.yaml,并放入headscale/config文件夹内,同时因derp更新不及时,这里采取了手动构建方式,需将derp.Dockerfile放入dockerfiles文件夹内。可以去GitHUB的代码仓下载config-example.yaml和derp-example.yaml,内容见0x04配置文件部分。

# docker-compose.yaml
version: '3.9'
networks:
  private:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.200.0/24
services:
  server:
    image: headscale/headscale:v0.23.0-alpha12
    container_name: headscale-server
    networks:
      - private
    volumes:
      - ./headscale/config:/etc/headscale
      - ./headscale/data:/var/lib/headscale
      - ./headscale/run:/var/run/headscale
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
    ports:
      - "58080:8080"
    command: serve
    restart: unless-stopped
    depends_on:
      - derp
  webui:
    image: ghcr.io/gurucomputing/headscale-ui
    container_name: headscale-ui
    networks:
      - private
    environment:
      HTTP_PORT: 7070
    ports:
      - "57070:7070" 
    volumes:
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
    restart: unless-stopped
  derp:
    build:
      context: ./dockerfiles
      dockerfile: derp.Dockerfile
    container_name: headscale-derp
    networks:
      - private
    environment:
      DERP_DOMAIN: hs.example.com
      DERP_ADDR: :6060
      DERP_CERT_MODE: letsencrypt
      DERP_VERIFY_CLIENTS: true
    ports:
      - "56060:6060" # derp port, TCP
      - "3478:3478/udp"  # STUN port, UDP
    volumes:
      - ./tailscale:/var/run/tailscale
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
    restart: unless-stopped
  
  client:
    image: tailscale/tailscale:stable
    container_name: tailscale-client
    network_mode: "host"
    privileged: true
    environment:
      TS_EXTRA_ARGS: --netfilter-mode = off
    volumes:
      - ./tailscale:/var/run/tailscale
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
      - /var/lib:/var/lib
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - net_admin
      - sys_module
    command: tailscaled
    restart: unless-stopped

请将derp.Dockerfile放入docker-compose.yaml同级的dockerfiles文件夹内

# derp.Dockerfile 
FROM golang:latest AS builder
WORKDIR /app
# https://tailscale.com/kb/1118/custom-derp-servers/
RUN go env -w GOPROXY=https://goproxy.io,direct
RUN go install tailscale.com/cmd/derper@latest
FROM ubuntu
WORKDIR /app
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
    apt-get install -y --no-install-recommends apt-utils && \
    apt-get install -y ca-certificates && \
    mkdir /app/certs
ENV DERP_DOMAIN=your-hostname.com
ENV DERP_CERT_MODE=letsencrypt
ENV DERP_CERT_DIR=/app/certs
ENV DERP_ADDR=:443
ENV DERP_STUN=true
ENV DERP_STUN_PORT=3478
ENV DERP_HTTP_PORT=80
ENV DERP_VERIFY_CLIENTS=false
ENV DERP_VERIFY_CLIENT_URL=""
COPY --from=builder /go/bin/derper .
CMD /app/derper --hostname=$DERP_DOMAIN \
    --certmode=$DERP_CERT_MODE \
    --certdir=$DERP_CERT_DIR \
    --a=$DERP_ADDR \
    --stun=$DERP_STUN  \
    --stun-port=$DERP_STUN_PORT \
    --http-port=$DERP_HTTP_PORT \
    --verify-clients=$DERP_VERIFY_CLIENTS \
    --verify-client-url=$DERP_VERIFY_CLIENT_URL

服务器配置

config.yaml

server_url: https://hs.example.cn
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
grpc_listen_addr: 0.0.0.0:50443 
noise:
  private_key_path: ./noise_private.key
prefixes:
  v6: fd7a:115c:a1e0::/48
  v4: 100.100.0.0/16
  allocation: sequential
derp:
  paths:
    - /etc/headscale/derp.yaml
database:
  type: sqlite
  sqlite:
    path: /var/lib/headscale/db.sqlite
    write_ahead_log: true

derp.yaml

regions:
  999:
    regionid: 999
    regioncode: cnsz
    regionname: China Tencent Cloud
    nodes:
      - name: my-derp
        regionid: 999
        hostname: hsderp.example.cn
        stunport: 3478
        stunonly: false
        derpport: 443

nginx配置文件

注意,为了便于笔者管理,以下给出的nginx配置文件仅为proxy相关conf,请自行在域名配置文件里incloud,相关语法:include /www/hsderp.example.cn/proxy/*.conf 。您也可以根自己喜好直接写入网站配置内。

headscale-server和derp正常进行反代就行了,ui端因为跨域的原因,需要在同一个域里。如您按照本文提供的内容进行创建的话,那么你可以直接使用此nginx配置,否则请自行修改相应端口。

  • hsderp.example.com反代设置 hsderp.conf
location ^~ / {
    proxy_pass http://127.0.0.1:56060; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
    add_header Strict-Transport-Security "max-age=31536000"; 
}
  • hs.example.com反代设置 hs.conf
location ^~ / {
    proxy_pass http://127.0.0.1:58080; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
    add_header Strict-Transport-Security "max-age=31536000"; 
    add_header Cache-Control no-cache; 
}

web.conf

location ^~ /web {
    proxy_pass http://127.0.0.1:57070; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
    add_header Strict-Transport-Security "max-age=31536000"; 
    add_header Cache-Control no-cache; 
}

至此,您在浏览器中打开https://hs.example.com/web及https://haderp.example.com均可看到相关页面

headscale-ui配置

  1. 为了便捷控制,首先生成api key供headscale-ui进行控制 ,其中-e参数后面指定的是该apikey的过期时间,这里设置为720天 docker exec headscale-server headscale apikeys create -e 720d
  2. ui端配置 2.1 打开ui端页面 2.2 点击”Settings” 2.3 添加”Headscale URL”,本例为https://hs.example.com 2.4 将刚才生成的api key粘贴进“Headscale API Key”中 2.5 点击“Test Server Settings”,出现绿色对号后UI端就可以通过ui控制服务端了 2.6 进入“User View”,点击“+New User”,添加一个用户 2.7 为该用户生成一个Preauth Key,供客户端连接使用。为了便捷性,最好设置为“Reusable”,并“Active”,如所示

客户端连接

客户端可以在tailscale官网进行下载及查看使用文档。 如您docker-compose文件中将derp部分的DERP_VERIFY_CLIENTS设置为了true,这代表您开启了客户端验证,如关闭则您的derp可被所有人使用。开启后需要对docker的client进行配置,参考linux客户端,如下为使用docker exec配置示例

docker exec -it tailscale-client tailscale up --netfilter-mode=off --login-server=https://hs.example.com --auth-key=YOUR AUTH KEY

linux客户端

  1. 使用官方脚本安装tailscale客户端 curl -fsSL https://tailscale.com/install.sh | sh
  2. 连接服务器 注意:以下命令二选一即可,有关路由转发描述见0x08 路由转发
# 需路由转发
tailscale up --netfilter-mode=off \
             --accept-routes \
             --advertise-routes=192.168.0.0/24 \
             --login-server=https://hs.example.com \
             --auth-key=YOUR AUTH KEY
# 不需路由转发
tailscale up --netfilter-mode=off \
             --login-server=https://hs.example.com \
             --auth-key=YOUR AUTH KEY

windows客户端

  1. 在官网下载并安装客户端后,首次需打开cmd或powershell,输入以下命令进行连接
tailscale up -netfilter-mode=off -login-server=https://hs.example.com -auth-key=YOUR AUTH KEY

IOS客户端

  1. 您需要使用非中国大陆地区APP Store账号进行下载并安装tailscale。本文不提供相关教程,请自行搜索美区、港区APPLE ID注册教程。
  2. 安装后点击右上角头像,在弹出“Accounts”窗口,点击右上角三个点,并选择“Use a custom coordination server”
  3. 输入您的域名https://hs.example.com点击“Login in”
  4. 复制弹窗的以mkey:xxxx开头的key
  5. 浏览器打开headscale-ui,点击“Device view”,并点击“New Device”
  6. 将步骤4中复制的key粘贴到“Device Key”中,并选择对应用户,点后面的勾。

其他客户端

因笔者设备原因,android/macos等平台不做其他描述,手动添加设备的教程同IOS客户端中第3步以后所示。

路由转发

路由转发为接受路由转发,当你启动tailscale时加了--accept-routes参数之后,您启动命令中advertise-routes需要附带您当前设备能够访问的子网,这将会被通告出去。

举个例子,家中网段为192.168.0.0/24,设备A的ip地址为192.168.0.1,当开启路由转发后,从手机等设备访问192.168.0.0/24这个网段将通过设备A进行转发,可以直接联通家中所有局域网。

如您在0x07 客户端连接中的linux客户端教程中使用了路由转发功能,需要额外进行配置

# eth@if78为出口网卡名,tailscale0为tailscale网卡名,需根据实际修改
iptables -I FORWARD -i eth@if78 -j ACCEPT
iptables -I FORWARD -o eth0@if78 -j ACCEPT
iptables -t nat -I POSTROUTING -o eth0@if78 -j MASQUERADE
iptables -I FORWARD -i tailscale0 -j ACCEPT
iptables -I FORWARD -o tailscale0 -j ACCEPT
iptables -t nat -I POSTROUTING -o tailscale0 -j MASQUERADE
sysctl -w net.ipv4.ip_forward=1
收藏
送赞
分享

1

主题

94

回帖

0

牛值

初出茅庐

2025-5-19 22:09:21 显示全部楼层

感觉这么更复杂。

其实并不麻烦,所有的东西都是基于docker compose的,up-d一下就行了  详情 回复
2025-5-22 10:46

1

主题

3

回帖

0

牛值

江湖小虾

2025-5-20 21:08:37 显示全部楼层

能出个视频版本的就好了

1

主题

1

回帖

0

牛值

江湖小虾

2025-5-22 10:46:57 楼主 显示全部楼层
nameyq 发表于 2025-5-19 22:09
感觉这么更复杂。

其实并不麻烦,所有的东西都是基于docker compose的,up-d一下就行了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则