Access Hub Scanner
Đang phát triểnĐồng bộ từ mã nguồn lúc 10:57, 03/10/2026
Skip to content

Kiến trúc ​

Kiến trúc của Access Hub Scanner. Tài liệu này so sánh các phương án, nêu khuyến nghị và luồng dữ liệu. Quyết định chính thức ở ADR 0001 (thành phần trên máy), ADR 0002 (nơi so khớp), ADR 0008 (nơi lưu), ADR 0009 (quét nội dung có giới hạn), ADR 0010 (bộ máy phát hiện), ADR 0011 (finding nội dung không mang giá trị). Sơ đồ chi tiết ở architecture/.

16 phút đọcCập nhật 03/10/2026access-hub-scanner, docs/02-architecture.md

1. Ràng buộc đầu vào (đã có trong hệ thống) ​

Ràng buộcNguồn
Access Hub Agent chạy bằng tài khoản accesshub-agent, CapabilityBoundingSet= rỗng, ProtectSystem=strict, ProtectHome=yes, MemoryMax=96M, CPUQuota=25%access-hub-agent/internal/svc/accesshub-agent.service
Agent không thực thi lệnh từ xa, cấu hình từ xa chỉ theo lược đồ, khóa lạ bị bỏADR 0005 của Agent, ADR 0003; ADR 0010 của Access Hub Collector
Danh tính (company_id, server_id) chỉ lấy từ thông tin đăng nhập qua registry phía máy chủ, không tin payload (cùng nguyên tắc với giám sát)Collector docs/03-protocol.md mục 1
Giới hạn body 1 MiB nén, 8 MiB giải nénCollector docs/03-protocol.md, bảng Giới hạn
Mã enroll, transport, creds, WAL của Agent nằm trong internal/ nên repo khác không import được; Scanner chỉ được chép mẫu (ghi nguồn), không importCây access-hub-agent/internal/; quyết định Q25
Scanner là sản phẩm, gói cước riêng; gói Scanner và gói Agent không phụ thuộc nhau theo chiều nàoQuyết định chủ dự án Q25 (2026-10-02), ADR 0001
Access Hub là nguồn sự thật cho dữ liệu nghiệp vụ (Server là thực thể chung của cả giám sát và Scanner)ADR 0004 của Collector

2. Phương án thành phần trên máy ​

(a) Mô-đun trong Agent hiện có ​

Thêm bộ thu security vào accesshub-agent.

ƯuNhược
Một gói cài, một danh tính, dùng lại WAL, transport, enroll, cấu hình từ xaKiểm tra cấu hình cần đọc /etc/shadow, /etc/sudoers, khóa host SSH (quyền và chủ sở hữu): Agent phải lên root hoặc có CAP_DAC_READ_SEARCH thường trực, trong khi nó là tiến trình có mạng và nhận cấu hình từ xa. Phá nguyên tắc chạy không đặc quyền (ANFR-13 của Agent)
Không cần thay đổi giao thức enrollNgân sách Agent (50 MB RSS, MemoryMax=96M) không chứa nổi đỉnh khi duyệt tệp và đọc rpmdb
Gắn nhịp phát hành: sửa một kiểm tra phải phát hành lại Agent trên mọi máy
Một lỗi parser (tệp cấu hình do kẻ tấn công cục bộ cài) chạy trong tiến trình có mạng

(b) Binary scanner riêng ​

(b1) Scanner riêng có mạng, dùng chung thư viện enroll và transport. Scanner tự enroll (License riêng hoặc dùng lại token của Agent), tự gửi tới Collector.

ƯuNhược
Tách nhịp phát hành, tách ngân sách tài nguyênThư viện cần dùng chung đang ở internal/ của Agent: phải tách ra module công khai (pkg/), thay đổi repo Agent
Có thể cài scanner mà không cần AgentTiến trình đặc quyền đọc lại có mạng, xử lý phản hồi và cấu hình từ xa: bề mặt tấn công giống (a)
Danh tính thứ hai: hoặc License riêng (đếm vào monitoring_agents của gói, thêm bản ghi, thêm xoay token), hoặc đọc credentials.json của Agent (ràng buộc định dạng tệp, hai tiến trình dùng chung token và giới hạn tốc độ)
Hai WAL, hai bộ backoff, hai đường TLS trên mỗi máy

