diff --git a/config/config.yaml b/config/config.yaml index e5786d4..a4691c6 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -1,233 +1,249 @@ --- -# headscale will look for a configuration file named `config.yaml` (or `config.json`) in the following order: -# -# - `/etc/headscale` -# - `~/.headscale` -# - current working directory +# ============================================================================ +# Headscale 設定檔 +# 檔案搜尋順序:/etc/headscale → ~/.headscale → 當前工作目錄 +# ============================================================================ + + +# ---------------------------------------------------------------------------- +# 伺服器與監聽位址 +# ---------------------------------------------------------------------------- # server_url: 給客戶端連線用的網址 -# server_url: http://127.0.0.1:8080 server_url: https://headscale.lotimmy.com -# listen_addr: Headscale 綁定在哪個 IP:Port 等待連線 -# listen_addr: 127.0.0.1:8080 +# listen_addr: Headscale HTTP API 綁定的 IP:Port listen_addr: 0.0.0.0:8080 -# metrics_listen_addr: 提供 Prometheus 或其他監控系統抓取 metrics 的位址 -# metrics_listen_addr: 127.0.0.1:9090 +# metrics_listen_addr: Prometheus/監控系統抓取 metrics 的位址 metrics_listen_addr: 0.0.0.0:9090 -# grpc_listen_addr: Headscale 提供 gRPC API 的服務位址,通常給內部或管理工具使用 +# grpc_listen_addr: gRPC API 服務位址(給內部或管理工具使用) grpc_listen_addr: 0.0.0.0:50443 -# grpc_listen_addr: 127.0.0.1:50443 -# grpc_allow_insecure: 是否允許 gRPC 使用未加密連線(建議保持 false 確保安全) +# grpc_allow_insecure: 是否允許 gRPC 未加密連線(建議保持 false) grpc_allow_insecure: false -# noise: Headscale 使用 Noise 協議加密與客戶端的流量 +# unix_socket: 本地 UNIX Socket 路徑 +unix_socket: /var/run/headscale/headscale.sock +# unix_socket_permission: UNIX Socket 權限設定 +unix_socket_permission: "0770" + + +# ---------------------------------------------------------------------------- +# Noise 加密協議 +# ---------------------------------------------------------------------------- + noise: # private_key_path: Noise 私鑰路徑,缺少時會自動生成 private_key_path: /var/lib/headscale/noise_private.key -# prefixes: 設定分配給節點的 IP 範圍(必須在 Tailscale 支援的範圍內) + +# ---------------------------------------------------------------------------- +# IP 位址分配(必須位於 Tailscale 支援的範圍內) +# ---------------------------------------------------------------------------- + prefixes: # v4: IPv4 分配範圍(預設 100.64.0.0/10) v4: 100.64.0.0/10 # v6: IPv6 分配範圍(預設 fd7a:115c:a1e0::/48) v6: fd7a:115c:a1e0::/48 - - # allocation: IP 分配策略(sequential 依序分配,random 隨機分配) + # allocation: 分配策略(sequential 依序 / random 隨機) allocation: sequential -# derp: DERP 是 Tailscale 用來在無法直連時的中繼伺服器設定 + +# ---------------------------------------------------------------------------- +# DERP 中繼伺服器(直連失敗時的備援通道) +# ---------------------------------------------------------------------------- + derp: - # server: 內建的 DERP 伺服器設定 server: # enabled: 是否啟用內建 DERP(需要 https/TLS) - enabled: false + enabled: true - # region_id: 內建 DERP 的區域 ID(避免與其他 DERP 衝突) + # region_id: 內建 DERP 區域 ID(避免與其他 DERP 衝突) region_id: 999 + # region_code: 區域代碼(顯示於 Tailscale UI) + region_code: "tw" + # region_name: 區域名稱(顯示於 Tailscale UI) + region_name: "Headscale TW" - # region_code: 區域代碼(會顯示在 Tailscale UI) - region_code: "headscale" - # region_name: 區域名稱(會顯示在 Tailscale UI) - region_name: "Headscale Embedded DERP" - - # stun_listen_addr: STUN 服務的監聽位址(協助 NAT 穿透) + # stun_listen_addr: STUN 服務監聽位址(協助 NAT 穿透) stun_listen_addr: "0.0.0.0:3478" - # private_key_path: 內建 DERP 使用的私鑰路徑,沒有會自動生成 + # private_key_path: 內建 DERP 私鑰路徑,缺少時自動生成 private_key_path: /var/lib/headscale/derp_server_private.key - # automatically_add_embedded_derp_region: 是否自動把內建 DERP 加進 DERP map + # automatically_add_embedded_derp_region: 自動把內建 DERP 加進 DERP map automatically_add_embedded_derp_region: true - # ipv4: 可選,將公開 IPv4 加入 DERP map(改善 Exit-Node 或 DNS 問題時的連線穩定性) - ipv4: 1.2.3.4 - # ipv6: 可選,將公開 IPv6 加入 DERP map - ipv6: 2001:db8::1 + # ipv4 / ipv6: 公開 IP(改善 Exit-Node 或 DNS 問題時的連線穩定性) + ipv4: 125.229.110.50 + ipv6: 2001:b011:3012:373a:be24:11ff:fe40:a31a # urls: 外部可用的 DERP map JSON 清單 urls: - https://controlplane.tailscale.com/derpmap/default - # paths: 本地的 DERP map YAML 檔路徑(通常用在自建 DERP 伺服器) + # paths: 本地 DERP map YAML 檔路徑(自建 DERP 伺服器使用) paths: [] - # auto_update_enabled: 是否自動定期更新 DERP map + # auto_update_enabled: 自動定期更新 DERP map auto_update_enabled: true - # update_frequency: DERP map 更新檢查頻率 update_frequency: 24h -# disable_check_updates: 是否停用 Headscale 啟動時自動檢查更新 -disable_check_updates: false -# ephemeral_node_inactivity_timeout: 臨時節點(ephemeral node)多久沒活動就自動刪除 -# ⚠️ 此鍵已於新版 Headscale 移除,改名為 node.ephemeral.inactivity_timeout(預設仍為 30m)。 -# 保留 30m 預設行為,故直接停用本鍵;如需自訂請改用新的 node.ephemeral.inactivity_timeout 區塊。 -# ephemeral_node_inactivity_timeout: 30m +# ---------------------------------------------------------------------------- +# 資料庫 +# ---------------------------------------------------------------------------- database: - # type: 資料庫類型(可選 sqlite 或 postgres,建議用 sqlite) + # type: 資料庫類型(sqlite / postgres,建議 sqlite) type: sqlite - # debug: 是否啟用資料庫偵錯(需搭配 log.level=debug/trace) + # debug: 啟用資料庫偵錯(需搭配 log.level=debug/trace) debug: false gorm: - # prepare_stmt: 是否啟用 prepared statements + # prepare_stmt: 啟用 prepared statements prepare_stmt: true - - # parameterized_queries: 是否啟用參數化查詢(提升安全性與效能) + # parameterized_queries: 啟用參數化查詢(安全性與效能) parameterized_queries: true - - # skip_err_record_not_found: 是否略過「record not found」錯誤訊息 + # skip_err_record_not_found: 略過「record not found」錯誤訊息 skip_err_record_not_found: true - # slow_threshold: 慢查詢閾值(毫秒) slow_threshold: 1000 sqlite: - # path: SQLite 資料庫檔案的存放路徑 + # path: SQLite 資料庫檔案路徑 path: /var/lib/headscale/db.sqlite - - # write_ahead_log: 是否啟用 WAL 模式(建議正式環境開啟,效能與穩定性更好) + # write_ahead_log: 啟用 WAL 模式(正式環境建議開啟) write_ahead_log: true - - # wal_autocheckpoint: WAL 自動 checkpoint 閾值(單位 frame,0 代表停用自動 checkpoint) + # wal_autocheckpoint: WAL 自動 checkpoint 閾值(frame,0 代表停用) wal_autocheckpoint: 1000 -# acme_url: ACME 伺服器 URL(預設使用 Let's Encrypt) -acme_url: https://acme-v02.api.letsencrypt.org/directory -# acme_email: 註冊 ACME 憑證時的聯絡 email +# ---------------------------------------------------------------------------- +# TLS / ACME 憑證 +# ---------------------------------------------------------------------------- + +# acme_url: ACME 伺服器 URL(預設 Let's Encrypt) +acme_url: https://acme-v02.api.letsencrypt.org/directory +# acme_email: 註冊 ACME 憑證的聯絡 email acme_email: "" # tls_letsencrypt_hostname: 要申請憑證的網域名稱 tls_letsencrypt_hostname: "" - -# tls_letsencrypt_cache_dir: 存放憑證與 metadata 的路徑 +# tls_letsencrypt_cache_dir: 憑證與 metadata 存放路徑 tls_letsencrypt_cache_dir: /var/lib/headscale/cache - -# tls_letsencrypt_challenge_type: ACME 驗證方式(支援 HTTP-01 或 TLS-ALPN-01) +# tls_letsencrypt_challenge_type: ACME 驗證方式(HTTP-01 或 TLS-ALPN-01) tls_letsencrypt_challenge_type: HTTP-01 -# tls_letsencrypt_listen: HTTP-01 驗證時使用的監聽位址(預設 80 port) +# tls_letsencrypt_listen: HTTP-01 驗證監聽位址 tls_letsencrypt_listen: ":http" -# tls_cert_path: 已有憑證的檔案路徑(選填,不用 Let's Encrypt 時使用) +# tls_cert_path / tls_key_path: 既有憑證路徑(不使用 Let's Encrypt 時填寫) tls_cert_path: "" -# tls_key_path: 已有私鑰的檔案路徑(選填,不用 Let's Encrypt 時使用) tls_key_path: "" + +# ---------------------------------------------------------------------------- +# 日誌 +# ---------------------------------------------------------------------------- + log: - # format: 日誌輸出格式(text 或 json) + # format: 輸出格式(text / json) format: text - # level: 日誌等級(常見有 debug、info、warn、error) + # level: 日誌等級(debug / info / warn / error) level: info +# logtail: 是否把 client 日誌送到 Tailscale 官方伺服器(預設關閉) +logtail: + enabled: false + + +# ---------------------------------------------------------------------------- +# ACL 政策 +# ---------------------------------------------------------------------------- + policy: - # mode: ACL 政策儲存方式(可選 file 或 database) + # mode: ACL 儲存方式(file / database) mode: file - # path: 當 mode=file 時,ACL HuJSON 檔案的路徑 + # path: mode=file 時的 HuJSON 檔案路徑 path: /etc/headscale/policy.hujson +# ---------------------------------------------------------------------------- +# DNS 與 MagicDNS +# ---------------------------------------------------------------------------- + dns: - # 啟用 MagicDNS,讓節點自動有 hostname + # magic_dns: 啟用 MagicDNS,讓節點自動取得 hostname magic_dns: true - # 要確定和 headscale server_url 不同網域,例如: - # base_domain: example.com + # base_domain: MagicDNS 基底網域(須與 server_url 網域不同) base_domain: internal.lotimmy.com - # override_local_dns: 是否強制使用 Headscale 的 DNS,覆蓋本地設定 - # 如果希望 tailnet 裡所有節點都「強制」走這組 DNS,建議改成 true - # 若你還想保留各節點自己的 DNS(例如公司 VPN、家裡路由器內網),就維持 false + # override_local_dns: 是否強制 tailnet 節點使用以下 DNS,覆蓋本地設定 + # true → 所有節點強制走這組 DNS + # false → 保留各節點自己的 DNS(例如公司 VPN、家用路由器內網) override_local_dns: true # nameservers.global: 全域 DNS 伺服器清單 nameservers: global: + # NextDNS(個人 DoH Profile,含封鎖清單與過濾規則) + - https://dns.nextdns.io/9c7b19 - # NextDNS(你的專屬 DoH Profile) - - https://dns.nextdns.io/9c7b19 # NextDNS DoH:完整支援你的個人設定、封鎖清單、過濾規則 + # NextDNS 傳統 IPv4(fallback) + - 45.90.28.37 + - 45.90.30.37 - # NextDNS IPv4 傳統 DNS(可作 fallback) - - 45.90.28.37 # NextDNS IPv4 主 DNS - - 45.90.30.37 # NextDNS IPv4 副 DNS + # Cloudflare DNS(快速、穩定) + - 1.1.1.1 + - 1.0.0.1 + - 2606:4700:4700::1111 + - 2606:4700:4700::1001 + - https://cloudflare-dns.com/dns-query + # Google DNS(高穩定度 fallback) + - https://dns.google/dns-query - # Cloudflare DNS(快速+穩定) - - 1.1.1.1 # Cloudflare IPv4 主 DNS(fallback) - - 1.0.0.1 # Cloudflare IPv4 副 DNS - - 2606:4700:4700::1111 # Cloudflare IPv6 主 DNS - - 2606:4700:4700::1001 # Cloudflare IPv6 副 DNS - - https://cloudflare-dns.com/dns-query # Cloudflare DoH:快速+加密 + # Quad9 DNS(側重惡意網站過濾) + - https://dns.quad9.net/dns-query - # Google DNS(可靠但不做安全過濾) - - https://dns.google/dns-query # Google DoH:高穩定度 fallback + # nameservers.split: Split DNS,針對特定網域指定 DNS + split: {} + # 範例: + # foo.bar.com: + # - 1.1.1.1 + # darp.headscale.net: + # - 1.1.1.1 + # - 8.8.8.8 - # Quad9 DNS(帶惡意網站安全過濾) - - https://dns.quad9.net/dns-query # Quad9 DoH:側重惡意網站與安全防護 - - # nameservers.split: Split DNS,每個網域指定不同 DNS 伺服器 - split: - {} - # foo.bar.com: - # - 1.1.1.1 - # darp.headscale.net: - # - 1.1.1.1 - # - 8.8.8.8 - - # search_domains: 自訂搜尋網域(啟用 MagicDNS 時,base_domain 會自動加在最前面) + # search_domains: 自訂搜尋網域(啟用 MagicDNS 時會自動加入 base_domain) search_domains: [] - # Extra DNS records - # so far only A and AAAA records are supported (on the tailscale side) - # See: docs/ref/dns.md - # extra_records: 額外的 DNS 紀錄(支援 A 與 AAAA,可用檔案或直接寫在這裡) + # extra_records: 額外 DNS 紀錄(目前僅支援 A 與 AAAA) + # 詳見 docs/ref/dns.md extra_records: [] # - name: "grafana.myvpn.example.com" # type: "A" # value: "100.64.0.3" - # - { name: "prometheus.myvpn.example.com", type: "A", value: "100.64.0.3" } - # extra_records_path: 額外 DNS 紀錄的 JSON 檔路徑(檔案變更時會自動載入) + # extra_records_path: 額外 DNS 紀錄 JSON 檔案路徑(檔案變更時自動載入) # extra_records_path: /var/lib/headscale/extra-records.json -# unix_socket: Headscale 提供本地 UNIX Socket 的路徑 -unix_socket: /var/run/headscale/headscale.sock -# unix_socket_permission: UNIX Socket 的權限設定(例如 0770) -unix_socket_permission: "0770" -logtail: - # enabled: 是否啟用 Logtail,把 client 日誌送到 Tailscale 官方伺服器(預設關閉) - enabled: false +# ---------------------------------------------------------------------------- +# 其他雜項 +# ---------------------------------------------------------------------------- -# randomize_client_port: 是否隨機使用 WireGuard port(預設 41641,開啟後會隨機挑 port,主要解決防火牆相容問題) -# ⚠️ 此頂層鍵已於新版 Headscale 移除,啟動會直接 FATAL(導致容器無限重啟)。 -# 新版改為在 policy 檔頂層設定 "randomizeClientPort": true(見 policy.path / policy.mode), -# 或用 nodeAttrs 針對個別節點授權。一般家用情境不需要,維持預設即可。 -# randomize_client_port: true +# disable_check_updates: 停用 Headscale 啟動時自動檢查更新 +disable_check_updates: false + +# ephemeral_node_inactivity_timeout: 臨時節點閒置多久後自動刪除 +ephemeral_node_inactivity_timeout: 30m + +# randomize_client_port: 隨機選擇 WireGuard port(預設 41641),有助穿越嚴格防火牆 +# randomize_client_port: # removed in new headscale; moved to policy file true diff --git a/docker-compose.yml b/docker-compose.yml index f5a43c0..a8bbe3d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,8 @@ services: headscale: - # 釘版本避免 watchtower 自動套用破壞性更新(見 OPERATIONS.md → 故障排除)。 - # 升級時手動改 tag 並先看 CHANGELOG 的 BREAKING 段落。 image: headscale/headscale:v0.29.0 container_name: headscale + command: serve restart: unless-stopped networks: - shared-net @@ -14,7 +13,7 @@ services: # 健康檢查 healthcheck: - test: ["CMD-SHELL", "headscale version >/dev/null 2>&1 || exit 1"] + test: ["CMD", "headscale", "version"] interval: 30s timeout: 10s retries: 3 @@ -38,6 +37,7 @@ services: - "8080:8080" # HTTP API - "9090:9090" # Metrics - "50443:50443" # gRPC + - "3478:3478/udp" # DERP STUN # 標籤配置 labels: