跳至正文
老丹的足迹 —— 代码写给机器,游记写给自己,感悟写给时间
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面

自建私有VPN网络:Headscale完整部署指南

引言

在云服务和远程办公日益普及的今天,搭建一个安全、私密的虚拟专用网络(VPN)成为许多开发者和企业的需求。Tailscale作为一款基于WireGuard的现代VPN解决方案,因其易用性和强大功能广受欢迎,但其控制服务器闭源且依赖第三方服务。Headscale作为Tailscale控制服务器的开源替代品,让我们能够完全掌控自己的VPN网络。

本文将详细记录从零开始部署Headscale的全过程,包括服务端搭建、Web管理界面配置、客户端连接以及网络优化等核心环节。

第一部分:环境准备

1.1 服务器要求

部署Headscale需要一台具备公网IP的服务器,并满足以下条件:

  • 操作系统:Ubuntu 20.04/22.04 LTS
  • 已安装Docker和Docker Compose
  • 拥有一个解析到服务器IP的域名
  • 防火墙开放必要端口:443(TCP)、3478(UDP)

1.2 域名准备

为服务准备以下域名解析:

  • 主域名:用于Headscale服务端和客户端连接
  • 子域名规划清晰,便于后续扩展

第二部分:服务端部署

2.1 获取SSL证书

使用Certbot为域名申请免费的Let’s Encrypt证书:

sudo apt update
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com

Certbot会自动完成域名验证、证书签发和Nginx配置更新。

2.2 配置Nginx反向代理

创建Nginx配置文件,实现以下功能:

  • 将域名请求转发到Headscale容器
  • 支持WebSocket协议(Headscale客户端通信必需)
  • 配置管理界面的独立路径

核心代理配置要点:

  • 启用HTTP/1.1和Upgrade头支持WebSocket
  • 设置正确的代理头传递客户端真实IP
  • 关闭缓冲确保实时通信

2.3 编写Docker Compose配置

创建项目目录结构并编写docker-compose.yml文件:

services:
  headscale:
    image: headscale/headscale:latest
    container_name: headscale
    restart: unless-stopped
    volumes:
      - ./config:/etc/headscale
      - ./data:/var/lib/headscale
    ports:
      - "127.0.0.1:8080:8080"
    command: serve
    networks:
      - headscale-net

  headplane:
    image: ghcr.io/tale/headplane:latest
    container_name: headplane
    restart: unless-stopped
    environment:
      - HEADSCALE_URL=http://headscale:8080
    volumes:
      - ./config/headplane:/etc/headplane
    ports:
      - "127.0.0.1:3001:3000"
    networks:
      - headscale-net

networks:
  headscale-net:
    driver: bridge

2.4 核心配置文件

Headscale的配置文件config.yaml需要重点关注以下参数:

server_url:客户端连接的公开地址,必须使用HTTPS协议
listen_addr:服务监听地址,需设置为0.0.0.0以允许容器间通信
database:使用SQLite作为数据库,适合中小规模部署
prefixes:IP地址段分配,使用Tailscale标准CGNAT范围
noise:新版本必需的私钥配置,用于加密通信
DERP:中继服务器配置,作为P2P直连失败时的备用方案
DNS:配置MagicDNS和上游DNS服务器
policy:ACL策略文件路径

2.5 初始启动与服务验证

执行以下命令启动服务并验证:

docker compose up -d
docker logs headscale

正常启动日志应显示服务正在监听指定端口,且无配置错误。

第三部分:管理界面部署

3.1 Headplane配置

Headplane是Headscale的现代化Web管理界面,需创建专属配置文件:

headscale:
  url: http://headscale:8080

server:
  listen: :3000
  cookie_secret: 32位随机字符串
  allow_registration: true

oauth:
  enabled: false

cookie_secret需生成32位随机字符串,可使用以下命令:

openssl rand -hex 16

3.2 Nginx路径代理

在Nginx配置中添加管理界面路径代理:

location /admin/ {
    proxy_pass http://127.0.0.1:3001/admin/;
    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 X-Forwarded-Proto $scheme;
}

第四部分:用户与密钥管理

4.1 创建用户

Headscale中的用户是设备归属和权限隔离的基本单位:

docker exec headscale headscale users create default

4.2 生成API密钥

API密钥用于登录Headplane管理界面:

docker exec headscale headscale apikeys create --expiration 999d

4.3 生成预授权密钥

预授权密钥用于客户端自动注册,无需手动审批:

docker exec headscale headscale preauthkeys create --user default --reusable --expiration 365d

第五部分:客户端连接

5.1 Linux客户端

# 安装Tailscale
curl -fsSL https://tailscale.com/install.sh | sh

# 连接Headscale
sudo tailscale up --login-server https://your-domain.com --authkey <预授权密钥>

5.2 Windows客户端

命令行方式(管理员PowerShell):

tailscale up --login-server https://your-domain.com --authkey <预授权密钥>

