Tài liệu
Cách hệ thống hoạt động và cách dùng nó. Mọi con số dưới đây là giá trị đang chạy thật, không phải ví dụ.
Sản phẩm này giải quyết gì
Đây là control plane cho việc sao lưu: một chỗ để khai chính sách, phát xuống nhiều máy, và trả lời được câu hỏi khó nhất của mọi hệ thống backup — đêm qua máy nào KHÔNG sao lưu được?
Chạy được một script rclone trên từng máy là chuyện dễ. Cái khó là sau sáu tháng, khi có 40 máy, không ai còn biết máy nào đang chạy bản script nào, máy nào đã im lặng ba tuần, và cảnh báo của máy nào đang gửi vào một nhóm chat không còn ai đọc.
Nguyên tắc nền
Ba thành phần
Giữ chính sách, cấp URL ký sẵn, gom nhật ký, phát cảnh báo. Là nơi duy nhất cầm khoá kho lưu trữ.
Quét thư mục, đẩy tệp thẳng lên kho lưu trữ, báo kết quả về. Không mở cổng nào — luôn là bên gọi đi.
Khai cấu hình, duyệt máy mới, đọc cảnh báo và nhật ký.
Một vòng chạy đầy đủ:
- 1.Agent gọi về server (agent luôn chủ động, server không gọi ngược)
- 2.Server trả config đã resolve + lệnh đang chờ
- 3.Tới giờ theo lịch, agent quét thư mục nguồn
- 4.Với tệp đã đổi, agent xin URL ký sẵn cho từng tệp
- 5.Agent PUT thẳng lên kho lưu trữ — dữ liệu KHÔNG đi qua server
- 6.Agent xác nhận, server cập nhật chỉ mục và trạng thái
Dữ liệu không đi qua server là chủ ý: một server 2 vCPU không thể làm trạm trung chuyển cho 40 máy cùng đẩy vài trăm GB.
Bắt đầu trong 5 bước
- 1Đặt khoá mã hoá cho server
Không có
STORAGE_KEYthì server từ chối lưu khoá kho lưu trữ và bot token — nó không ghi plaintext làm phương án thay thế.STORAGE_KEY=$(openssl rand -base64 32)
Mất khoá này là mất khả năng giải mã mọi secret đã lưu. Cất cùng chỗ với mật khẩu database.
- 2Khai kho lưu trữ
Cấu hình → Kho lưu trữ. Khai một hồ sơ storage — endpoint, region, bucket khai một lần rồi chọn lại ở mọi lớp, khỏi gõ lại ở từng nơi.
Khoá truy cập nằm bên dưới hồ sơ, được mã hoá AES-256-GCM trước khi ghi và không API nào đọc ngược ra. Chỉ còn lại vân tay 4 byte để đối chiếu đúng khoá.
- 3Khai chính sách mặc định
Cấu hình → Chính sách mặc định là lớp
global, áp cho mọi máy: thư mục nguồn, loại trừ, lịch chạy, kho lưu trữ đích. - 4Cài agent lên máy cần sao lưu
Trước hết lấy mã cài đặt ở Cấu hình → Nhóm máy → chọn nhóm → Mã cài đặt. Máy cài bằng mã của nhóm nào sẽ vào thẳng nhóm đó và nhận cấu hình của nhóm ngay từ lần sync đầu. Một mã dùng chung cho cả đợt — chọn số máy, hoặc để không giới hạn. Mọi máy dùng cùng một mã sẽ vào cùng một nhóm, nên đây cũng là cách gán sẵn một cụm máy vào cùng chính sách.
Mã chỉ hiện đúng một lần lúc tạo — server chỉ giữ bản băm. Màn hình đó cho sẵn lệnh cài đã ghép đủ địa chỉ server và mã, chép dán thẳng được.
Giải nén gói cài rồi chạy bằng quyền quản trị. Linux (cần systemd):
tar xzf backup-agent-<ver>-linux-amd64.tar.gz cd backup-agent-<ver>-linux-amd64 sudo ./install.sh --server https://backup.noi-bo --token <enroll-token>
Windows — mở PowerShell bằng Run as Administrator:
.\install.ps1 -Server https://backup.noi-bo -Token <enroll-token>
Thư mục cần sao lưu nằm trên NAS thì đọc thêm Nguồn trên ổ mạng trước khi cài — có một cái bẫy riêng của Windows ở đó.
Agent rơi vào trạng thái Chờ duyệt. Máy chờ duyệt không nhận config thật, không nhận khoá kho lưu trữ, không nhận bot token — cắm nhầm một máy lạ vào mạng không làm rò rỉ gì.
Nâng cấp: chạy lại chính install script đó
Nó tự dừng service, thay tệp chạy, rồi chạy lại — giữ nguyên danh tính máy và chỉ mục tệp đã sao lưu, nên lượt kế tiếp vẫn chỉ đẩy phần thay đổi. Đừng gỡ ra cài lại: gỡ kèm--purgesẽ xoá danh tính, máy thành máy mới trên danh sách và phải đẩy lại từ đầu. - 5Duyệt máy và gắn kênh thông báo
Agent → chip Chờ duyệt → menu cuối dòng → Duyệt máy này. Sau đó tạo ít nhất một kênh ở Cấu hình → Thông báo và bấm Gửi thử.
Đừng bỏ bước Gửi thử
Không bấm thử thì lần đầu biết kênh cấu hình sai sẽ đúng vào lúc có sự cố thật.
Cấu hình phân lớp
Ba lớp, lớp sau đè lớp trước:
- 1.global — mọi máy
- 2.group — một nhóm máy
- 3.agent — riêng một máy
Chỉ những mục bật công tắc mới được khai ở lớp dưới. Mục không bật rơi xuống lớp trên — vì vậy không có khái niệm “giá trị mặc định” ở lớp agent.
Với các trường dạng danh sách (nguồn, loại trừ), bắt buộc khai mode:
| mode | nghĩa |
|---|---|
replace | Bỏ hẳn danh sách của lớp trên, dùng danh sách này |
append | Nối thêm vào danh sách của lớp trên |
Bắt khai rõ vì suy đoán ngầm ở đây rất tốn: một lớp group tưởng là append nhưng chạy thành replace sẽ âm thầm ngừng sao lưu mọi thư mục khai ở global.
Hai loại hash
| hash | gồm gì | dùng để |
|---|---|---|
config_hash | Toàn bộ config, kể cả đích lưu trữ (chứa id máy) | Agent biết config có đổi không |
policy_hash | Phần không phụ thuộc máy | So hai máy có cùng chính sách hay không |
config_hash luôn khác nhau giữa các máy vì đích lưu trữ có id máy trong đó — nên nó không trả lời được câu “hai máy này có cùng chính sách không”. Đó là lý do có hash thứ hai.
Nhóm máy & mã cài đặt
Nhóm là lớp group ở trên. Nó tồn tại vì máy Windows và máy Linux gần như không bao giờ dùng chung được thư mục nguồn — mà khai riêng cho từng máy thì tới máy thứ mười là không ai theo nổi.
Cấu hình → Nhóm máy. Mỗi nhóm gom ba thứ vào cùng một chỗ:
| Chính sách của nhóm | Nguồn, loại trừ, lịch, đích — đè lên lớp global |
| Mã cài đặt | Máy cài bằng mã của nhóm vào thẳng nhóm đó |
| Danh sách máy đang thuộc nhóm | Chuyển máy sang nhóm khác ngay tại đây |
Nhóm default không xoá được, và nhóm còn máy cũng không xoá được — xoá được thì những máy đó sẽ lặng lẽ rơi về chính sách global, thường là một chính sách không hợp với chúng.
Gắn máy đã cài vào nhóm
Agent → menu trên thẻ máy → Chuyển nhóm. Máy nhận chính sách mới ở lần gọi về kế tiếp, không cần cài lại và không mất chỉ mục tệp đã sao lưu.
Mã cài đặt
Một mã dùng được cho nhiều máy — cài cả một cụm bằng đúng một dòng lệnh, và cả cụm vào cùng một nhóm.
| tuỳ chọn | mặc định | ý nghĩa |
|---|---|---|
max_uses | 1 | Số máy dùng được. Đặt 0 = không giới hạn |
ttl_hours | 72 | Hạn dùng, tối đa 720 (30 ngày) |
allowed_cidrs | trống | Chỉ nhận enroll từ dải IP này. Trống = từ đâu cũng được |
auto_approve | tắt | Máy vào thẳng trạng thái đang chạy, không cần ai duyệt |
Tự duyệt bắt buộc phải kèm dải IP
Mã chỉ hiện đúng một lần lúc tạo; server chỉ giữ bản băm. Mất thì thu hồi rồi tạo mã khác. Thu hồi có hiệu lực ngay, nhưng không đụng tới máy đã cài bằng mã đó — chúng đã có token riêng.
Hết lượt dùng thì lần enroll tiếp theo bị từ chối kèm lý do rõ ràng, chứ không báo “mã sai” — nhầm hai chuyện đó khiến người cài đi tìm lại mã trong khi mã vẫn đúng.
Hồ sơ kho lưu trữ
Endpoint, region, bucket, path-style… khai một lần thành một hồ sơ, rồi ở global / nhóm / máy chỉ việc chọn ra từ danh sách. Sửa endpoint một chỗ là mọi lớp đang trỏ tới đó đổi theo.
Cấu hình → Kho lưu trữ → Hồ sơ. Ở trình soạn chính sách, nút Chọn hồ sơ mở danh sách đã tạo sẵn; vẫn khai tay được từng trường nếu một máy cần đi hướng khác.
Hồ sơ trỏ tới khoá, không chứa khoá
credential_id. Đổi khoá truy cập thì sửa đúng một bản ghi khoá, không phải đi tìm lại mọi nơi đã dán nó vào.prefix cố ý không nằm trong hồ sơ: nó là cách chia không gian tên giữa các nhóm máy, nên nó thuộc về lớp chính sách chứ không thuộc về cái kho.
Trước khi xoá một hồ sơ, cột Đang dùng cho biết bao nhiêu lớp đang trỏ tới nó. Xoá một hồ sơ đang dùng là làm những máy đó mất đích lưu trữ.
Ngưỡng multipart
Mặc định tệp trên 5 GiB mới chia mảnh. Hạ ngưỡng khi kho lưu trữ nằm sau một lớp có giới hạn kích thước request.
Kho lưu trữ xuất qua Cloudflare: đặt 90
413 — một mã lỗi mà nhìn vào không đoán ra là do CDN chứ không phải do kho lưu trữ.Ghi thẳng vào ổ mạng thay vì S3
Provider local ghi thẳng vào một đường dẫn đã mount: NFS, SMB/CIFS, iSCSI hay một ổ rời đều dùng chung đường này, vì sau khi mount cả ba đều chỉ là một thư mục. Việc mount thuộc về hệ điều hành (fstab, autofs), không thuộc về agent.
| trường | ý nghĩa |
|---|---|
path | Thư mục đích, tuyệt đối. vd /mnt/nas-backup hoặc \\nas\backup |
require_mount | Từ chối ghi nếu đường dẫn chưa được mount. Bật cho mọi đích trên ổ mạng |
Mất đi lớp bảo vệ quan trọng nhất
Thư mục nguồn & loại trừ
ID nguồn phải ổn định
<prefix><id nguồn>/…. Đổi id là cắt đứt cả lịch sử lẫn liên kết tới dữ liệu đã lưu — đổi đường dẫn thì không sao, đổi id thì mất.Đường dẫn phải tuyệt đối. Các cờ trên từng nguồn:
| cờ | khi bật |
|---|---|
| recursive | Quét cả cây thư mục con, không chỉ tầng đầu |
| require_mount | Chưa mount là LỖI, không phải “quét được 0 tệp”. Bật cho mọi nguồn nằm trên ổ mạng |
| stay_on_filesystem | Không vượt sang filesystem khác. Thiếu nó, nguồn “/” đệ quy sẽ đi thẳng vào ổ NFS 10TB |
| follow_symlinks | Đi theo symlink thư mục (luôn có chống vòng lặp) |
| max_file_size_mb | Bỏ qua tệp lớn hơn ngưỡng, và đếm chúng vào báo cáo |
require_mount là cờ quan trọng nhất ở đây
Quy tắc loại trừ
| pattern | khớp |
|---|---|
/var/tmp | Neo ở gốc — chỉ đúng đường dẫn đó |
node_modules | Khớp ở mọi độ sâu |
*.tmp | Theo tên tệp, mọi độ sâu |
Nguồn trên ổ mạng (NAS, SMB)
Thư mục cần sao lưu nằm trên NAS chứ không nằm trên đĩa của máy là chuyện thường. Agent đọc được, không cần cấu hình gì thêm về giao thức — nhưng trên Windows có một cái bẫy khiến gần như ai cũng vấp đúng một lần.
Luôn khai bằng đường dẫn UNC
\\nas01\ketoan\du-lieu | Đúng |
X:\du-lieu | Sai — agent sẽ không bao giờ thấy |
Ổ đã ánh xạ (X:) thuộc về phiên đăng nhập của người dùng. Agent chạy như một service ở phiên khác, nên nó không thấy ổ đó dù Explorer của bạn vẫn thấy. Triệu chứng là “The system cannot find the path specified” trên một đường dẫn mở bằng tay vẫn vào được.
“Mở Z: bằng tay vẫn vào được” không chứng minh gì
LocalSystem không đọc được NAS đứng riêng — không có cách lập trình nào vòng qua
LocalSystem, và Windows không cho một tiến trình LocalSystem xác thực với SMB bằng tài khoản khác. Đã thử cả ba đường và cả ba đều dừng ở lỗi 1312 (a specified logon session does not exist):| cách | kết quả |
|---|---|
WNetAddConnection2 | 1312 |
NetUseAdd | 1312 — đây là thứ lệnh net use gọi |
CredWrite / cmdkey | Ghi được credential, nhưng SMB dùng nó vẫn 1312 |
Chọn cách theo loại NAS
Service phải có danh tính của riêng nó được NAS chấp nhận. Cách làm khác hẳn nhau tuỳ NAS có tham gia domain hay không:
| NAS | cách cấp quyền cho service |
|---|---|
| Tham gia domain (Windows Server, NAS đã join AD) | Cấp quyền đọc cho TÀI KHOẢN MÁY — không sinh ra mật khẩu nào |
| Đứng riêng: Synology, TrueNAS, Samba, NAS gọi bằng IP trần | Tài khoản Windows cục bộ TRÙNG tên và mật khẩu với user trên NAS, rồi chạy service bằng tài khoản đó |
NAS trong domain — không mật khẩu nào cả
Để nguyên cách cài mặc định. Service chạy bằng LocalSystem, và khi ra mạng nó xác thực với SMB bằng tài khoản máy:
CONGTY\TENMAY$ ← dấu $ ở cuối là bắt buộc
Cấp cho tài khoản đó quyền chỉ đọc trên share nguồn, ở phía NAS. Hết. Không có mật khẩu nào được sinh ra, nên cũng không có mật khẩu nào để lộ, để hết hạn, hay để đi đổi trên ba mươi máy.
Script cài in thẳng tên tài khoản máy ra màn hình sau khi cài xong, vì cái tên đó không hiển nhiên và đoán sai thì người ta quay sang dùng tài khoản admin cho xong chuyện.
NAS đứng riêng — khớp tên và mật khẩu
NAS không tham gia domain không hiểu tài khoản máy, nên cách trên không dùng được. Nó chỉ có danh sách user của riêng nó. Windows xác thực với share bằng tên và mật khẩu của tài khoản đang chạy service, nên cách nối hai bên lại là cho chúng trùng nhau:
- 1.Trên NAS: tạo (hoặc dùng lại) một user chỉ có quyền ĐỌC trên share nguồn
- 2.Trên máy Windows: tạo một tài khoản cục bộ TRÙNG cả tên lẫn mật khẩu với user đó
- 3.Cài agent với -ServiceUser ".\ten-do" -ServicePassword "..."
.\install.ps1 -Server https://backup.noi-bo -Token <token> `
-ServiceUser ".\svc-backup" -ServicePassword "...".\ ở đầu nghĩa là tài khoản cục bộ của máy này. Mật khẩu hai bên lệch nhau là hỏng, kể cả khi tên vẫn trùng — nên khi đổi mật khẩu thì phải đổi cả hai chỗ.
Tài khoản dịch vụ của domain
Khi cả máy lẫn NAS đều trong domain và bạn muốn một danh tính riêng:
.\install.ps1 -Server https://backup.noi-bo -Token <token> `
-ServiceUser "CONGTY\svc-backup" -ServicePassword "..."Tài khoản đó cần đúng ba thứ, và không cần là administrator:
- quyền Log on as a service trên máy này
- quyền đọc trên share nguồn
- toàn quyền trên
C:\ProgramData\BackupAgent— script tự cấp
Thiếu “Log on as a service” = lỗi 1069
secpol.msc.Đừng cho agent quyền ghi lên share nguồn
Nhiều NAS: khai hồ sơ trên web
Chỉ dùng được khi service đã chạy bằng tài khoản người dùng
LocalSystem thì hồ sơ khai ở đây không có tác dụng, và agent sẽ ghi rõ lý do đó vào nhật ký thay vì thử lại mỗi vòng.Cách khớp tên/mật khẩu ở trên chỉ gọn khi có một NAS. Nhiều NAS với tài khoản khác nhau thì không tạo nổi một tài khoản Windows khớp với tất cả. Lúc đó: chạy service bằng một tài khoản dịch vụ dùng chung, rồi khai từng NAS ở Cấu hình → Truy cập ổ mạng.
| Chỉ máy đã duyệt nhận được | Máy chờ duyệt không nhận mật khẩu nào |
| Chỉ nhận NAS mình cần | Máy chỉ đọc NAS kế toán không nhận mật khẩu NAS nhân sự |
| Mật khẩu không chạm đĩa | Lưu ở mức chỉ-trong-phiên; khởi động lại là mất và agent xin lại từ server |
| Chỉ agent Windows | Máy Linux mount qua fstab/autofs như cũ |
Đánh đổi, nói thẳng
Agent kiểm thật sau khi cấp: nó mở một đường dẫn nguồn trên NAS đó chứ không chỉ tin vào việc ghi credential thành công. Không mở được thì nó hạ xuống mức lưu ra đĩa rồi thử lại, và ghi cảnh báo — vì lúc đó mật khẩu nằm lại trên máy được sao lưu, một đánh đổi không được phép âm thầm.
Bật require_mount cho mọi nguồn mạng
Nhắc lại vì đây là chỗ nó có giá trị nhất: NAS mất kết nối trông y hệt một thư mục rỗng. Không bật cờ này thì mỗi đêm hệ thống báo “sao lưu thành công” trong khi không có tệp nào được lưu.
Kiểm bằng đúng danh tính của service
Xem service đang chạy bằng tài khoản nào — thứ quyết định mọi chuyện ở trên:
sc.exe qc backup-agent | findstr SERVICE_START_NAME
Chạy agentctl trong PowerShell của bạn sẽ cho kết quả SAI
PsExec -s cho LocalSystem:PsExec.exe -s -i cmd.exe dir \\172.16.1.131\Share-SMBDòng
dir đó chạy được thì agent cũng chạy được, và ngược lại.Agent nói thẳng nguyên nhân, không chỉ chép lại lỗi Windows
Lịch chạy
Cron 5 trường (phút giờ ngày tháng thứ). Khi khai cả ngày trong tháng lẫn thứ trong tuần, hai điều kiện là HOẶC — giống cron của Unix.
| trường | bắt buộc | vì sao |
|---|---|---|
cron | có | Giờ chạy |
jitter_sec | có | 200 máy cùng 0 2 * * * sẽ đồng loạt đập vào kho lưu trữ lúc 2:00:00 |
window | không | vd 22:00-06:00 — ngoài khung giờ này thì bỏ qua lượt |
Lỡ giờ thì BỎ QUA, không chạy bù
Sao lưu tăng dần
Server giữ chỉ mục những tệp đã lưu kèm hash nội dung. Mỗi lượt, agent chỉ đẩy tệp mới hoặc đã đổi.
lượt 1: 4 tệp → đẩy 4, bỏ qua 0 lượt 2: 4 tệp → đẩy 1, bỏ qua 3 (sửa 1 tệp) lượt 3: 4 tệp → đẩy 0, bỏ qua 4 (không đổi gì)
Tệp lớn
S3 chặn 5 GiB cho một lần ghi. Tệp lớn hơn được chia thành các mảnh 64 MiB và ghép lại ở đích — bản dump database vài chục GB đẩy được bình thường.
| Kích thước mảnh | 64 MiB |
| Ngưỡng chia mảnh | 5 GiB, đổi được trong hồ sơ kho lưu trữ |
| Trần số mảnh | 10.000 — tức tệp tối đa khoảng 640 GB |
| Đứt mạng giữa chừng | Mất lại đúng mảnh đang dở (~3 phút trên đường 3 Mbps), không mất cả tệp |
Bỏ dở thì phải huỷ, không được để đó
Cảnh báo & thông báo
Sáu loại cảnh báo
| loại | nghĩa |
|---|---|
| no_heartbeat | Máy im lặng quá 15 phút |
| run_failed | Lượt sao lưu thất bại |
| run_partial | Chạy xong nhưng có nguồn lỗi hoặc tệp bị bỏ |
| upgrade_rollback | Nâng cấp thất bại và đã quay về bản cũ |
| token_reissued | Máy được cấp lại token |
| reissue_while_alive | Cấp lại token trong khi máy cũ vẫn đang sống |
Ai gửi: agent hay server
Báo được cả khi không gọi tới server — đúng lúc hay xảy ra sự cố nhất. Đổi lại, mỗi máy giữ một bản bot token.
Token không rời khỏi server. Đổi lại, mất server thì mất luôn cảnh báo.
Chống dội tin
Hai lớp, chạy trên chính agent:
| cơ chế | mặc định | tác dụng |
|---|---|---|
| Trần mỗi giờ | 6 tin/giờ/kênh | Một máy hỏng liên tục không làm ngập nhóm chat |
| Nghỉ giữa hai tin cùng loại | 3600 giây | Cùng một sự cố không lặp lại mỗi vòng |
Tin bị nén lại được đếm và báo kèm trong tin tiếp theo được phép gửi. Nén im lặng sẽ biến “một máy hỏng” và “hai mươi máy hỏng” thành cùng một dòng thông báo.
Định tuyến
Mỗi kênh chọn Nhận tất cả hoặc Chỉ những loại chọn bên dưới. Tab Cảnh báo → Định tuyến hiện loại nào đi tới kênh nào — và tô đỏ loại nào không kênh nào nhận.
Tách kênh vì “máy im lặng” và “sao lưu lỗi” thường là việc của hai người khác nhau. Gộp chung thì một nhóm sẽ mute kênh, và sau đó cả hai loại cùng chìm.
Tin đã gửi
Agent gửi thẳng, rồi báo bản sao về server ở mức ưu tiên thấp — chỉ khi không có lượt sao lưu nào đang chạy, theo lô nhỏ, cách nhau vài phút. Danh sách vì thế có thể trễ vài phút so với tin thật, nhưng nó không tranh băng thông với dữ liệu.
Dòng đáng đọc nhất là dòng gửi hỏng
Vòng đời một máy
| trạng thái | nghĩa |
|---|---|
| chờ duyệt | Đã khai báo, chưa được duyệt. Không nhận config thật hay secret nào |
| đang chạy | Đã duyệt. Nhận config và thực thi lịch |
| đã cho nghỉ | Biến khỏi fleet, token hết hiệu lực, nhưng lịch sử vẫn còn |
Trực tuyến = có gọi về trong 5 phút gần nhất. Im lặng quá 15 phút thì sinh cảnh báo no_heartbeat.
Cho nghỉ hay xoá hẳn
| Cho nghỉ | Xoá hẳn | |
|---|---|---|
| Biến khỏi danh sách | có | có |
| Token hết hiệu lực | có | có |
| Nhật ký, cảnh báo, lịch sử tin | giữ | mất |
| Chỉ mục tệp đã sao lưu | giữ | mất |
| Đảo lại được | có | không |
Máy cũ đã thay thế: chọn Cho nghỉ
Cả hai đều không đụng tới dữ liệu đã nằm trên kho lưu trữ, và cả hai đều không tự gỡ agent trên máy thật — máy đó chỉ mất quyền và sẽ bị từ chối mỗi lần gọi về.
Máy vẫn đang gọi về thì thao tác xoá bị chặn, kèm lý do. Xoá một máy còn sống nghĩa là hệ thống quên nó, còn nó thì vẫn chạy tiếp mà không ai thấy.
Mô hình bảo mật
| Nguyên tắc | Cụ thể |
|---|---|
| Agent không cầm khoá kho lưu trữ | Chỉ nhận URL ký sẵn cho đúng một tệp, sống 30 phút. Máy bị chiếm không xoá được backup của chính nó |
| Secret mã hoá trước khi ghi | AES-256-GCM, gắn với id bản ghi. Không API nào đọc ngược ra — chỉ còn vân tay 4 byte |
| Không có phương án ghi plaintext | Thiếu STORAGE_KEY thì server TỪ CHỐI lưu, chứ không âm thầm ghi thô |
| Bot token không nằm trong config | Config được hash và trả về cho mọi quản trị viên. Token đi đường riêng |
| Máy chờ duyệt không nhận gì | Không config thật, không khoá kho lưu trữ, không bot token |
| Nhật ký thao tác không xoá được | Bảng audit chặn sửa và xoá ở tầng database, và chỉ ghi vân tay chứ không ghi secret |
| Agent không mở cổng | Luôn là bên gọi đi. Không cần mở firewall vào máy được sao lưu |
Nhật ký
Agent gửi bản trích nhật ký về server để trả lời “đêm qua máy này có chuyện gì” mà không phải SSH vào chính cái máy đang hỏng.
| Giữ | 7 ngày |
| Hạn mức | 500 dòng/giờ/máy — vượt thì bị bỏ và ĐẾM, không im lặng |
| Nhật ký đầy đủ | Vẫn nằm trên chính máy đó (journalctl -u backup-agent trên Linux) |
Số dòng bị bỏ hiện ngay trên đầu danh sách. Im lặng cắt bớt sẽ khiến người đọc tin nhầm rằng khoảng đó không có gì xảy ra.
Khắc phục sự cố
| Triệu chứng | Nguyên nhân thường gặp |
|---|---|
| Máy hiện “Mất kết nối” nhưng vẫn bật | Agent không gọi ra được (proxy, firewall), hoặc dịch vụ đã dừng. Xem Nhật ký ở trang chi tiết máy |
| Máy hiện “Lệch config” | Đã nhận config mới nhưng chưa áp xong. Gửi lệnh Nạp lại config |
| Sao lưu báo thành công nhưng 0 tệp | Ổ mạng chưa mount. Bật require_mount cho nguồn đó để nó thành LỖI thay vì thành công rỗng |
| Kênh thông báo báo lỗi đỏ | Bấm Gửi thử — Telegram nói rõ lý do (chat not found, bot bị chặn) và hệ thống hiện nguyên văn |
| Không nhận được cảnh báo nào | Xem tab Định tuyến. Loại nào tô đỏ là loại không kênh nào nhận |
| Trang Cấu hình báo chưa có khoá mã hoá | Server thiếu STORAGE_KEY. Đặt biến môi trường rồi khởi động lại server |
| Sao lưu hoàn tất một phần | Có nguồn lỗi hoặc tệp bị bỏ. Trang chi tiết máy liệt kê đúng nguồn nào |
| Windows: “The user name or password is incorrect” trên \\nas\share | Đường dẫn đúng, sai là tài khoản của service. Cấp quyền đọc cho tài khoản máy CONGTY\TENMAY$ trên NAS — xem mục Nguồn trên ổ mạng |
| Windows: “The system cannot find the path” trên X:\… | Ổ ánh xạ không tồn tại với service. Khai lại bằng đường dẫn UNC |
| Tệp lớn hỏng với lỗi 413 | Kho lưu trữ nằm sau Cloudflare (chặn 100 MB). Đặt ngưỡng multipart về 90 trong hồ sơ kho lưu trữ |
| Máy đã xoá nhưng vẫn hiện trực tuyến | Agent trên máy đó vẫn chạy. Gỡ bằng uninstall.sh — nó tự báo server trước khi gỡ |
Giới hạn đã biết
Những việc hệ thống chưa làm được. Liệt kê ở đây để không ai phát hiện ra chúng vào lúc cần nhất:
- Chưa có snapshot VSS. Tệp đang bị ứng dụng mở khoá ghi (database đang chạy) có thể không đọc được. Sao lưu ứng dụng sống cần dừng dịch vụ hoặc dump ra trước.
- Chưa có phục hồi từ giao diện. Dữ liệu nằm trên kho lưu trữ theo đường dẫn đọc được, nhưng phải lấy về thủ công.
- Nâng cấp agent từ xa chưa bật. Còn thiếu bước ký và kiểm chữ ký bản cài — phát một bản cài không kiểm chữ ký là biến control plane thành công cụ phát tán mã.
- Chưa có nâng cấp theo đợt. Chưa thử trên một nhóm nhỏ trước khi phát toàn bộ.
- Windows: chưa hỗ trợ gMSA. Tài khoản dịch vụ riêng vẫn phải khai mật khẩu lúc cài. Muốn hoàn toàn không mật khẩu thì dùng tài khoản máy (cách 1).
- Windows: tài khoản dịch vụ không đọc được tệp cục bộ bị chặn ACL. Chưa dùng
SeBackupPrivilege, nên tài khoản không phải admin chỉ đọc được những gì ACL cho phép. Nguồn trên SMB không vướng chuyện này.