(b2) Scanner riêng không có mạng, Agent chuyển tiếp (tách đặc quyền). Bộ đọc không mạng ghi spool, Agent đọc spool và gửi tới Collector bằng token của nó. Đây là khuyến nghị ban đầu; bị loại bởi quyết định Q25: gắn Scanner vào Agent và Collector, không cài được Scanner nếu không có giám sát.

(b3) Gói Scanner có bộ đọc không mạng và bộ gửi riêng không đặc quyền (tách đặc quyền trong cùng gói). Bộ đọc accesshub-scanner chạy theo timer bằng tài khoản có đúng CAP_DAC_READ_SEARCH, mạng bị chặn ở systemd, ghi báo cáo protobuf nén vào spool. Bộ gửi accesshub-scan-uploader (tài khoản riêng, không capability, chỉ HTTPS đi ra) có danh tính Scanner riêng (enroll bằng mã enroll Scanner, khóa Ed25519 sinh tại máy), đọc spool qua nhóm và gửi tới vai trò ingest của secmatch. Cấu hình quét đi ngược: ingest, bộ gửi ghi config.pb, bộ đọc đọc và kiểm tra lại.

ƯuNhược
Tiến trình đặc quyền không có mạng, tiến trình có mạng không đặc quyền: chiếm ingest hay đường truyền không chạm được tiến trình đặc quyền ngoài một tệp cấu hình đã kiểm tra hai lầnDanh tính thứ hai trên máy cài cả giám sát và Scanner (agent_id và host_id), hai enroll, hai luồng thu hồi
Scanner độc lập hoàn toàn với giám sát: bán, cài, gỡ, nâng cấp riêng (Q25)Phải tự làm enroll, backoff, xoay khóa, trạng thái (chép mẫu từ Agent): khoảng 10 đến 14 ngày người
Không cần thay đổi repo Agent hay CollectorCần vai trò ingest có TLS, giới hạn, registry máy Scanner ở trung tâm (SMT-6, HUB-SEC-21)
Bộ đọc nhỏ: không TLS, không enroll, không backoff; bộ đọc và bộ gửi cùng gói nên luôn khớp phiên bảnKiểm tra TLS cục bộ (P5) chạy trong bộ gửi, chỉ tới địa chỉ của chính máy
Bộ đọc không thường trú: RSS bằng 0 giữa hai lần quét

| | Máy sau NAT, tường lửa không với tới được; Dedicated cần thêm vùng mạng |

So sánh ​

Tiêu chí(a)(b1)(b2)(b3)(c)
Đặc quyền và mạng cùng một tiến trìnhCóCóKhôngKhôngCó (phía trung tâm)
Chỉ đi raCóCóCóCóKhông
Thực thi từ xaKhôngKhôngKhôngKhôngCó (lệnh qua SSH)
Phụ thuộc AgentCóCó (thư viện)CóKhôngKhông
Danh tính mớiKhôngCóKhôngCó (host_id)Thông tin đăng nhập SSH
Thay đổi repo AgentLớnLớn (tách thư viện)VừaKhôngKhông
Ngân sách RAM trên máyVượt ngân sách AgentRiêngRiêng, 0 khi rảnhBộ đọc 0 khi rảnh, bộ gửi dưới 32 MB0
Cài đặtMột góiMột hoặc hai góiHai góiMột gói ScannerKhông

Khuyến nghị ​

(b3), đã chấp nhận ở ADR 0001 (Q1, Q6, Q25). Đây là cách duy nhất vừa giữ ba ràng buộc (không đặc quyền khi có mạng, chỉ đi ra, không thực thi từ xa) trong khi đọc được tệp chỉ root đọc, vừa để Scanner độc lập với giám sát. (c) chỉ cân nhắc sau P10 cho thiết bị không cài được gì, cần ADR mới (Q27).

3. Nơi so khớp: trên máy hay tập trung ​

Tiêu chíTrên máyTập trung (secmatch)
Kích thước DB trên máyHàng trăm MB và tải mỗi ngày trên mọi máy (ví dụ DB của Trivy, Grype cỡ hàng trăm MB, cần đo ở spike S2)0
Ngân sách CPU, RAM, mạng trên máyVượt xa SNFR-03, SNFR-04Inventory vài chục KB
CVE mới công bốPhải quét lại mọi máySo khớp lại inventory đã lưu, không chạm máy
Dedicated offlinePhải phân phối DB tới từng máyChỉ nhập DB vào secmatch on-prem
Nhất quánMỗi máy có thể có DB khác ngàyMột DB, một phiên bản cho cả công ty
Tìm "máy nào có gói X"Không làm được nếu không gửi inventoryCó sẵn
Lộ thông tinKhông gửi danh sách gói ra ngoài máyDanh sách gói rời máy (siêu dữ liệu vận hành, lưu có cô lập tenant)

