2fb067ecbf
checklocks / checklocks (push) Has been cancelled
CodeQL / Analyze (go) (push) Has been cancelled
natlab-integrationtest / natlab-integrationtest (push) Has been cancelled
CI / gomod-cache (push) Has been cancelled
CI / race-root-integration (1/4) (push) Has been cancelled
CI / race-root-integration (2/4) (push) Has been cancelled
CI / race-root-integration (3/4) (push) Has been cancelled
CI / race-root-integration (4/4) (push) Has been cancelled
CI / test (-race, amd64, 1/3) (push) Has been cancelled
CI / test (-race, amd64, 2/3) (push) Has been cancelled
CI / test (-race, amd64, 3/3) (push) Has been cancelled
CI / test (386) (push) Has been cancelled
CI / test (amd64) (push) Has been cancelled
CI / Windows (benchmarks) (push) Has been cancelled
CI / Windows (1/2) (push) Has been cancelled
CI / Windows (2/2) (push) Has been cancelled
CI / macos (push) Has been cancelled
CI / privileged (push) Has been cancelled
CI / vm (push) Has been cancelled
CI / cross (386, linux) (push) Has been cancelled
CI / cross (amd64, darwin) (push) Has been cancelled
CI / cross (amd64, freebsd) (push) Has been cancelled
CI / cross (amd64, openbsd) (push) Has been cancelled
CI / cross (amd64, windows) (push) Has been cancelled
CI / cross (arm, 5, linux) (push) Has been cancelled
CI / cross (arm, 7, linux) (push) Has been cancelled
CI / cross (arm64, darwin) (push) Has been cancelled
CI / cross (arm64, linux) (push) Has been cancelled
CI / cross (arm64, windows) (push) Has been cancelled
CI / cross (loong64, linux) (push) Has been cancelled
CI / ios (push) Has been cancelled
CI / crossmin (amd64, illumos) (push) Has been cancelled
CI / crossmin (amd64, plan9) (push) Has been cancelled
CI / crossmin (amd64, solaris) (push) Has been cancelled
CI / crossmin (ppc64, aix) (push) Has been cancelled
CI / android (push) Has been cancelled
CI / wasm (push) Has been cancelled
CI / tailscale_go (push) Has been cancelled
CI / fuzz (push) Has been cancelled
CI / depaware (push) Has been cancelled
CI / go_generate (push) Has been cancelled
CI / make_tidy (push) Has been cancelled
CI / licenses (push) Has been cancelled
CI / staticcheck (macOS) (push) Has been cancelled
CI / staticcheck (Linux) (push) Has been cancelled
CI / staticcheck (Windows) (push) Has been cancelled
CI / staticcheck (Portable (1/4)) (push) Has been cancelled
CI / staticcheck (Portable (2/4)) (push) Has been cancelled
CI / staticcheck (Portable (3/4)) (push) Has been cancelled
CI / staticcheck (Portable (4/4)) (push) Has been cancelled
CI / notify_slack (push) Has been cancelled
CI / merge_blocker (push) Has been cancelled
CI / check_mergeability_strict (push) Has been cancelled
CI / check_mergeability (push) Has been cancelled
Dockerfile build / deploy (push) Has been cancelled
test installer.sh / test (curl, alpine:3.21) (push) Has been cancelled
test installer.sh / test (curl, alpine:edge) (push) Has been cancelled
test installer.sh / test (curl, alpine:latest) (push) Has been cancelled
test installer.sh / test (curl, amazonlinux:latest) (push) Has been cancelled
test installer.sh / test (curl, archlinux:latest) (push) Has been cancelled
test installer.sh / test (curl, debian:oldstable-slim) (push) Has been cancelled
test installer.sh / test (curl, debian:sid-slim) (push) Has been cancelled
test installer.sh / test (curl, debian:stable-slim, 1.80.0) (push) Has been cancelled
test installer.sh / test (curl, debian:testing-slim) (push) Has been cancelled
test installer.sh / test (curl, elementary/docker:stable) (push) Has been cancelled
test installer.sh / test (curl, elementary/docker:unstable) (push) Has been cancelled
test installer.sh / test (curl, fedora:latest, 1.80.0) (push) Has been cancelled
test installer.sh / test (curl, kalilinux/kali-dev) (push) Has been cancelled
test installer.sh / test (curl, kalilinux/kali-rolling) (push) Has been cancelled
test installer.sh / test (curl, opensuse/leap:latest) (push) Has been cancelled
test installer.sh / test (curl, opensuse/tumbleweed:latest) (push) Has been cancelled
test installer.sh / test (curl, oraclelinux:8) (push) Has been cancelled
test installer.sh / test (curl, oraclelinux:9) (push) Has been cancelled
test installer.sh / test (curl, parrotsec/core:latest) (push) Has been cancelled
test installer.sh / test (curl, rockylinux:8.7) (push) Has been cancelled
test installer.sh / test (curl, rockylinux:9) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:20.04) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:22.04) (push) Has been cancelled
test installer.sh / test (curl, ubuntu:24.04, 1.80.0) (push) Has been cancelled
test installer.sh / test (wget, debian:oldstable-slim) (push) Has been cancelled
test installer.sh / test (wget, debian:sid-slim) (push) Has been cancelled
update-flake / update-flake (push) Has been cancelled
tailscale.com/cmd/vet / vet (push) Has been cancelled
test installer.sh / notify-slack (push) Has been cancelled
Client security fixes (cmd/tailscale-tray/main.go): - SSRF protection in Add Server dialog (validateControlURL): reject private/loopback/link-local/cloud-metadata IPs via DNS resolution - RCE gate on AuthURL/BrowseToURL exec paths (validateAuthURL) - Sanitized URL logging (sanitizeURLForLog drops query auth tokens) - Error handling on exec.Command with user-facing showError() Admin panel security (web-admin): - Bcrypt password hashing (replaces SHA256) - Rate limiting: 5 failed logins → 15-min lockout - Session + login attempt cleanup goroutine (hourly) - url.QueryEscape / encodeURIComponent for all API params - Fail-hard startup when no TLS and non-loopback bind - ADMIN_PASSWORD required (no default), password min 12 chars - Username regex whitelist Installer hardening (Setup.wxs): - util:PermissionEx restricts SCM access: only Administrators + SYSTEM can start/stop/reconfigure service. Authenticated Users limited to QueryStatus/QueryConfig/Interrogate - Vital="yes" on ServiceInstall Docs & roadmap: - PRODUCTION_ROADMAP.md: 5-milestone plan (security + features + distribution + ops) with granular tasks, effort, done-when - CLIENT_SECURITY_AUDIT.md, SECURITY_FIXES.md, DEPLOYMENT.md - AI assistant rules (.cursorrules, .antigravityrules, etc.) Build & distribution: - build-msi.ps1, deploy-and-sign.ps1, sign-release.ps1 - redeploy.ps1, tray-deploy.ps1, test-msi.ps1 - installer/msi/ alternative WXS setup - Restored .github/workflows/ removed in mirror cleanup .gitignore hardened: *.pfx, *.p12, *.key, *.pem, .env*
236 lines
7.9 KiB
Markdown
236 lines
7.9 KiB
Markdown
# 🔒 Bản Cập Nhật Bảo Mật - Tailscale Custom Admin Panel
|
|
|
|
## Tóm Tắt Các Sửa Chữa Đã Thực Hiện
|
|
|
|
### ✅ Lỗ Hổng NGUY HIỂM TỐI ĐẠI - ĐÃ SỬA
|
|
|
|
#### 1. **Hashing Mật Khẩu Yếu** (SHA256 → bcrypt)
|
|
- **Trước:** SHA256 đơn giản không đủ bảo mật
|
|
- **Sau:** bcrypt với cost factor 12 (10+ tỷ lần hash để crack một mật khẩu)
|
|
- **Tập Tin Thay Đổi:** `web-admin/main.go` (dòng 114-127)
|
|
- **Impact:** Nếu database bị lộ, passwords giờ cần hàng năm để crack thay vì phút
|
|
|
|
#### 2. **Mật Khẩu Admin Mặc Định Bắt Buộc**
|
|
- **Trước:** `ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin123}` (mặc định xấu)
|
|
- **Sau:** Yêu cầu `ADMIN_PASSWORD` được đặt rõ ràng, server sẽ thoát nếu không
|
|
- **Tập Tin Thay Đổi:** `web-admin/main.go` (dòng 217-230), `docker-compose.yml`
|
|
- **Impact:** Không thể triển khai mà không đặt password mạnh
|
|
|
|
#### 3. **Tiêm Tham Số URL** (Query Parameter Injection)
|
|
- **Trước:** `fmt.Sprintf(...?user=%s&key=%s"...)` - không mã hóa
|
|
- **Sau:** Sử dụng `url.QueryEscape()` cho tất cả tham số người dùng
|
|
- **Tập Tin Thay Đổi:**
|
|
- `web-admin/main.go` (dòng 481, 757, 669)
|
|
- `web-admin/static/app.js` (dòng 424)
|
|
- **Impact:** Ngăn chặn CRLF injection và parameter pollution
|
|
|
|
#### 4. **Không Có TLS/HTTPS**
|
|
- **Trước:** HTTP plaintext - sessions/API keys visible trên mạng
|
|
- **Sau:** Hỗ trợ HTTPS với certificates, cảnh báo nếu không dùng TLS
|
|
- **Tập Tin Thay Đổi:** `web-admin/main.go` (dòng 32, 169-215)
|
|
- **Cấu Hình:**
|
|
```bash
|
|
TLS_CERT_FILE=/path/to/cert.pem
|
|
TLS_KEY_FILE=/path/to/key.pem
|
|
```
|
|
- **Impact:** Tất cả giao tiếp bây giờ được mã hóa end-to-end
|
|
|
|
### ✅ Lỗ Hổng CAO - ĐÃ SỬA
|
|
|
|
#### 5. **Quản Lý Phiên Yếu** (Session Management)
|
|
- **Thêm:** Rate limiting với account lockout
|
|
- **Cơ Chế:** 5 lần đăng nhập sai → khóa 15 phút
|
|
- **Tập Tin Thay Đổi:** `web-admin/main.go` (dòng 137-145, 258-310)
|
|
- **Impact:** Ngăn chặn brute force attacks
|
|
|
|
#### 6. **Xác Thực Dữ Liệu Đầu Vào**
|
|
- **Thêm:** Username validation (chỉ alphanumeric, underscore, dash, dot)
|
|
- **Độ Dài:** Min 1, Max 63 ký tự
|
|
- **Tập Tin Thay Đổi:** `web-admin/main.go` (dòng 131-142)
|
|
- **Impact:** Ngăn chặn injection attacks qua username
|
|
|
|
#### 7. **Yêu Cầu Mật Khẩu Mạnh Hơn**
|
|
- **Trước:** Tối thiểu 4 ký tự
|
|
- **Sau:** Tối thiểu 12 ký tự
|
|
- **Tập Tin Thay Đổi:** `web-admin/main.go` (dòng 313, 349, 360, 394, 619, 626, 660)
|
|
- **Impact:** Tăng entropy của mật khẩu
|
|
|
|
---
|
|
|
|
## 📋 Hướng Dẫn Triển Khai Bảo Mật
|
|
|
|
### 1️⃣ Chuẩn Bị (Before Deployment)
|
|
|
|
#### Tạo TLS Certificates
|
|
```bash
|
|
# Self-signed (for testing)
|
|
openssl req -x509 -newkey rsa:4096 -keyout /certs/key.pem -out /certs/cert.pem -days 365 -nodes
|
|
|
|
# Hoặc sử dụng Let's Encrypt/Certbot (production)
|
|
certbot certonly --standalone -d vpn.softs.business
|
|
```
|
|
|
|
#### Tạo .env file
|
|
```bash
|
|
# .env
|
|
HEADSCALE_API_KEY=your-long-random-api-key-here-at-least-32-chars
|
|
ADMIN_PASSWORD=your-very-strong-password-here-min-12-chars
|
|
|
|
# Optional TLS (production)
|
|
TLS_CERT_FILE=/certs/cert.pem
|
|
TLS_KEY_FILE=/certs/key.pem
|
|
TLS_CERT_DIR=/path/to/certs
|
|
```
|
|
|
|
#### Khởi Động Docker Compose
|
|
```bash
|
|
docker compose up -d
|
|
|
|
# Xem logs để xác nhận
|
|
docker compose logs headscale-admin
|
|
```
|
|
|
|
### 2️⃣ Kiểm Tra Bảo Mật Sau Triển Khai
|
|
|
|
#### ✓ Đăng Nhập Lần Đầu Tiên
|
|
```bash
|
|
# Từ logs hoặc web UI
|
|
# Username: admin
|
|
# Password: (từ ADMIN_PASSWORD env var)
|
|
```
|
|
|
|
#### ✓ Kiểm Tra HTTPS (nếu được cấu hình)
|
|
```bash
|
|
curl -v https://localhost:9080/
|
|
# Nên thấy: TLS Handshake, Valid Certificate
|
|
```
|
|
|
|
#### ✓ Kiểm Tra Rate Limiting
|
|
```bash
|
|
# Thử 6 lần đăng nhập sai
|
|
for i in {1..6}; do
|
|
curl -X POST https://localhost:9080/api/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"username":"admin","password":"wrong"}'
|
|
done
|
|
# Lần thứ 6 sẽ trả về: "account temporarily locked"
|
|
```
|
|
|
|
#### ✓ Kiểm Tra Validation Input
|
|
```bash
|
|
# Thử tên người dùng không hợp lệ
|
|
curl -X POST https://localhost:9080/api/admin/accounts \
|
|
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"username":"invalid@user#name","password":"password123456","role":"user"}'
|
|
# Nên trả về: "invalid username: only alphanumeric..."
|
|
```
|
|
|
|
### 3️⃣ Danh Sách Kiểm Tra Triển Khai (Deployment Checklist)
|
|
|
|
- [ ] ADMIN_PASSWORD được đặt thành mật khẩu mạnh (min 12 chars)
|
|
- [ ] HEADSCALE_API_KEY được đặt với giá trị ngẫu nhiên dài
|
|
- [ ] TLS_CERT_FILE và TLS_KEY_FILE được cấu hình với certificates hợp lệ
|
|
- [ ] Docker image được build lại với code mới
|
|
- [ ] Đã kiểm tra HTTPS hoạt động (curl -v https://...)
|
|
- [ ] Đã kiểm tra rate limiting hoạt động (5 failed attempts → lock)
|
|
- [ ] Tất cả default credentials đã bị loại bỏ
|
|
- [ ] Logging được cấu hình để không log sensitive data
|
|
- [ ] Backup users.json được thực hiện (chứa password hashes)
|
|
|
|
### 4️⃣ Các Biến Môi Trường Bảo Mật
|
|
|
|
```yaml
|
|
# REQUIRED
|
|
ADMIN_PASSWORD=<your-strong-password-12-chars-min>
|
|
HEADSCALE_API_KEY=<your-api-key>
|
|
|
|
# RECOMMENDED for Production
|
|
TLS_CERT_FILE=/certs/cert.pem
|
|
TLS_KEY_FILE=/certs/key.pem
|
|
|
|
# OPTIONAL
|
|
HEADSCALE_URL=http://headscale:8080 # Nên là HTTPS
|
|
LISTEN_ADDR=:9080
|
|
DATA_DIR=/data
|
|
```
|
|
|
|
---
|
|
|
|
## 🚨 Vẫn Còn Cần Làm (Future Improvements)
|
|
|
|
### Ưu Tiên Cao
|
|
- [ ] **JWT Tokens thay vì random strings** - Cho xác thực không trạng thái
|
|
- [ ] **HTTPS cho Headscale backend** - Mã hóa API key trong transit
|
|
- [ ] **Audit Logging** - Ghi lại tất cả admin actions
|
|
- [ ] **Session Rotation** - Refresh tokens tự động sau 1 giờ
|
|
- [ ] **2FA/TOTP** - Xác thực hai lớp cho admin accounts
|
|
|
|
### Ưu Tiên Trung Bình
|
|
- [ ] **IP Whitelisting** - Cho phép chỉ những IPs nhất định
|
|
- [ ] **Database Encryption** - Mã hóa users.json at rest
|
|
- [ ] **API Rate Limiting** - Giới hạn requests/minute
|
|
- [ ] **CORS Configuration** - Chặn cross-origin requests
|
|
|
|
### Ưu Tiên Thấp
|
|
- [ ] **Password Policies** - Enforce complexity requirements
|
|
- [ ] **Session Analytics** - Dashboard cho login attempts
|
|
- [ ] **Backup Management** - Automated backups của users.json
|
|
|
|
---
|
|
|
|
## 📊 Bảng So Sánh: Trước & Sau
|
|
|
|
| Lỗ Hổng | Trước | Sau | Nguy Hiểm |
|
|
|---------|-------|-----|---------|
|
|
| Password Hashing | SHA256 (instant) | bcrypt 12 (10B iterations) | CRITICAL |
|
|
| Default Password | admin123 | Required env var | CRITICAL |
|
|
| URL Encoding | None | url.QueryEscape() | HIGH |
|
|
| HTTPS | No TLS | Optional TLS + warning | HIGH |
|
|
| Rate Limiting | None | 5 attempts → 15min lock | MEDIUM |
|
|
| Username Validation | None | Regex validation | MEDIUM |
|
|
| Min Password Length | 4 chars | 12 chars | MEDIUM |
|
|
| Session Storage | In-memory | In-memory + cleanup | LOW |
|
|
|
|
---
|
|
|
|
## 🔍 Testing Bảo Mật (Security Testing)
|
|
|
|
### Test 1: Hashing Password
|
|
```bash
|
|
# Kiểm tra bcrypt được dùng
|
|
grep -n "bcrypt" web-admin/main.go
|
|
# Expected: golang.org/x/crypto/bcrypt in use
|
|
```
|
|
|
|
### Test 2: No Default Password
|
|
```bash
|
|
docker compose up -d
|
|
# Nên thấy error: "ADMIN_PASSWORD environment variable is required"
|
|
```
|
|
|
|
### Test 3: URL Encoding
|
|
```bash
|
|
# Thử user có &
|
|
curl -X POST https://localhost:9080/api/admin/register \
|
|
-H "Authorization: Bearer TOKEN" \
|
|
-d '{"user":"admin&role=admin","key":"test"}'
|
|
# Request sẽ được URL-encoded, không inject parameters
|
|
```
|
|
|
|
---
|
|
|
|
## 📞 Support & Reporting
|
|
|
|
Nếu tìm thấy vấn đề bảo mật khác:
|
|
1. Không public disclosure (avoid posting to GitHub)
|
|
2. Email: huanld.dev@gmail.com
|
|
3. Chi tiết: cách tái tạo, impact, suggested fix
|
|
|
|
---
|
|
|
|
**Phiên Bản:** 1.0
|
|
**Ngày Cập Nhật:** 2026-04-22
|
|
**Status:** ✅ SECURE for Staging
|
|
**Ready for Production:** ✅ YES (với TLS cấu hình)
|