为什么会有此文章呢,因为前面写过一篇文章是用openvpn实现的,当时有友友提到阿里云服务器的带宽有限,可能连接质量不好,毕竟水管子太小了。很多朋友在评论区提到了内网穿透,而tailscale就是一款内网穿透工具,客户端和中继服务器derper是开源的,服务器端不开源,但是社区搞了headscale平替官方的服务器端,本文将介绍如何一步一步的安装headscale,derper,tailscale实现内网穿透,以实现在远程控制家里面的电脑。
注意事项:
- 由于tailscale是代码中硬编码使用100.64.0.0/10网段,该网段在国内公有云提供商如腾讯云、阿里云上均是云商保留IP段,用于云商的各种镜像仓库,负载均衡等,如果你在你的ECS上安装了tailscale客户端,会导致无法访问这些云商的资源。
- headscale和podman不能并存,笔者最开始的时候就是在笔者的阿里云服务器上,直接在物理机上安装headscale,结果直接导致整个podman容器无法访问,后改成了本文中用的docker部署方式
- MacOS 下使用一些增强代理工具时, 如果安装 App Store 的官方图形化客户端, 则可能与这些软件冲突, 推荐使用纯命令行版本并添加进程规则匹配 tailscale 和 tailscaled 两个进程, 让它们始终走 DIRECT 规则即可
- headscale各版本配置文件不兼容,请注意配置文件和程序的版本要匹配,配置文件示例可以在官方的github仓库中切换不同的分支/tag找到。
准备工作:
购买服务器,推荐阿里云的99元个人版,足够使用了,3M带宽,可以参考微软官方的文档:
https://learn.microsoft.com/zh-cn/training/modules/implement-manage-networking-azure-virtual-desktop/4-remote-desktop-protocol-bandwidth
服务器上安装docker , docker-compose ,具体教程推荐直接看官方文档,也可以安装podman,笔者安装的podman,docker的命令在podman中通用。
创建docker网桥,如果已经创建忽略,如果你有别的网桥,那后面docker配置文件中的网桥名称,IP地址等根据你的实际情况更改
docker network create --driver bridge --gateway 10.200.0.1 --ip-range 10.200.2.1/32 --subnet 10.200.0.1/16 xplan
配置并启动headscale:
建立本文需要的工作目录,本文所有工作目录放在/root/headscale/,请根据你的实际情况调整目录:
mkdir -p /root/headscale/headscale
cd /root/headscale/headscale
创建
/root/headscale/headscale/docker-compose.yml
version: "3.7"
services:
headscale:
image: headscale/headscale:v0.23.0
restart: unless-stopped
container_name: headscale
ports:
- "9064:8080"
- "9065:9090"
volumes:
# Please change to the fullpath of the config folder just created
- ./config:/etc/headscale
- /var/lib/headscale:/var/lib/headscale
command: serve
networks:
xplan:
ipv4_address: 10.200.222.4
networks:
xplan:
external: true
name: xplan
创建
/root/headscale/headscale/config/config.yaml
# https://myheadscale.example.com:443
# 替换成你的域名
server_url: https://headscale.yourdomain.com
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
grpc_listen_addr: 127.0.0.1:50443
grpc_allow_insecure: false
noise:
# 第一次启动,会自动创建,此处就是笔者踩过的坑,0.23版本配置在这,低版本不在
private_key_path: /var/lib/headscale/noise_private.key
# 注意IP只能是100.64.0.0/10的子网,这是代码里面写死的,不能改,此子网和k8s, 阿里云,腾讯云都有冲突,所以只能尝试用docker
prefixes:
v4: 100.127.254.0/24
allocation: sequential
derp:
server:
# 禁用官方的中继服务器
enabled: false
region_id: 999
region_code: "headscale"
region_name: "Headscale Embedded DERP"
stun_listen_addr: "0.0.0.0:3478"
private_key_path: /var/lib/headscale/derp_server_private.key
automatically_add_embedded_derp_region: true
ipv4: 1.2.3.4
# ipv6: 2001:db8::1
# List of externally available DERP maps encoded in JSON
urls:
- https://controlplane.tailscale.com/derpmap/default
# 自建中继服务器配置文件
# paths:
# - /etc/headscale/derp-example.yaml
paths: ["/etc/headscale/derp.yaml"]
auto_update_enabled: true
update_frequency: 24h
disable_check_updates: false
ephemeral_node_inactivity_timeout: 30m
database:
type: sqlite
# Enable debug mode. This setting requires the log.level to be set to "debug" or "trace".
debug: false
# GORM configuration settings.
gorm:
# Enable prepared statements.
prepare_stmt: true
# Enable parameterized queries.
parameterized_queries: true
# Skip logging "record not found" errors.
skip_err_record_not_found: true
# Threshold for slow queries in milliseconds.
slow_threshold: 1000
# SQLite config
sqlite:
path: /var/lib/headscale/db.sqlite
write_ahead_log: true
# URL to ACME directory
acme_url: https://acme-v02.api.letsencrypt.org/directory
acme_email: ""
tls_letsencrypt_hostname: ""
tls_letsencrypt_cache_dir: /var/lib/headscale/cache
tls_letsencrypt_challenge_type: HTTP-01
tls_letsencrypt_listen: ":http"
tls_cert_path: ""
tls_key_path: ""
log:
# Output formatting for logs: text or json
format: text
level: info
policy:
mode: file
path: ""
dns:
magic_dns: true
base_domain: example.com
# List of DNS servers to expose to clients.
nameservers:
global:
- 223.6.6.6
- 119.29.29.29
split:
{}
search_domains: []
extra_records: []
use_username_in_magic_dns: false
unix_socket: /var/run/headscale/headscale.sock
unix_socket_permission: "0770"
logtail:
enabled: false
randomize_client_port: false
创建
/root/headscale/headscale/config/derp.yaml自建中继服务器配置:
regions:
900:
regionid: 900
regioncode: bj
regionname: Alicloud Beijing
nodes:
- name: 900a
regionid: 900
hostname: der.yourdomain.com
ipv4: your ip
stunport: 33478
stunonly: false
derpport: 443
regioncode和regionname可以随意取,ipv4填你服务器的公网IP,hostname填你分配给derper中断服务器的域名
启动容器,在/root/headscale/headscale下执行命令:
mkdir -p /var/lib/headscale
chown -R 1000:1000 /var/lib/headscale
docker compose up -d
通过docker compose ps 命令查看容器,看到如图的展示,则代表容器启动成功
配置caddy服务器反代headscale:
如果你已经有caddy服务器,请直接在你的Caddyfile配置文件中增加反代配置并重启即可:
hd.shuncheng.lu {
tls i@shuncheng.lu
reverse_proxy http://10.200.222.4:8080
}
创建caddy配置目录:
mkdir -p /root/headscale/caddy
cd /root/headscale/caddy
创建
/root/headscale/caddy/docker-compose.yml
version: "3.7"
services:
xplan_caddy:
image: caddy:2.4.6
restart: always
container_name: xplan_caddy
ulimits:
nofile:
soft: "1048576"
hard: "1048576"
nproc:
soft: "1048576"
hard: "1048576"
memlock:
soft: -1
hard: -1
volumes:
- /workspace/caddy/data:/data
- /workspace/caddy/logs:/var/log/caddy
- /workspace/caddy/config:/config
- ./Caddyfile:/etc/caddy/Caddyfile
ports:
- 80:80
- 443:443
networks:
xplan:
ipv4_address: 10.200.222.222
networks:
xplan:
external: true
name: xplan
注意文件中的/workspace/caddy目标为存放caddy的日志,证书,配置等文件目录,根据你的服务器情况创建好。
创建
/root/headscale/caddy/Caddyfile文件
{
debug
auto_https disable_redirects
email i@yourdomain.com
}
headscale.yourdomain.com {
tls i@yourdomain.com
reverse_proxy http://10.200.222.4:8080
}
在/root/headscale/caddy中执行命令启动caddy
docker compose up -d
等待容器启动完成后,打开你的浏览器输入
https://headscale.yourdomain.com,正常能看到404提示页,并且没有证书错误,证明你已经成功搭建headscale中控服务器。
配置derper中继服务器
注意,你需要一个域名,才能开启验证客户端,避免你的中继服务器被人白嫖。中继服务器验证客户端需要在中继服务器所在服务器上启动tailscaled,并且使用tailscale up登录headscale中控服务器, 由于某些未知原因tailscale up 不支持docker cmd或者docker exec方式去执行,必须进入到容器内手动执行。
创建/root/headscale/derper目录:
mkdir /root/headscale/derper
创建
/root/headscale/derper/docker-compose.yml文件
version: "3.7"
services:
headscale:
build:
context: ./
dockerfile: Dockerfile
restart: unless-stopped
container_name: derper
devices:
- /dev/net/tun
privileged: true
cap_add:
- NET_ADMIN
environment:
- TZ=Asia/Shanghai
- DERP_CERT_MODE=letsencrypt
- DERP_DOMAIN=der.yourdomain.com
- DERP_ADDR=:44443
- KEY=${KEY}
ports:
- "33478:3478/tcp"
- "33478:3478/udp"
networks:
xplan:
ipv4_address: 10.200.222.6
networks:
xplan:
external: true
name: xplan
创建
/root/headscale/derper/Dockerfile文件
FROM ubuntu:24.04
RUN echo '# 阿里云\n\
Types: deb\n\
URIs: http://mirrors.aliyun.com/ubuntu/\n\
Suites: noble noble-updates noble-security\n\
Components: main restricted universe multiverse\n\
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg' > /etc/apt/sources.list.d/ubuntu.sources
RUN apt-get update -y && apt-get install -y curl wget vim
RUN curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg | tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
RUN curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list | tee /etc/apt/sources.list.d/tailscale.list
RUN apt-get update -y && apt-get install -y tailscale golang
RUN go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct && go install tailscale.com/cmd/derper@main
RUN go env
RUN mv /root/go/bin/derper /usr/local/bin
RUN useradd --create-home --home-dir /var/lib/derper/ --system --user-group --shell /usr/sbin/nologin derper
RUN echo 'net.ipv4.ip_forward = 1' | tee /etc/sysctl.d/ipforwarding.conf
RUN echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.d/ipforwarding.conf
COPY ./up.sh /up.sh
RUN chmod +x /up.sh
CMD ["/up.sh"]
创建
/root/headscale/derper/up.sh文件
#!bin/bash
tailscaled &
sleep 5 # wait tailscaled started
/usr/local/bin/derper -c=/var/lib/derper/private.key -a=:44443 -stun-port=3478 --hostname=der.yourdomain.com -verify-clients
tail -f /dev/null
创建
/root/headscale/derper/start.sh文件
#!/bin/bash
KEY=`docker exec -it headscale headscale preauthkeys create -e 72h -u default |grep -v "TRC" |grep -v "Docker" |grep -v nodocker`
export KEY=$KEY
docker compose up -d --build
echo "你需要手动执行如下命令,第一步进入容器,第二步在容器内执行:"
echo "docker exec -it derper bash"
echo "tailscale up --login-server https://headscale.yourdomain.com --accept-routes=true --accept-dns=false --auth-key ${KEY}"
登录你的阿里云/腾讯云等控制台,能安全组中放行33478/UDP。
启动derper:
cd /root/headscale/derper
docker compose up -d
按图示,手动登录tailscale。
配置caddy反代derper
网上有说nginx也可以,只需要按平时我们配置websocket反代一样就行,笔者没尝试。主要是caddy可以自动申请证书
在前面的Caddyfile中增加反代配置:
der.yourdomain.com {
tls i@shuncheng.lu
reverse_proxy http://10.200.222.6:44443
}
在/root/headscale/caddy中执行重启命令
docker compose restart
现在打开浏览器,你应该可以看到der的输出:
安装客户端
官方教程:
https://tailscale.com/kb/1347/installation
访问官方下载页面,下载客户端,笔者是windows直接访问
https://tailscale.com/download/windows下载windows版本安装。
安装后,会自动打开,不要去登录,默认是登录tailscale官方的服务器,我们打开一个管理员运行的命令提示符,或者powershell,执行登录命令:
tailscale up --login-server https://headscale.yourdomain.com --accept-routes=true --accept-dns=false --auth-key=yourauthkey
yourauthkey为预授权码,在你的服务器上执行如下命令获取:
docker exec -it headscale headscale preauthkeys create -e 72h -u default |grep -v "TRC" |grep -v "Docker" |grep -v nodocker
重复上述步骤在多个客户端执行,如果你的软路由,可以在软路由执行,并且把参数换下,允许路由转发,由可以实现通过内网IP访问所有内网机器。
- --login-server: 指定使用的中央服务器地址(必填)
- --advertise-routes: 向中央服务器报告当前客户端处于哪个内网网段下, 便于中央服务器让同内网设备直接内网直连(可选的)或者将其他设备指定流量路由到当前内网(可选)
- --accept-routes: 是否接受中央服务器下发的用于路由到其他客户端内网的路由规则(可选)
- --accept-dns: 是否使用中央服务器下发的 DNS 相关配置(可选, 推荐关闭)
开启RDP的方式,可以点笔者头像,看笔者上期文章,里面有如何打开RDP。
你只需要上上图一样,在控制端通过点击设备列表中的被控端设备,就可以获取IP,然后打开系统自带的远程桌面连接,输入IP,用户名,密码等即可连接。
如果你有什么问题,可以在评论区讨论留言。
如果你觉得本文对你有用,欢迎点赞、关注、转发。