Khuyến nghị: tập trung (ADR 0002). Máy chỉ gửi inventory và kết quả kiểm tra cấu hình. Đánh giá kiểm tra cấu hình vẫn diễn ra trên máy (cần đọc tệp), chỉ phần so với danh sách dự kiến (cổng nghe) diễn ra tập trung.

3b. Phát hiện bí mật và dữ liệu cá nhân: luôn trên máy ​

Ngược với so khớp lỗ hổng, phát hiện nội dung không có phương án tập trung: muốn quét ở trung tâm thì phải gửi nội dung tệp ra khỏi máy, trái yêu cầu cứng "giá trị không rời máy" (ADR 0011). Vì vậy:

PhầnNơi chạyLý do
Duyệt, lọc, đọc tệp, chạy detector, che giấu, tính fingerprintScanner trên máy (lượt nội dung)Giá trị chỉ tồn tại trong bộ nhớ của scanner
Chỉ mục tệp đầy đủ, trạng thái từng tệpMáy (/var/lib/accesshub-scanner/index/)Danh sách mọi tệp không rời máy (14 mục 6)
So sánh trạng thái finding nội dung giữa hai báo cáo, phát sự kiệnSecmatchDùng chung outbox, idempotency, xóa theo công ty với finding lỗ hổng
Vòng đời (SLA, ngoại lệ, quyền xem, audit, thông báo)Access HubNhư mọi finding (ADR 0008)
Sinh và giữ K_company (mã hóa ENC-2)Access HubBí mật theo công ty; phát xuống máy qua cấu hình

Hệ quả cho tài nguyên trên máy: lượt nội dung là phần tốn nhất của sản phẩm, nên tách unit, chạy trong khung giờ yên tĩnh, tăng dần, có ngân sách riêng (ADR 0009, SNFR-12 đến SNFR-19).

4. Thành phần ​

Thành phầnRepoVai trò
accesshub-scannerRepo này, cmd/accesshub-scannerBinary Go tĩnh trên máy, hai unit cùng binary: lượt siêu dữ liệu mỗi giờ (DB gói, os-release, kernel, dịch vụ, phần mềm, tệp cấu hình, /proc, kiểm tra AHS-*) và lượt nội dung trong khung giờ yên tĩnh (detector AHK-*, AHP-*, chỉ mục cục bộ). Ghi báo cáo vào spool; không mạng
accesshub-scan-uploaderRepo này (SCN-4), cùng góiBộ gửi trên máy, không đặc quyền: enroll, giữ khóa Ed25519 của máy Scanner, đọc spool, gửi POST /scan/v1/report, tải GET /scan/v1/config ghi config.pb, chạy kiểm tra TLS cục bộ (P5). Không phụ thuộc Agent
Secmatch vai trò ingestRepo này (SMT-6), accesshub-secmatch --role ingestĐiểm vào công khai của Scanner sau load balancer: enroll, xác thực chữ ký máy Scanner, kiểm giấy phép (security_scanning, hạn mức scan_hosts), giới hạn, khử trùng, gắn company_id, server_id, host_id từ registry, chuyển tiếp tới vai trò matcher qua outbox bền vững
accesshub-secmatch vai trò matcherRepo này, cmd/accesshub-secmatchDịch vụ Go trung tâm, mạng nội bộ: lưu inventory mới nhất mỗi máy (gói, dịch vụ, phần mềm, thống kê tệp), so khớp, tính điểm, so khớp lại khi DB đổi, so sánh trạng thái finding nội dung, gửi delta finding về Access Hub, API nội bộ tra cứu gói, phần mềm, dịch vụ
secdb-buildRepo này, cmd/secdb-buildJob dựng DB: tải nguồn (03), chuẩn hóa, ký Ed25519, phát hành. Chạy ở hạ tầng của nền tảng, không chạy ở máy khách
Access Hub (mở rộng)/var/www/access-hubFinding và vòng đời (lỗ hổng, cấu hình, bí mật, dữ liệu cá nhân), ngoại lệ, SLA, dashboard, thông báo, quyền (gồm quyền xem bí mật và dữ liệu cá nhân), cài đặt quét nội dung, K_company, mã enroll và registry máy Scanner (HUB-SEC-21), gói và hạn mức, thống kê nền tảng ẩn danh

