2025-12-13 23:17:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
https://github.com/juanfont/headscale/releases/download/v0.27.1/headscale_0.27.1_linux_amd64
|
|
|
|
|
|
https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
|
|
|
|
|
|
mkdir /var/lib/headscale
|
|
|
|
|
|
chown -R headscale:headscale /var/lib/headscale/
|
|
|
|
|
|
touch /var/lib/headscale/db.sqlite
|
|
|
|
|
|
|
|
|
|
|
|
headscale_0.27.1_linux_amd64 /usr/local/bin/headscale
|
|
|
|
|
|
chmod +x /usr/local/bin/headscale
|
|
|
|
|
|
mkdir /etc/headscale/
|
|
|
|
|
|
cp config-example.yaml /etc/headscale/
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2025-12-13 23:19:06 +08:00
|
|
|
|
|
2025-12-13 23:17:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
修改配置文件,将 server_url 改为公网 IP 或域名。如果是国内服务器,域名必须要备案。我的域名无法备案,所以我就直接用公网 IP 了。
|
|
|
|
|
|
如果暂时用不到 DNS 功能,可以先将 magic_dns 设为 false。
|
|
|
|
|
|
server_url 设置为 http://<PUBLIC_ENDPOINT>:8080,将 <PUBLIC_ENDPOINT> 替换为公网 IP 或者域名。
|
|
|
|
|
|
建议打开随机端口,将 randomize_client_port 设为 true。
|
|
|
|
|
|
可自定义私有网段,也可同时开启 IPv4 和 IPv6:
|
|
|
|
|
|
|
|
|
|
|
|
ip_prefixes:
|
|
|
|
|
|
# - fd7a:115c:a1e0::/48
|
|
|
|
|
|
- 100.64.0.0/16
|
|
|
|
|
|
```
|
2025-12-13 23:19:06 +08:00
|
|
|
|
#### vim /etc/systemd/system/headscale.service
|
|
|
|
|
|
```
|
2025-12-13 23:17:21 +08:00
|
|
|
|
[Unit]
|
|
|
|
|
|
Description=headscale controller
|
|
|
|
|
|
After=syslog.target
|
|
|
|
|
|
After=network.target
|
|
|
|
|
|
|
|
|
|
|
|
[Service]
|
|
|
|
|
|
Type=simple
|
|
|
|
|
|
User=headscale
|
|
|
|
|
|
Group=headscale
|
|
|
|
|
|
ExecStart=/usr/local/bin/headscale serve
|
|
|
|
|
|
Restart=always
|
|
|
|
|
|
RestartSec=5
|
|
|
|
|
|
|
|
|
|
|
|
# Optional security enhancements
|
|
|
|
|
|
NoNewPrivileges=yes
|
|
|
|
|
|
PrivateTmp=yes
|
|
|
|
|
|
ProtectSystem=strict
|
|
|
|
|
|
ProtectHome=yes
|
|
|
|
|
|
ReadWritePaths=/var/lib/headscale /var/run/headscale
|
|
|
|
|
|
AmbientCapabilities=CAP_NET_BIND_SERVICE
|
|
|
|
|
|
RuntimeDirectory=headscale
|
|
|
|
|
|
|
|
|
|
|
|
[Install]
|
|
|
|
|
|
WantedBy=multi-user.target
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2025-12-13 23:30:50 +08:00
|
|
|
|
#### 需要# 启用IP转发
|
|
|
|
|
|
```
|
|
|
|
|
|
echo 'net.ipv4.ip_forward=1' | tee -a /etc/sysctl.conf
|
|
|
|
|
|
sysctl -p
|
|
|
|
|
|
```
|
|
|
|
|
|
##### 配置NAT规则(以eth0为外网接口)
|
|
|
|
|
|
```
|
|
|
|
|
|
apt install iptables-persistent
|
|
|
|
|
|
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
|
|
|
|
|
iptables -t filter -A FORWARD -i tailscale0 -o eth0 -j ACCEPT
|
|
|
|
|
|
iptables -t filter -A FORWARD -i eth0 -o tailscale0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
|
|
|
|
|
netfilter-persistent save
|
|
|
|
|
|
```
|
|
|
|
|
|
#### 启用出口节点模式
|
|
|
|
|
|
```
|
|
|
|
|
|
tailscale up --advertise-exit-node
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 启动
|
2025-12-13 23:17:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
systemctl daemon-reload
|
|
|
|
|
|
systemctl enable --now headscale
|
|
|
|
|
|
systemctl status headscale.service
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-13 23:18:25 +08:00
|
|
|
|
|
|
|
|
|
|
#### 完整 egrep -v "#|^$" /etc/headscale/config.yaml
|
2025-12-13 23:17:21 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2025-12-13 23:18:25 +08:00
|
|
|
|
egrep -v "#|^$" /etc/headscale/config.yaml
|
2025-12-13 23:17:21 +08:00
|
|
|
|
---
|
|
|
|
|
|
server_url: http://47.106.140.17:8080
|
|
|
|
|
|
listen_addr: 0.0.0.0:8080
|
|
|
|
|
|
metrics_listen_addr: 127.0.0.1:9090
|
|
|
|
|
|
grpc_listen_addr: 0.0.0.0:50443
|
|
|
|
|
|
grpc_allow_insecure: false
|
|
|
|
|
|
noise:
|
|
|
|
|
|
private_key_path: /var/lib/headscale/noise_private.key
|
|
|
|
|
|
prefixes:
|
|
|
|
|
|
v4: 100.64.0.0/10
|
|
|
|
|
|
v6: fd7a:115c:a1e0::/48
|
|
|
|
|
|
allocation: sequential
|
|
|
|
|
|
derp:
|
|
|
|
|
|
server:
|
|
|
|
|
|
enabled: false
|
|
|
|
|
|
region_id: 999
|
|
|
|
|
|
region_code: "headscale"
|
|
|
|
|
|
region_name: "Headscale Embedded DERP"
|
|
|
|
|
|
verify_clients: true
|
|
|
|
|
|
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: 198.51.100.1
|
|
|
|
|
|
ip_allocation: "sequential"
|
|
|
|
|
|
acl:
|
|
|
|
|
|
- action: "accept"
|
|
|
|
|
|
urls:
|
|
|
|
|
|
- https://controlplane.tailscale.com/derpmap/default
|
|
|
|
|
|
paths: []
|
|
|
|
|
|
auto_update_enabled: true
|
|
|
|
|
|
update_frequency: 3h
|
|
|
|
|
|
disable_check_updates: false
|
|
|
|
|
|
ephemeral_node_inactivity_timeout: 30m
|
|
|
|
|
|
database:
|
|
|
|
|
|
type: sqlite
|
|
|
|
|
|
debug: false
|
|
|
|
|
|
gorm:
|
|
|
|
|
|
prepare_stmt: true
|
|
|
|
|
|
parameterized_queries: true
|
|
|
|
|
|
skip_err_record_not_found: true
|
|
|
|
|
|
slow_threshold: 1000
|
|
|
|
|
|
sqlite:
|
|
|
|
|
|
path: /var/lib/headscale/db.sqlite
|
|
|
|
|
|
write_ahead_log: true
|
|
|
|
|
|
wal_autocheckpoint: 1000
|
|
|
|
|
|
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:
|
|
|
|
|
|
level: info
|
|
|
|
|
|
format: text
|
|
|
|
|
|
policy:
|
|
|
|
|
|
mode: file
|
|
|
|
|
|
path: ""
|
|
|
|
|
|
dns:
|
|
|
|
|
|
magic_dns: false
|
|
|
|
|
|
base_domain: rapha.top
|
|
|
|
|
|
override_local_dns: true
|
|
|
|
|
|
nameservers:
|
|
|
|
|
|
global:
|
|
|
|
|
|
- 114.114.114.114
|
|
|
|
|
|
- 233.5.5.5
|
|
|
|
|
|
- 1.1.1.1
|
|
|
|
|
|
- 8.8.8.8
|
|
|
|
|
|
split:
|
|
|
|
|
|
{}
|
|
|
|
|
|
search_domains: []
|
|
|
|
|
|
extra_records: []
|
|
|
|
|
|
unix_socket: /var/run/headscale/headscale.sock
|
|
|
|
|
|
unix_socket_permission: "0770"
|
|
|
|
|
|
logtail:
|
|
|
|
|
|
enabled: false
|
|
|
|
|
|
randomize_client_port: false
|
|
|
|
|
|
|
2025-12-13 23:27:12 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 创建用户
|
|
|
|
|
|
```
|
|
|
|
|
|
headscale user create cba
|
|
|
|
|
|
```
|
|
|
|
|
|
### 查看用户
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
# headscale user list
|
|
|
|
|
|
ID | Name | Username | Email | Created
|
|
|
|
|
|
1 | | cba | | 2025-12-11 14:11:53
|
|
|
|
|
|
2 | | abc | | 2025-12-13 12:23:02
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### linux cli 配置
|
|
|
|
|
|
```
|
|
|
|
|
|
wget https://pkgs.tailscale.com/stable/tailscale_1.22.2_amd64.tgz
|
|
|
|
|
|
tar zxvf tailscale_1.22.2_amd64.tgz
|
|
|
|
|
|
|
|
|
|
|
|
cp tailscale_1.22.2_amd64/tailscaled /usr/sbin/tailscaled
|
|
|
|
|
|
cp tailscale_1.22.2_amd64/tailscale /usr/bin/tailscale
|
|
|
|
|
|
|
|
|
|
|
|
cp tailscale_1.22.2_amd64/systemd/tailscaled.service /lib/systemd/system/tailscaled.service
|
|
|
|
|
|
cp tailscale_1.22.2_amd64/systemd/tailscaled.defaults /etc/default/tailscaled
|
|
|
|
|
|
```
|
|
|
|
|
|
```
|
|
|
|
|
|
systemctl enable --now tailscaled
|
|
|
|
|
|
systemctl status tailscaled
|
|
|
|
|
|
```
|
|
|
|
|
|
#### Tailscale 接入 Headscale:
|
|
|
|
|
|
```
|
|
|
|
|
|
## 如果你是在自己的服务器上部署的,请将 <HEADSCALE_PUB_ENDPOINT> 换成你的 Headscale 公网 IP 或域名
|
|
|
|
|
|
|
|
|
|
|
|
tailscale up --login-server=http://47.106.140.17:8080 --accept-routes=true --accept-dns=false
|
|
|
|
|
|
|
2025-12-13 23:34:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
### 将其中的命令复制粘贴到服务段 headscale 所在机器的终端中,并将 USERNAME 替换为前面所创建的 user。
|
2025-12-13 23:27:12 +08:00
|
|
|
|
|
2025-12-13 23:34:24 +08:00
|
|
|
|
headscale nodes register --key ZR12m7dvnPUgbbfkx_FdMUvW --user cba
|
|
|
|
|
|
```
|
2025-12-13 23:27:12 +08:00
|
|
|
|
```
|
|
|
|
|
|
#### 注册成功,查看注册的节点:
|
|
|
|
|
|
```
|
|
|
|
|
|
# headscale nodes list
|
|
|
|
|
|
ID | Hostname | Name | MachineKey | NodeKey | User | IP addresses | Ephemeral | Last seen | Expiration | Connected | Expired
|
|
|
|
|
|
1 | localhost | localhost | [ZqdSj] | [qxtoU] | cba | 100.64.0.1, fd7a:115c:a1e0::1 | false | 2025-12-13 15:03:06 | 0001-01-01 00:00:00 | offline | no
|
|
|
|
|
|
2 | smb-kk | smb-kk | [6+OpS] | [ZOUQN] | abc | 100.64.0.2, fd7a:115c:a1e0::2 | false | 2025-12-13 14:42:15 | 0001-01-01 00:00:00 | online | no
|
|
|
|
|
|
|
2025-12-13 23:30:50 +08:00
|
|
|
|
```
|
|
|
|
|
|
#### 回到 Tailscale 客户端所在的 Linux 主机,可以看到 Tailscale 会自动创建相关的路由表和 iptables 规则。路由表可通过以下命令查看
|
|
|
|
|
|
```
|
|
|
|
|
|
# ip route show table 52
|
|
|
|
|
|
|
|
|
|
|
|
100.64.0.1 dev tailscale0
|
|
|
|
|
|
100.100.100.100 dev tailscale0
|
|
|
|
|
|
```
|
|
|
|
|
|
#### 查看 iptables 规则:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
# iptables -S
|
|
|
|
|
|
-P INPUT ACCEPT
|
|
|
|
|
|
-P FORWARD DROP
|
|
|
|
|
|
-P OUTPUT ACCEPT
|
|
|
|
|
|
-N DOCKER
|
|
|
|
|
|
-N DOCKER-BRIDGE
|
|
|
|
|
|
-N DOCKER-CT
|
|
|
|
|
|
-N DOCKER-FORWARD
|
|
|
|
|
|
-N DOCKER-ISOLATION-STAGE-1
|
|
|
|
|
|
-N DOCKER-ISOLATION-STAGE-2
|
|
|
|
|
|
-N DOCKER-USER
|
|
|
|
|
|
-N ts-forward
|
|
|
|
|
|
-N ts-input
|
|
|
|
|
|
-A INPUT -j ts-input
|
|
|
|
|
|
-A FORWARD -j ts-forward
|
|
|
|
|
|
-A FORWARD -j DOCKER-USER
|
|
|
|
|
|
-A FORWARD -j DOCKER-FORWARD
|
|
|
|
|
|
-A DOCKER ! -i docker0 -o docker0 -j DROP
|
|
|
|
|
|
-A DOCKER-BRIDGE -o docker0 -j DOCKER
|
|
|
|
|
|
-A DOCKER-CT -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
|
|
|
|
|
-A DOCKER-FORWARD -j DOCKER-CT
|
|
|
|
|
|
-A DOCKER-FORWARD -j DOCKER-ISOLATION-STAGE-1
|
|
|
|
|
|
-A DOCKER-FORWARD -j DOCKER-BRIDGE
|
|
|
|
|
|
-A DOCKER-FORWARD -i docker0 -j ACCEPT
|
|
|
|
|
|
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
|
|
|
|
|
|
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
|
|
|
|
|
|
-A DOCKER-USER -j RETURN
|
|
|
|
|
|
-A ts-forward -i tailscale0 -j MARK --set-xmark 0x40000/0xff0000
|
|
|
|
|
|
-A ts-forward -m mark --mark 0x40000/0xff0000 -j ACCEPT
|
|
|
|
|
|
-A ts-forward -s 100.64.0.0/10 -o tailscale0 -j DROP
|
|
|
|
|
|
-A ts-forward -o tailscale0 -j ACCEPT
|
|
|
|
|
|
-A ts-input -s 100.64.0.2/32 -i lo -j ACCEPT
|
|
|
|
|
|
-A ts-input -s 100.115.92.0/23 ! -i tailscale0 -j RETURN
|
|
|
|
|
|
-A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP
|
|
|
|
|
|
-A ts-input -i tailscale0 -j ACCEPT
|
|
|
|
|
|
-A ts-input -p udp -m udp --dport 41641 -j ACCEPT
|
2025-12-13 23:17:43 +08:00
|
|
|
|
```
|