# 暑期實習 結業報告
## 報告架構
* 報告 10 分鐘
* 工作內容 8 分鐘
* 建議事項 2 分鐘
* Q\&A 5 分鐘
---
## Part 1: Basic
----
### `about.me`
鍾詠傑 Jie Chung
* 台南人
* 來自師大資工系
* github: [G36maid](https://github.com/G36maid?tab=repositories)
* linkedin: [yung-chieh-chung](https://www.linkedin.com/in/yung-chieh-chung-a114b02b2/)
* 部門:Networking Software Dept. 3 Section 4
----
### `about.me` :
* OS: Arch Linux
* 專長:Linux kernel, OS
* 語言: Rust, C/C++
* 虛擬化: Docker, K8S, PVE
* 自架: NAS, switch, Firewal
* 開源愛好者,盡可能使用 FOSS
---
### 先備知識
* 公司產品 Moxa Remote Connect ->
* MRC Quick Link Ultra ->
* vpncloud-service ->
* Headscale
* Headscale = 自架版 Tailscale 控制伺服器
* Tailscale = 自帶內網穿透的 VPN 客戶端
一個是頭(Head),一個是尾(Tail)
---
## Part 2: Works
----
### 問題背景
現況:
* 公司基於 Headscale v0.22.3 開發許多 feature
* 上游已更新至 v0.26,版本差距逐漸擴大
挑戰:
* 自有功能與上游版本分離,難以同步更新
* 錯失上游的新功能、效能優化、安全性修復
目標:
* 評估上游新版本的可移植性
* 在保持現有功能的前提下升級版本
* 降低未來維護成本
----
### 我的任務
1. 確認版本變化
2. 發現大規模重構
3. ~~抽取現有功能 (features)~~
4. ~~在新版 Headscale 上重新實作~~
5. ~~保持 相容性 + 行為一致~~
----
結構比較圖:
```bash
├── hscontrol
│ ├── acls.go
│ ├── acls_types.go
│ ├── api_common.go
│ ├── api.go
│ ├── api_key.go
│ ├── app.go
│ ├── config.go
│ ├── db.go
│ ├── derp.go
│ ├── derp_server.go
│ ├── dns.go
│ ├── grpcv1.go
│ ├── handler_legacy.go
│ ├── handler_placeholder.go
│ ├── machine.go
│ ├── matcher.go
│ ├── metrics.go
│ ├── noise.go
│ ├── oidc.go
│ ├── platform_config.go
│ ├── preauth_keys.go
│ ├── protocol_common.go
│ ├── protocol_common_poll.go
│ ├── protocol_common_utils.go
│ ├── protocol_legacy.go
│ ├── protocol_legacy_poll.go
│ ├── protocol_noise.go
│ ├── protocol_noise_poll.go
│ ├── routes.go
│ ├── templates
│ │ ├── apple.html
│ │ └── windows.html
│ ├── users.go
│ └── utils.go****
```
----
```bash
── hscontrol
│ ├── app.go
│ ├── assets
│ │ └── oidc_callback_template.html
│ ├── auth.go
│ ├── auth_noise.go
│ ├── cache.go
│ ├── db
│ │ ├── api_key.go
│ │ ├── db.go
│ │ ├── ip.go
│ │ ├── node.go
│ │ ├── policy.go
│ │ ├── preauth_keys.go
│ │ ├── routes.go
│ │ └── users.go
│ ├── derp
│ │ ├── derp.go
│ │ └── server
│ │ └── derp_server.go
│ ├── grpcv1.go
│ ├── handlers.go
│ ├── mapper
│ │ ├── mapper.go
│ │ └── tail.go
│ ├── metrics.go
│ ├── noise.go
│ ├── notifier
│ │ ├── metrics.go
│ │ └── notifier.go
│ ├── oidc.go
│ ├── platform_config.go
│ ├── policy
│ │ ├── acls.go
│ │ ├── acls_types.go
│ │ └── matcher
│ │ └── matcher.go
│ ├── poll.go
│ ├── tailsql.go
│ ├── templates
│ │ ├── apple.html
│ │ └── windows.html
│ ├── types
│ │ ├── api_key.go
│ │ ├── common.go
│ │ ├── config.go
│ │ ├── const.go
│ │ ├── node.go
│ │ ├── policy.go
│ │ ├── preauth_key.go
│ │ ├── routes.go
│ │ └── users.go
│ └── util
│ ├── addr.go
│ ├── const.go
│ ├── dns.go
│ ├── file.go
│ ├── key.go
│ ├── log.go
│ ├── net.go
│ ├── string.go
│ └── util.go
```
----
我的任務
1. 確認版本變化
2. 發現大規模重構
3. 抽取現有功能 (features)
4. 在新版 Headscale 上重新實作
5. 保持 **相容性** + **行為一致**
----
### ported features (舉例)
1. notifier client 統一管理架構
2. cluster sync via DB
3. login process change(純 ported)
4. acl config api(ported+test)
----
#### Notifier 統一通知機制
舊版問題:
* 每個 client 各自建立 goroutine 輪詢 server
* 各自管理資料狀態,頻繁進行 DB 讀寫
新版改進:
* 引入統一的 Notifier 架構
* 透過 Go Channel 集中管理事件通知
* 支援多種通知模式:
* `notifierWithNodeID` - 特定節點通知
* `notifierWithIgnore` - 排除特定節點
* `notifierAll` - 廣播通知
因此我在移植 features 的時候都會多利用 notifier 來通知節點進行更新
效果:大幅減少 DB 讀寫,提升整體效能
圖片:todo
----
#### Cluster 同步機制優化
舊版實作:
* 完全仰賴共享 DB 進行同步
* 各節點定期檢查 DB 時間戳
* 主動輪詢更新,頻繁 DB 存取
新版改進:
* 保留時間戳機制確保資料一致性
* 結合 Notifier 進行事件驅動同步
* 只在接收通知時才進行 DB 讀寫
效果:從輪詢改為推送,大幅減少不必要的 DB 操作
圖片:todo
----
#### Login Process 調整
變更內容:
* 配合新版 authentication 流程
* 保持與舊版相同的登入行為
* 確保 API 回應格式一致性
* 新增 `GetNodeByAnyKeyAndAuthKeyAndHostname` 方法支援多種認證方式
實作方式:
* 直接移植舊版邏輯到新架構
* 實作靈活的節點查找機制,支援不同的 Key 和認證組合
----
#### ACL Config API 移植
問題:新版 Headscale 沒有所有 ACL Policy 相關 API
解決方案:
* 重新實作完整的 gRPC API
* 適配新版內部邏輯結構
* 保持 API 介面向下相容
驗證方式:
* 使用 Postman 進行完整 API 測試
* 確認 ACL Policy 行為與舊版一致
----
### 本地部署測試
測試挑戰:
* Quick Link Ultra 為多服務架構
* 需要 cluster server + 多個 client 環境
* 必須驗證 control plane 行為一致性
測試方案:
* 使用 Docker Compose 建構完整測試環境
* 模擬生產環境的服務互動
* 對比新舊版本行為差異
測試工具:
* LazyDocker - 容器管理與監控
* Postman - API 功能驗證
圖片:todo
----
### 完成進度
已完成功能移植:
- [x] headscale-cluster local deployment
- [x] Sync by DB for Cluster
- [x] ACL Config Auto reload
- [x] ACL Related APIs
- [x] Add routes/peers cache mechanism for reduce db query
- [x] Add PreAuth Key Tag Lock mechanism
- [x] Confirm whether v0.23.0 supports “PeersRemoved” in MapResponse
- [X] Support for transparent mode
- [x] Adjust routes mechanism
- 8/12
- [x] Binding Node with PreAuth Key
- 8/15
- [X] PreAuthKey Related APIs
- [X] ExpireNode Related APIs
- 8/15
- [X] Implement API for Disconnect Actively
- [X] assign vpn ip by tag
- 8/15
- [X] include destination node's routes when parse ACL Policy
- 8/22
- [X] Support environment variable format in the db settings of config.yaml
- 8/22
後續工作:
* 在類生產環境進行整合測試
* 效能基準測試與調優
---
## Part 3: LLM & AI Tools
### 我的開發工具
* DevTool:
* Zed / Vim (Editor)
* LazyGit (Git flow)
* Tmux
* opencode
* Markdown (docs/spec)
* TestTool:
* Docker Compose
* LazyDocker
* Postman
* //Github Action
----
### models:
1. Gemini:有最大的上下文窗口
2. 分析 code base / diff,
3. 建立實作計畫/spec(markdown)
3. Claude:最強大的程式設計模型
4. 依計畫/spec實作、
5. 修 bug(配合 LSP)
6. Run diagnosis/ integration test
5. GPT:最便宜,無限制使用
5. 用來改文件 / 格式化報告
6. 生成 commit message,
----
### 心得
* LLM 無法維持清晰的 mental model
* 我常能在 2 天內完成一個功能移植
* 但測試場景不足,容易忽略 業務邏輯
* 缺乏邏輯上的文件,需靠與 mentor meeting 補齊
* 如果能有建立公司需求邏輯的文件/註解的 markdown 文檔
* 或是使用 MCP 可以解決這個問題
---
## Part 4: 公司心得
* 技術面:接觸到大規模專案與企業需求整合
* 工作方式:學習如何在不完整需求下進行開發
* 成長點:理解「開發 ≠ 完成功能」,而是「對齊實際業務場景」
---
## Part 5: 建議事項 (給 Moxa)
1. 文件化流程:補齊 feature 背後的 業務邏輯文件
* 降低新進人員理解成本(而不是去爬 commit message)
* 或許已經有關掉的 jira ticket 但是我不好找
2. LLM 開發指引:
* 讓工程師能安全地提升效率
* MOXA MCP server ?
* jira MCP ?
---
## Q\&A
預設問題 (你可以準備答案):
* 為什麼選擇用 LLM 而不是自己寫?
* 你怎麼確保新版 feature 的相容性?
* 你認為上游 Headscale 的重構方向正確嗎?
* 這段實習最大的收穫是什麼?
{"title":"暑期實習 結業報告","description":"報告時間15分鐘:報告10分鐘(工作8分鐘 + 對Moxa建議事項 2分鐘)+ Q&A 5分鐘","contributors":"[{\"id\":\"8db22c7a-01d1-4d31-a16d-380a780b14c4\",\"add\":34665,\"del\":26698,\"latestUpdatedAt\":1756281607302}]"}