Vị trí của secmatch: dịch vụ riêng trong repo này (Q3, đã duyệt), gồm hai vai trò cùng binary: ingest (công khai, nhẹ, không giữ DB lỗ hổng) và matcher (nội bộ, giữ DB và kho inventory). Collector không tham gia đường Scanner.

5. Luồng dữ liệu ​

5.1 Quét và gửi (đường chính) ​

  1. accesshub-scanner.timer kích hoạt mỗi giờ (lệch ngẫu nhiên). Scanner so mtime, kích thước DB gói với lần trước (lưu trong thư mục trạng thái của scanner). Không đổi và chưa đến hạn 24 giờ thì thoát.
  2. Bộ đọc đọc tệp cấu hình quét do bộ gửi ghi (/var/lib/accesshub-scan-uploader/config.pb), kiểm tra lại lược đồ, bỏ khóa lạ. Không có tệp thì dùng mặc định cục bộ.
  3. Scanner kiểm kê, chạy kiểm tra cấu hình đến hạn, dựng SecurityReport (xem 07), tính inventory_hash, nén, ghi nguyên tử vào /var/lib/accesshub-scanner/spool/ (tệp tạm, fsync, đổi tên). Giữ tối đa 2 báo cáo, báo cáo mới thay báo cáo cũ chưa gửi.
  4. Bộ gửi accesshub-scan-uploader kiểm tra spool mỗi 60 giây (chỉ readdir, rất rẻ), lấy báo cáo mới nhất chưa gửi, kiểm tra khung (magic, schema_version nằm trong miền, kích thước, SHA-256), gửi POST /scan/v1/report ký bằng khóa của máy Scanner. Nếu inventory_hash trùng lần đã được xác nhận và kiểm tra cấu hình không đổi, bộ gửi gửi dạng rút gọn (chỉ băm).
  5. Vai trò ingest xác thực chữ ký, tra registry máy Scanner (host_id, company_id, server_id), kiểm giấy phép (403 licence_inactive khi hết gói hoặc vượt hạn mức scan_hosts), áp giới hạn, ghi outbox, trả 202. Bộ gửi ghi report_id đã xác nhận vào trạng thái của mình.
  6. Ingest chuyển tiếp ForwardedReport tới vai trò matcher POST /internal/v1/reports. Matcher lưu inventory theo (company_id, server_id), so khớp, so với finding đang mở của máy, đưa delta (mở, đóng, đổi điểm) vào outbox.
  7. Secmatch gửi lô delta tới Access Hub POST /api/v1/security/matcher/findings (idempotent theo event_id). Access Hub cập nhật security_findings, kích hoạt thông báo theo luật.

5.2 DB lỗ hổng cập nhật (không cần máy) ​

  1. secdb-build chạy hằng ngày (và khi KEV đổi), phát hành gói DB ký số kèm manifest.
  2. Secmatch kéo manifest, xác minh chữ ký và số phiên bản tăng, nạp DB mới song song với DB cũ, chuyển nguyên tử.
  3. Secmatch so khớp lại mọi inventory đã lưu theo từng công ty, chỉ phát delta. Làm giàu EPSS và KEV cũng đi theo đường này (điểm đổi thì phát finding.rescored).

5.3 Người dùng xem ​

Access Hub đọc security_findings (của mình) cho danh sách, dashboard. Tra cứu gói ("máy nào có gói X") gọi API nội bộ của secmatch với company_id lấy từ phiên người dùng, giống mẫu MonitoringCollectorClient hiện có (app/Services/Monitoring/Collector/MonitoringCollectorClient.php).

5.4 Xóa ​

Xóa vĩnh viễn Server hoặc purge Company: Access Hub xóa bảng security_* của phạm vi đó trong cùng giao dịch, sau commit gọi DELETE /internal/v1/companies/{id}/data hoặc .../servers/{id}/data của secmatch (giống HUB-14, Collector docs/06 mục 8.1).

