ADR 0008Chấp nhận
ADR 0008. Dịch vụ Windows chạy bằng tài khoản ảo và khóa ACL thư mục dữ liệu
- Trạng thái: Đã chấp nhận
- Ngày: 2026-10-02
Bối cảnh
Trên Linux, dịch vụ chạy bằng user riêng accesshub-agent, credentials.json quyền 0600 và agent từ chối tệp quyền rộng. Trên Windows, creds không kiểm tra quyền, và tệp dưới C:\ProgramData thừa hưởng ACL của ProgramData, nơi nhóm Users đọc được. Nếu cài mà không xử lý thì mọi người dùng cục bộ đọc được token của agent, mất cô lập giữa người dùng và giữa các công ty dùng chung máy chủ Terminal.
Quyết định
- Dịch vụ tên
AccessHubAgent, chạy bằng tài khoản dịch vụ ảoNT SERVICE\AccessHubAgent(không mật khẩu, không phải LocalSystem, không có quyền quản trị). SID dịch vụ đặt chế độunrestricted. service installkhóa thư mục dữ liệuC:\ProgramData\AccessHubAgentTRƯỚC khi ghi bất cứ tệp nào: DACL được bảo vệ (không thừa hưởng từ ProgramData), chỉ cấp toàn quyền cho SYSTEM, Administrators và SID của dịch vụ, lan xuống tệp con. Mô tả bằng SDDLD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;<SID dịch vụ>). SID dịch vụ tính bằng hàm thuần (S-1-5-80cộng SHA-1 của tên viết hoa UTF-16LE), kiểm thử với giá trị đã công bố của TrustedInstaller. Khóa thất bại thì cài đặt dừng, không tạo dịch vụ (đóng an toàn).enrollchạy từ dấu nhắc quản trị: tệp tạo ra thừa hưởng ACL đã khóa nên dịch vụ đọc được, người dùng thường thì không. Không cần chạy enroll dưới tài khoản dịch vụ.- Khởi động thủ công mặc định (
--enablechuyển sang tự động trễ), không bao giờ tự bắt đầu trước khi enroll, giống Linux. - Khôi phục: khởi động lại sau 5 giây, 30 giây, 60 giây (lần cuối lặp lại), áp dụng cả khi dịch vụ báo dừng kèm lỗi. Mã thoát không khắc phục được bằng thử lại (2 sai cú pháp, 3 cấu hình, 4 chưa enroll, 5 enroll bị từ chối) được báo cho SCM là dừng bình thường nên không bị khởi động lại, tương đương
RestartPreventExitStatus=2 3 4 5của systemd. Mã khác báoERROR_SERVICE_SPECIFIC_ERRORvới mã cụ thể để khởi động lại. - Dịch vụ không có stderr: khi
log.filetrống và chạy với cờ--windows-service, log ghi vào<state_dir>\logs\agent.log(xoay vòng sẵn có củalogx). Lỗi cấu hình khi khởi động chỉ có mã thoát 3, dùngcheck-configtrước khi bật. - Chỉ nhận Stop và Shutdown từ SCM. Không có lệnh điều khiển tùy ý, không có cách chạy mã từ xa (ADR 0005). Nạp lại cấu hình qua SCM (ParamChange) để sau.
Hệ quả
- Người dùng cục bộ không đọc được token. Quản trị viên máy vẫn đọc được (chấp nhận được, họ có quyền đọc bộ nhớ tiến trình).
- Mã thật gọi
advapi32(CreateServiceW,ChangeServiceConfig2W,SetNamedSecurityInfoW,StartServiceCtrlDispatcherW) chỉ biên dịch chéo ở môi trường này. Phần logic (SID, SDDL, thứ tự cài đặt, đóng an toàn, ánh xạ mã thoát) có kiểm thử trên mọi máy. Cần chạy thử trên Windows thật: cài, enroll, khởi động, dừng, kiểm traicacls, thử người dùng thường đọc tệp. - MSI (WiX) sẽ gọi
accesshub-agent service install, không tự lặp lại logic ACL.
Phương án đã cân nhắc
- LocalSystem: đơn giản nhưng quyền quá lớn cho một chương trình chỉ cần đọc số liệu và gửi ra ngoài.
- Tài khoản
NT AUTHORITY\LocalService: dùng chung với nhiều dịch vụ khác, tệp của agent đọc được bởi chúng. SID dịch vụ riêng cô lập hơn. - DPAPI bọc token: chống đọc ngoại tuyến nhưng khó phục hồi khi đổi máy hay tài khoản, để sau như một lớp bổ sung.