注册表方式(免命令行):
创建并导入以下注册表文件:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Tailscale IPN]
"LoginURL"="https://your-domain.com"

5.3 macOS客户端

sudo tailscale up --login-server https://your-domain.com --authkey <预授权密钥>

第六部分:网络功能验证

6.1 DERP中继服务

DERP是Tailscale的中继协议,在无法建立P2P直连时提供备用通道。部署时需启用内置DERP并配置STUN:

derp:
  server:
    enabled: true
    region_id: 999
    region_code: "headscale"
    region_name: "Headscale Embedded DERP"
    ipv4: 服务器公网IP
    stun_listen_addr: "0.0.0.0:3478"

验证DERP状态:

docker logs headscale | grep -i derp
tailscale debug derp-map

6.2 P2P直连测试

通过ping命令测试设备间连接路径:

tailscale ping 目标设备IP

预期输出:

  • via IP:端口 in Xms:P2P直连成功
  • via DERP(区域) in Xms:走中继转发

影响P2P直连的因素:

  • 双方网络NAT类型
  • IPv6支持情况
  • 防火墙策略

第七部分:ACL策略配置

ACL(访问控制列表)用于控制VPN网络中设备间的通信权限。

默认全允许策略:

{
  "acls": [
    {
      "action": "accept",
      "src": ["*"],
      "dst": ["*:*"]
    }
  ]
}

精细化控制示例:

{
  "acls": [
    {
      "action": "accept",
      "src": ["tag:dev"],
      "dst": ["tag:dev-server:*"]
    },
    {
      "action": "accept",
      "src": ["tag:ops"],
      "dst": ["tag:prod-server:22"]
    }
  ]
}

第八部分:常见问题与解决方案

8.1 配置文件版本兼容

不同版本Headscale的配置字段有变化,关键变更包括:

  • ip_prefixes → prefixes.v4/v6
  • dns_config.nameservers → dns.nameservers.global
  • 新增 noise.private_key_path 字段
  • 数据库配置从 db_type/db_path 改为 db.type/db.path

8.2 Headplane启动失败

确保:

  • cookie_secret为正好32位字符串
  • 配置文件路径正确挂载
  • Headscale服务可被Headplane访问

8.3 客户端无法连接

检查:

  • Nginx是否正确转发WebSocket
  • 防火墙是否放行必要端口
  • server_url是否使用HTTPS协议
  • 客户端是否使用正确的登录服务器地址

结语

通过以上步骤,我们成功搭建了一个完全自控的私有VPN网络。Headscale作为开源控制服务器,配合Headplane管理界面,提供了与Tailscale官方服务相当的使用体验,同时让我们完全掌握数据主权和网络配置。

这套方案适合:

  • 希望摆脱第三方服务依赖的开发者
  • 需要精细控制VPN网络的企业
  • 对数据隐私有较高要求的个人用户

Headscale的部署过程虽然涉及多个组件,但一旦配置完成,日常使用和管理都非常便捷。随着对ACL策略、子网路由、出口节点等高级功能的深入探索,可以构建出满足各种复杂需求的私有网络架构。

作者

老丹

关注我
其他文章
上一个

constexpr:C++编译期计算的基石

下一个

C++ 智能指针完全指南:从入门到工程实战

关于博主

    老丹是一名C/C++后台开发工程师,信奉“无抽象不设计,无性能不生产”。

  • 技术栈:Modern C++、Linux环境编程、多线程/并发、网络编程等。
  • 信条:能用constexpr解决的问题绝不拖到运行时,能靠RAII避免的泄漏绝不写析构。
  • 正在填坑:从解封装到渲染的C++全链路实现,正在驯服FFmpeg与H.264/H.265。
  • 输出原则:这里的每一段代码都经过-Wall -Wextra -Werror -O2的洗礼。

近期文章

  • Ubuntu 防火墙迁移指南:从 UFW 到 firewalld 的完整实践 2026年9月12日
  • Nano 编辑器完全操作指南:从入门到熟练 2026年9月12日
  • SSCG:让自签名证书不再“危险”的生成工具 2026年9月12日
  • Ubuntu Samba 服务安装与配置完全指南 2026年9月12日
  • 从零开始:用 Docker 部署 Jellyfin 并启用英特尔核显硬件加速 2026年9月11日

文章分类

  • C/C++开发 (22)
  • Docker容器 (5)
  • Linux工具包 (17)
  • Linux服务配置 (50)
  • Linux系统 (16)
  • OpenWrt路由 (3)
  • Shell脚本 (3)
  • 代码管理 (1)
  • 安防技术 (4)
  • 数据安全 (36)
  • 未分类 (1)
  • 网络协议 (25)
  • 计算机理论 (23)
  • 音视频技术 (5)
联系我们:📍 地址:中国·广东省深圳市   |   ✉️ 邮箱:support@tanglinux.com   |   💬 QQ:870866607
版权所有:老丹的足迹粤ICP备2026061170号-1       公安备案图标 粤公网安备44030002013274号