5.5 Lượt nội dung (khung giờ yên tĩnh) ​

  1. accesshub-scanner-content.timer kích hoạt trong khung giờ yên tĩnh (mặc định 01:00 đến 05:00 giờ máy, lệch ngẫu nhiên). Scanner đọc config.pb và /etc/accesshub-scanner/local.conf, tính phạm vi hiệu lực (ADR 0009 mục 2), nạp K_host và K_company.
  2. Duyệt từ điểm dừng của lượt trước, so từng tệp với chỉ mục; tệp đổi hoặc chưa quét được lọc (loại, kích thước, nhị phân), đọc theo luồng, chạy detector, che giấu, tính fingerprint, ghi kết quả vào chỉ mục (không giá trị).
  3. Trước mỗi lô tệp kiểm tra PSI, ngân sách CPU, byte, số mục và giờ kết thúc khung; vượt thì lưu điểm dừng và thoát.
  4. Cuối lượt (hoặc ở lượt siêu dữ liệu kế tiếp), scanner dựng SecurityReport v2 gồm inventory mới nhất và ảnh chụp đầy đủ finding nội dung từ chỉ mục, kèm độ phủ; content_hash không đổi thì chỉ gửi băm.
  5. Từ bộ gửi trở đi đi chung đường 5.1: ingest kiểm tra lớp hai phần nội dung (07 mục 3.4), secmatch so trạng thái, phát finding.opened, finding.updated, finding.resolved với kind là secret hoặc sensitive_data.

6. Topology ​

Môi trườngBố trí
DevMột secmatch chạy cả hai vai trò, kho inventory bằng tệp, DB lỗ hổng nạp từ tệp, bộ gửi trỏ tới ingest cục bộ
CloudIngest 2 bản sau load balancer có TLS (tên miền riêng của Scanner), matcher 2 bản sau load balancer nội bộ, kho inventory MySQL riêng (không dùng chung MySQL của Access Hub), một tiến trình giữ lease chạy so khớp lại, secdb-build chạy như job định kỳ ở hạ tầng nền tảng
DedicatedMột secmatch on-prem (hai vai trò) cạnh Access Hub của khách hàng, không cần Collector, DB kéo từ CDN của nền tảng (chỉ đi ra) hoặc nhập tay khi không có Internet (P10)

7. Công nghệ ​

LớpLựa chọn đề xuấtLý do
Ngôn ngữ bộ đọc, bộ gửi, secmatch, secdb-buildGo, không CGOGiống Agent, Collector (ADR 0001 của Agent, ADR 0003 của Collector); .proto của Scanner thuộc repo này (accesshub.scan.v1)
Đọc rpmdbThư viện Go thuần (ứng viên github.com/knqyf263/go-rpmdb, giấy phép cần xác nhận ở P0)Tránh gọi rpm, tránh CGO. Spike S1 đo kích thước và độ đúng
So sánh phiên bảnTự viết theo đặc tả dpkg, rpmvercmp, apk, kiểm thử bằng bảng lấy từ công cụ gốcLõi độ chính xác, phải nắm hoàn toàn (ADR 0007)
Kho inventory của secmatchMySQL (cùng loại máy chủ đội đã vận hành) hoặc PostgreSQLQ4
Định dạng DB lỗ hổngTệp nhị phân hoặc SQLite thuần Go chỉ đọc, đóng gói tar.zst kèm manifest kýADR 0005, spike S2
Giao thứcHTTPS + protobuf, cùng kiểu với đường Agent tới Collector nhưng endpoint, danh tính và hợp đồng riêng của ScannerADR 0002 của Collector (tham khảo), ADR 0001
Bộ máy phát hiệnregexp của Go (RE2), Aho-Corasick tự viết hoặc thư viện giấy phép dễ dãi, bộ xác thực tự viết; quy tắc bí mật khởi đầu từ cấu hình gitleaks (MIT)ADR 0010, spike S6, S7
Chỉ mục cục bộbbolt (MIT) hoặc định dạng tự viếtADR 0009, spike S6
FingerprintHMAC-SHA256 thư viện chuẩn của GoADR 0011
Trang này có giúp được bạn không?
Sửa trang này

Nội dung đồng bộ từ kho mã access-hub-scanner lúc 10:57, 03/10/2026. Khi tài liệu và mã khác nhau, mã thắng.