remote.Tài liệuTrang chủ

Tác nhân AI nên tìm nạp https://remote.ivjn.us/SKILL.md.

API HTTP cho hoạt động Agent

Hoạt động niêm phong gốc hiện hỗ trợ người gọi chỉ HTTP. Sử dụng remote-cli --transport http hoặc REMOTE_TRANSPORT=http. POST /api/sealed/connections tạo hộp thư; POST /input gửi các bản bắt tay hoặc văn bản mã hóa đã ký, kết quả thăm dò GET /events và DELETE đóng kết nối. Khách hàng giữ lại mật mã đầu cuối và ủy quyền thiết bị hiện có. Điểm cuối hành động của thiết bị ban đầu vẫn trả về 409. Kết nối thiết bị không thay đổi. Hộp thư HTTP yêu cầu có mối quan hệ giống với phiên bản Exchange đang tạo và hết hạn sau 90 giây mà không hoạt động. Tuần tự hóa các đầu vào, chỉ thử lại cùng một chuỗi và văn bản mã hóa, đồng thời xác nhận các sự kiện đã xử lý bằng after. Web Console, thiết bị di động và mạng LAN vẫn giữ nguyên phương tiện truyền tải hiện có của chúng. Việc thực thi cài sẵn vẫn yêu cầu manage.

https://remote.ivjn.us/sealed-http.md

HTTP 409 / Sealed sessions are required. tại điểm cuối thao tác thiết bị có nghĩa là cần phiên kín; chỉ mã thông báo Bearer không thể thực thi thao tác thiết bị. Dùng remote-cli --profile alice exec lab -- uname -a, hoặc remote-cli --profile alice --transport http exec lab -- uname -a trong môi trường chỉ cho phép HTTP. CLI vẫn thực hiện bắt tay có chữ ký và mã hóa đầu cuối.

URL cơ sở

Sản xuất Exchange:

https://exchange.ivjn.us

Triển khai tự lưu trữ sử dụng nguồn gốc HTTPS của riêng bạn. Tất cả các đường dẫn bên dưới đều liên quan đến cơ sở đó. Gửi JSON bằng Content-Type: application/json.

Xác thực

Mỗi tuyến đường /api/* (ngoại trừ người trợ giúp xác thực/đăng ký công khai) yêu cầu:

Authorization: Bearer <token>

<token> có thể là:

  1. Mã thông báo phiên đăng nhập mật khẩu từ POST /api/auth/login
  2. Khóa API chính Operator (mã thông báo tồn tại lâu dài được hiển thị một lần khi tài khoản nhà điều hành được tạo)

Cả hai đều được chấp nhận bởi cùng một đường dẫn authenticate_operator được bảng điều khiển và CLI sử dụng.

Đăng nhập bằng mật khẩu

curl -sS -X POST 'https://exchange.ivjn.us/api/auth/login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"alice@example.com","password":"your-password-here"}'

email là danh tính tài khoản và phải là địa chỉ hợp lệ. Dịch vụ bình thường hóa nó (cắt, viết thường) và yêu cầu địa chỉ được xác minh. Các hoạt động triển khai hiện tại vẫn có thể gửi { "username": "alice", "password": "..." } cho đến khi các tài khoản đó chuyển sang email; giá trị chứa @ trong username được coi là một email. Địa chỉ không hợp lệ sẽ bị từ chối trước khi kiểm tra mật khẩu.

Phản hồi ví dụ:

{
  "username": "alice",
  "email": "alice@example.com",
  "tenant_id": "00000000-0000-0000-0000-000000000000",
  "token": "<prefix>.<secret>",
  "expires_in": 2592000
}

Sử dụng token làm thông tin xác thực Bearer. Gọi POST /api/auth/logout với cùng tiêu đề để thu hồi phiên đó. Khóa API của nhà điều hành chính không bị thu hồi khi đăng xuất.

Khóa API của nhà điều hành (mã thông báo chính)

TOKEN='<prefix>.<secret>'   # issued at operator creation; store offline
curl -sS 'https://exchange.ivjn.us/api/devices' \
  -H "Authorization: Bearer ${TOKEN}"

Liệt kê các thiết bị

curl -sS 'https://exchange.ivjn.us/api/devices' \
  -H "Authorization: Bearer ${TOKEN}"

Mỗi mục bao gồm id, name, online, enabled, info, dấu thời gian và active_sessions. Kiểm kê thiết bị là siêu dữ liệu Exchange. Việc liệt kê một thiết bị không thiết lập phiên kín cần thiết để vận hành thiết bị đó.

Từ chối HTTP hành động thiết bị và quản lý phiên

Tất cả các hoạt động của thiết bị đều sử dụng phiên WebSocket kín. Các tuyến HTTP bên dưới không thể thiết lập bắt tay máy khách/thiết bị và do đó trả về HTTP 409 cho các yêu cầu được ủy quyền, xác thực vượt qua quá trình xác thực yêu cầu. Việc từ chối xảy ra trước khi gửi thiết bị: không có lệnh, yêu cầu cảm biến, thăm dò mạng, cập nhật, cuộc gọi ubus, yêu cầu công việc được giữ lại hoặc lệnh đã ghim được gửi tới agent. Một thiết bị trực tuyến không thể thực hiện được các tuyến đường này.

Xác thực, quyền và xác thực đầu vào vẫn được áp dụng. Thông tin xác thực không hợp lệ trả về 401; hoạt động bị cấm trả về 403; các lệnh, URL hoặc nội dung yêu cầu không hợp lệ sẽ giữ lại các lỗi xác thực của chúng, bao gồm 400. Phiên kín 409 không thay thế các lỗi xác thực hoặc ủy quyền trước đó. Việc kiểm tra quyền đối với các lệnh được ghim tuân theo chính sách lệnh được ghim; chuyển chúng vẫn không cho phép thực thi HTTP.

Phương pháp và đường dẫn Hành vi sau khi xác thực, ủy quyền và xác nhận
POST /api/devices/{id}/exec 409: thực thi bên trong phiên WebSocket kín
GET /api/devices/{id}/exec/holds 409: kiểm tra các công việc được giữ trong phiên WebSocket được niêm phong
POST /api/devices/{id}/exec/holds/{job_id}/kill 409: dừng các công việc được giữ trong phiên WebSocket đã được niêm phong
GET /api/devices/{id}/exec/holds/{job_id}/cat 409: đọc đầu ra công việc được giữ bên trong phiên WebSocket được niêm phong
POST /api/devices/{id}/sensors 409: thu thập các cảm biến bên trong phiên WebSocket kín
POST /api/devices/{id}/net 409: chạy các đầu dò mạng bên trong phiên WebSocket kín
POST /api/devices/{id}/update 409: kiểm tra hoặc áp dụng các bản cập nhật bên trong phiên WebSocket kín
POST /api/devices/{id}/ubus 409: gọi ubus trong phiên WebSocket kín
POST /api/devices/{id}/commands/{cmd}/run 409: tìm nạp lệnh đã ghim và thực thi lệnh đó bên trong phiên WebSocket được niêm phong với quyền quản lý được ủy quyền của thiết bị

Ví dụ: yêu cầu hành động hợp lệ này là kiểm tra từ chối, không phải giao diện thực thi lệnh:

curl -i -X POST "https://exchange.ivjn.us/api/devices/${DEVICE_ID}/exec" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H 'Content-Type: application/json' \
  -d '{"command":"uname -a","timeout_secs":30}'

Yêu cầu HTTP 409 có thông báo lỗi tiếng Anh Sealed sessions are required. (được bản địa hóa theo ngôn ngữ yêu cầu). Thiết lập phiên WebSocket được niêm phong riêng để thực hiện thao tác. Không có phản hồi đầu ra lệnh thành công nào từ tuyến HTTP này.

Quản trị phiên Exchange

Kiểm kê và hủy phiên vẫn có sẵn qua HTTP vì chúng quản lý siêu dữ liệu định tuyến Exchange. Chúng không thực thi các thao tác của thiết bị hoặc mở phiên thiết bị bổ sung.

Phương pháp và đường dẫn Cơ thể thành công
GET /api/devices/{id}/sessions {sessions:[DeviceSessionInfo], limit, count}
POST /api/devices/{id}/sessions/{session_id}/kill {session_id, released}

Các trường DeviceSessionInfo là session_id (ID số phía thiết bị), operator_session_id, kind, hold, age_secs và deadline_unix_ms. limit là max_sessions_per_device (mặc định là 32); count là độ dài danh sách hiện tại. Danh sách đọc trực tiếp trạng thái trung tâm Exchange cục bộ; một thiết bị ngoại tuyến cục bộ trả về 503. Kill sử dụng ID Z của thiết bị, gửi lệnh hủy thích hợp (bao gồm cả đối với lệnh thực thi bị giữ) và giải phóng tuyến cục bộ ngay cả khi thiết bị không trả lời. Phiên bị thiếu hoặc thiết bị ngoại tuyến cục bộ trả về HTTP 200 với released:false. Toán tử chỉ đọc nhận 403 cho cả hai điểm cuối.

curl -sS "https://exchange.ivjn.us/api/devices/${DEVICE_ID}/sessions" \
  -H "Authorization: Bearer ${TOKEN}"

curl -sS -X POST "https://exchange.ivjn.us/api/devices/${DEVICE_ID}/sessions/${SESSION_ID}/kill" \
  -H "Authorization: Bearer ${TOKEN}"

Trước khi từ chối giới hạn phiên đầy đủ, Exchange lấy lại các tuyến của nhà điều hành đã chết và các tuyến trước thời hạn: thời gian chờ thực thi + 15 giây, truyền tệp 3600 giây + 15 giây, các loại khác là 24 giờ. Người thực thi được giữ trong thời hạn của nó sẽ tách ra khi nhà điều hành ngắt kết nối thay vì bị giết.

Hoạt động CLI kín gốc

CLI thiết lập các phiên kín như một phần của hoạt động bình thường của thiết bị. Trước tiên hãy hoàn thành phê duyệt gốc không gian làm việc và ủy quyền thiết bị; xem phiên kín. Không có lựa chọn không tham gia bản rõ. Các lệnh thông thường không cần thêm cờ niêm phong:

remote-cli exec "$DEVICE_ID" -- uname -a
remote-cli shell "$DEVICE_ID"
remote-cli exec-holds "$DEVICE_ID"
remote-cli exec-hold-cat "$DEVICE_ID" "$JOB_ID"
remote-cli exec-hold-kill "$DEVICE_ID" "$JOB_ID"
remote-cli sensors "$DEVICE_ID" --json
remote-cli net "$DEVICE_ID" ping 1.1.1.1
remote-cli net "$DEVICE_ID" http https://example.com/
remote-cli ubus "$DEVICE_ID" system board '{}'
remote-cli commands list "$DEVICE_ID"
remote-cli commands run "$DEVICE_ID" "$COMMAND_ID"

Hoạt động công việc được tổ chức chạy trong các phiên kín; Quản trị phiên Exchange được cung cấp riêng biệt thông qua remote-cli sessions và remote-cli session-kill. Việc tìm nạp siêu dữ liệu lệnh được ghim không cho phép thực thi: thiết bị phải chấp nhận quyền quản lý của nhà điều hành được niêm phong.

Thư mục khóa phiên kín và cấp chuyển tiếp

Exchange lưu trữ khóa công khai của nhà điều hành và mã thông báo cấp rsg1. do chủ sở hữu ký để khách hàng có thể khám phá lẫn nhau. Đây không phải là ủy quyền. Các thiết bị vẫn xác minh chữ ký của chủ sở hữu theo chính sách địa phương. Exchange chỉ lập chỉ mục tải trọng mã thông báo (owner_key, operator_key, device_id, level, expires_at) và không bao giờ coi việc tải lên là quyền. Exchange không thể giả mạo chữ ký gốc nhưng có thể giữ lại thông tin xác thực, trình bày sai danh sách cho máy khách gốc tự động phê duyệt, quan sát siêu dữ liệu hoặc từ chối dịch vụ.

Thư mục gốc của không gian làm việc (rsr1.) và lời mời cấp quyền (rsi1.) là cùng một loại chuyển tiếp. Exchange kiểm tra hình dạng mã thông báo và chữ ký tự Ed25519 (lời mời cũng phải khớp với khóa gốc được lưu trữ) và not quyết định khóa toán tử nào được phê duyệt. GET /api/seal/roster là chế độ xem siêu quản trị viên về các thành viên, vai trò và operator_device_grants. Khách hàng không được coi khóa mới xuất hiện là đáng tin cậy cho đến khi khách hàng gốc phê duyệt nó cục bộ. Xem docs/sealed-sessions.md.

Bất kỳ thành viên không gian làm việc được xác thực nào cũng có thể liệt kê các khóa, đăng ký khóa riêng của họ và tải lên các khoản cấp phép (các khoản cấp phép tự xác thực). DELETE của một khóa được giới hạn trong tài khoản đăng ký (quản trị viên có thể xóa bất kỳ tài khoản nào). DELETE của một khoản trợ cấp được giới hạn cho người tải lên (quản trị viên có thể xóa bất kỳ khoản trợ cấp nào). GET /api/seal/grants bỏ qua các hàng đã hết hạn.

Bằng chứng đăng ký chính là Ed25519 trên:

remote-seal-key-register:v1:<workspace_id>:<operator_id>:<public_key>:<issued_at_ms>

issued_at_ms phải cách đồng hồ máy chủ trong vòng ±10 phút. public_key và proof là base64 tiêu chuẩn (khóa 32 byte, chữ ký 64 byte).

Phương pháp và đường dẫn Thân hình thành công
POST /api/seal/keys {"public_key","label"?,"proof","issued_at_ms"} khóa đã đăng ký (upsert cho cùng một tài khoản)
GET /api/seal/keys — [{operator_id, username, email, public_key, label, created_at, last_seen_at}]
DELETE /api/seal/keys/{key} — 204 ({key} là khóa chung được mã hóa URL)
POST /api/seal/grants {"tokens":["rsg1.…"]} {stored:[…], errors:[…]}
GET /api/seal/grants?mine=1 — cấp mà operator_key là một trong những khóa đã đăng ký của người gọi. Mỗi cấp có owner_key không phải là gốc được xuất bản cũng bao gồm chain (mã thông báo chứng chỉ, có thể trống)
GET /api/seal/grants?owner_key=… — cấp quyền được ký bởi khóa chủ sở hữu đó
DELETE /api/seal/grants/{id} — 204
PUT /api/seal/root {"token":"rsr1.…","rotation":"rsx1.…"?} gốc không gian làm việc được lưu trữ. Chỉ có quản trị viên cấp cao. Hình dạng và chữ ký riêng của khóa được kiểm tra; đây không phải là sự chấp thuận rotation (tùy chọn) phải được ký bởi root hiện đã được xuất bản và đặt tên cho root mới; Exchange sau đó đẩy seal_root {token, rotation} đến các thiết bị kín trực tuyến, các thiết bị này chỉ được ghim lại khi vòng xoay được ký bởi người gốc mà họ đã tin tưởng. Nếu không có vòng xoay hợp lệ, các thiết bị đã ghim gốc cũ sẽ giữ nguyên
GET /api/seal/root — {workspace_id, root_key, payload, signature, token, created_at} hoặc 404 khi chưa được xuất bản
POST /api/seal/invitations {"token":"rsi1.…"} lời mời được lưu trữ Chỉ dành cho quản trị viên cấp cao và chỉ sau khi có root
GET /api/seal/invitations — lời mời chưa hết hạn, mới nhất trước ([] khi không có)
GET /api/seal/roster — {members:[{operator_id, username, email, role, restricted, enabled, keys:[{public_key, label}], device_grants:[{device_id, can_manage}]}]}. Chỉ có quản trị viên cấp cao. Bao gồm các thành viên khuyết tật

Việc không có sẵn thư mục không bỏ qua yêu cầu về phiên kín hoặc cấp thiết bị. GET /api/seal/root trả về 404 khi không có gốc không gian làm việc nào được xuất bản.

# Register this operator key (proof signed locally)
curl -sS -X POST "$BASE/api/seal/keys" \
  -H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
  -d '{"public_key":"<ed25519-b64>","label":"cli","proof":"<sig-b64>","issued_at_ms":1700000000000}'

curl -sS "$BASE/api/seal/keys" -H "Authorization: Bearer ${TOKEN}"

curl -sS -X POST "$BASE/api/seal/grants" \
  -H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
  -d '{"tokens":["rsg1.…"]}'

curl -sS "$BASE/api/seal/grants?mine=1" -H "Authorization: Bearer ${TOKEN}"

Chứng chỉ trung gian (rsc1.)

Exchange lưu trữ chứng chỉ trung gian để khóa không phải gốc có thể ký các cấp phép mà thiết bị sẽ chấp nhận. Nó xác minh chữ ký Ed25519 của nhà phát hành và không thể giả mạo chứng chỉ. Tải mã thông báo lên không phải là ủy quyền: người gọi phải là nhà điều hành của tổ chức phát hành. Chứng chỉ có chữ ký gốc (issuer_key tương đương với gốc của không gian làm việc đã xuất bản) chỉ có thể được xuất bản bởi quản trị viên cấp cao của không gian làm việc. Một sản phẩm trung gian chỉ có thể được xuất bản bởi tài khoản có khóa con dấu đã đăng ký là issuer_key và bản thân nhà phát hành đó phải là đối tượng của chứng chỉ được lưu trữ, chưa bị thu hồi, chưa hết hạn với can_issue. Trẻ phải ở trong cấp độ, phạm vi thiết bị và thời hạn sử dụng của cha mẹ (áp dụng các thiết bị kiểm tra tương tự). Xuất bản lại (issuer_key, subject_key) tương tự sẽ thay thế hàng cũ hơn và xóa việc thu hồi.

GET /api/seal/certs/chain?subject_key= trả về {chain:[tokens]} nhà phát hành đi bộ liên kết đến thư mục gốc đã xuất bản, tối đa 4 chứng chỉ, chứng chỉ gốc được cấp trước hoặc 404. Bất kỳ thành viên được xác thực nào cũng có thể gọi nó. GET /api/seal/grants?mine=1 cho biết thêm rằng chain đối với các khoản trợ cấp mà người ký không phải là người gốc, vì vậy khách hàng sẽ nhận được nó cùng với khoản trợ cấp. Các khoản tài trợ được ký bởi người chủ bỏ qua chain.

GET /api/seal/certs liệt kê mọi hàng, bao gồm cả những hàng bị thu hồi (quản trị viên và quản trị viên cấp cao). DELETE /api/seal/certs/{serial} (tài khoản của nhà phát hành hoặc quản trị viên cấp cao) đặt revoked. Điều đó chỉ dừng phân phối. Các thiết bị tiếp tục tôn trọng bản sao mà chúng đã có cho đến khi nó hết hạn; thu hồi cứng là revoked_keys của chính sách thiết bị. {serial} là chuỗi nối tiếp base64 tiêu chuẩn được mã hóa URL.

Phương pháp và đường dẫn Thân hình thành công
POST /api/seal/certs {"token":"rsc1.…"} chứng chỉ được lưu trữ (được cấp bởi nhà phát hành và chủ đề)
GET /api/seal/certs/chain?subject_key= — {chain:["rsc1.…"]}, được cấp root trước hoặc 404
GET /api/seal/certs — [{serial, issuer_key, subject_key, token, expires_at_ms, created_at, revoked}]. Quản trị viên hoặc quản trị viên cấp cao
DELETE /api/seal/certs/{serial} — 204. Nhà phát hành hoặc quản trị viên cấp cao. Chỉ dừng phân phối
curl -sS -X POST "$BASE/api/seal/certs" \
  -H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
  -d '{"token":"rsc1.…"}'

curl -sS "$BASE/api/seal/certs/chain?subject_key=<ed25519-b64>" \
  -H "Authorization: Bearer ${TOKEN}"

Sao lưu khóa gốc của không gian làm việc (tùy chọn)

PUT / GET / DELETE /api/seal/backup lưu trữ một đốm màu rsb1. mờ đục cho mỗi tài khoản. PUT và GET chỉ dành cho quản trị viên cấp cao: blob là không gian làm việc root khóa riêng, được mã hóa trên máy khách bằng Argon2id (64 MiB, t=3, p=1) và ChaCha20-Poly1305. Cụm mật khẩu là tùy chọn và không có độ mạnh bắt buộc. Với cụm mật khẩu trống hoặc yếu, bất kỳ ai nắm giữ blob (bao gồm Exchange) đều có thể giải mã khóa gốc và kiểm soát mọi thiết bị. Tải lên là tùy chọn; khách hàng có thể xuất khóa gốc (rsk1.) và giữ nó ngoại tuyến. Exchange kiểm tra xem blob có bắt đầu bằng rsb1. và độ dài của nó không, đồng thời không bao giờ giải mã. GET được giới hạn ở 5 yêu cầu cho mỗi tài khoản mỗi giờ cho mỗi quy trình (HTTP 429). Việc đọc, ghi và xóa chỉ được kiểm tra bằng số byte. Phản hồi gửi Cache-Control: no-store.

Phương pháp và đường dẫn Thân hình thành công
PUT /api/seal/backup {"blob":"rsb1.…"} {blob, updated_at}
GET /api/seal/backup — {blob, updated_at} hoặc 404 khi không được lưu trữ. Tỷ lệ giới hạn
DELETE /api/seal/backup — 204, kể cả khi không có hàng nào tồn tại
curl -sS -X PUT "$BASE/api/seal/backup" \
  -H "Authorization: Bearer ${TOKEN}" -H 'Content-Type: application/json' \
  -d '{"blob":"rsb1.…"}'

curl -sS "$BASE/api/seal/backup" -H "Authorization: Bearer ${TOKEN}"

curl -sS -X DELETE "$BASE/api/seal/backup" -H "Authorization: Bearer ${TOKEN}"

Xác thực chuỗi gốc của phần mở rộng trình duyệt

Hoạt động của trình duyệt sử dụng các phiên WebSocket được niêm phong riêng, không phải HTTP một lần thi hành. Tiện ích mở rộng tự tạo khóa toán tử Ed25519. Với một nhà điều hành Mã thông báo mang nó nhận được tenant_id / operator_id từ /api/auth/me, sau đó gọi POST /api/seal/keys với {public_key, label, proof, issued_at_ms}. Dấu hiệu PoP:

remote-seal-key-register:v1:<workspace_id>:<operator_id>:<public_key>:<issued_at_ms>

Khóa/chữ ký là base64 tiêu chuẩn (32/64 byte); thời gian phải nằm trong khoảng ±10 phút của đồng hồ máy chủ. Việc đăng ký chứng tỏ sự sở hữu chứ không phải sự ủy quyền. Tiện ích mở rộng đồng bộ hóa GET /api/seal/root, GET /api/seal/grants?mine=1 và mã thông báo chứng chỉ được bao gồm trong các khoản trợ cấp hoặc được lấy từ GET /api/seal/certs/chain?subject_key=<url-encoded-key>. Các khoản tài trợ phải được xác minh để gốc không gian làm việc đáng tin cậy, trực tiếp hoặc thông qua chuỗi chứng chỉ hợp lệ, với phạm vi, mức độ và hiệu lực của thiết bị chính xác. Đăng ký mã thông báo thiết bị vẫn còn tách biệt khỏi luồng thư mục mã thông báo toán tử này.

Tiện ích mở rộng xác minh các địa chỉ gốc đến thông qua thư mục gốc của nó và bao gồm sở hữu chữ ký xin chào/cấp/chuỗi trong SealAccept.peer. CLI/console xác minh bằng chứng đó và yêu cầu peer.operator_key == accept.device_key trước khi chấp nhận chữ ký phản hồi. Các tác nhân Rust sử dụng chính sách gốc thông thường của chúng khi tiện ích mở rộng hoạt động như một nhà điều hành. Bằng chứng không hợp lệ/thiếu không đóng được; không có trình duyệt riêng cửa hàng tin cậy/giao diện người dùng hoặc dự phòng kế thừa. TOFU gốc của thiết bị gốc và không gian làm việc vẫn còn; tiện ích mở rộng lưu trữ thư mục gốc đầu tiên trên mỗi máy chủ/không gian làm việc và từ chối các thay đổi.

Security: xác minh root đầu tiên ngoài băng tần; PoP hoặc vai trò máy chủ không phê duyệt gốc. Xem lại các khóa không xác định trước khi tự động phê duyệt máy khách gốc. Bảo vệ hồ sơ/khóa điểm cuối và tập lệnh được lưu trữ. Xóa thư mục không thu hồi thông tin xác thực đã ký được lưu trong bộ nhớ đệm. Exchange có thể xem siêu dữ liệu, giữ lại thông tin xác thực hoặc từ chối dịch vụ; việc niêm phong không cô lập toán tử CDP đầy đủ thù địch.

Chọn WebSocket hoặc HTTPS

Cần sử dụng
Lệnh, kiểm tra hoặc hủy bỏ công việc được giữ lại, cảm biến, thăm dò mạng, cập nhật, ubus, lệnh được ghim Phiên WebSocket được niêm phong riêng
PTY tương tác, đầu ra phát trực tuyến, truyền tập tin, màn hình/cây/tấn Android Phiên WebSocket được niêm phong riêng
Xác thực, kiểm kê thiết bị, thư mục khóa/cấp/chứng chỉ, sao lưu gốc API HTTPS
Kiểm kê và hủy phiên định tuyến Exchange Điểm cuối quản trị phiên HTTPS
Sự hiện diện của thiết bị trực tiếp và kết nối nhà điều hành lâu dài WebSocket; hoạt động của thiết bị trên kết nối vẫn yêu cầu niêm phong

Luồng vé trình duyệt (thông tin xác thực không bao giờ có trong URL WebSocket):

  1. POST /api/ws-ticket với Authorization: Bearer ….
  2. Kết nối với GET /ws/browser và gửi khung JSON đầu tiên {"ticket":"…"}.
  3. Thiết lập bắt tay máy khách/thiết bị kín gốc trước khi gửi bất kỳ thao tác thiết bị nào. Chuỗi cấp và chứng chỉ của nhà điều hành phải xác thực dựa trên thư mục gốc được thiết bị tin cậy.

Máy khách gốc sử dụng GET /ws/operator với xác thực của nhà điều hành và yêu cầu phiên kín tương tự. Chỉ riêng kết nối WebSocket hoặc đăng nhập tài khoản thành công không cho phép thiết bị hoạt động. Xem Bảng điều khiển web và Web Push, protocol và phiên kín.

Bảng ghi trạng thái lỗi

Trạng thái Nguyên nhân điển hình
400 Đầu vào hành động không hợp lệ, chẳng hạn như lệnh trống hoặc URL nguồn cập nhật không hợp lệ; xác nhận xảy ra trước khi từ chối phiên kín
401 Mã thông báo Bearer bị thiếu hoặc không hợp lệ
403 Quyền tài khoản hoặc thiết bị không cho phép yêu cầu
409 Hành động của thiết bị HTTP hợp lệ, được ủy quyền yêu cầu phiên WebSocket được niêm phong; không có sự gửi thiết bị nào xảy ra
404 Thiếu mục nhập thư mục hoặc gốc không gian làm việc chưa được xuất bản, theo hợp đồng điểm cuối
429 Giới hạn tốc độ dành riêng cho điểm cuối, bao gồm cả các lần đọc bản sao lưu gốc của không gian làm việc
503 Kiểm kê phiên không thể tìm thấy thiết bị ở trạng thái trung tâm Exchange cục bộ

Các tuyến HTTP hành động của thiết bị không chờ đầu ra agent, vì vậy, kết quả được ủy quyền thông thường của chúng là 409, không phải là thực thi thành công, lỗi gửi ngoại tuyến hoặc hết thời gian thực thi HTTP. Các lỗi từ siêu dữ liệu, xác thực và API thư mục vẫn giữ nguyên ý nghĩa dành riêng cho điểm cuối của chúng.

Kế hoạch xác nhận thủ công

Sử dụng tài khoản thử nghiệm và thiết bị có quyền đã biết. Kiểm tra từ chối HTTP không yêu cầu thực thi công việc trên thiết bị:

  1. Xác thực và liệt kê các thiết bị qua HTTPS; xác minh quyền của tài khoản và thiết bị.
  2. Gửi yêu cầu hợp lệ tới từng lộ trình hành động của thiết bị trong bảng từ chối. Yêu cầu HTTP 409 và xác nhận rằng không có hành động nào đạt tới agent, bao gồm cả các lần đọc lệnh được giữ lại và chạy lệnh được ghim.
  3. Kiểm tra riêng thông tin đăng nhập không hợp lệ, tài khoản bị cấm và yêu cầu nhập không hợp lệ. Mong đợi các lỗi xác thực, quyền và xác thực thay vì giả sử mọi yêu cầu đều trả về 409.
  4. Đọc kho lưu trữ phiên Exchange. Đối với phiên dùng một lần được chọn rõ ràng, hãy hủy kiểm tra và xác minh released; một phiên bị thiếu sẽ trả về released:false. Danh sách phiên trên thiết bị ngoại tuyến cục bộ trả về 503.
  5. Hoàn thành phê duyệt và cấp quyền gốc, sau đó chạy thao tác CLI gốc vô hại như remote-cli exec "$DEVICE_ID" -- uname -a. Xác minh nó thành công thông qua cái bắt tay kín. Cấp thiết bị bị thiếu hoặc không hợp lệ phải đóng không thành công.
  6. Xác thực đăng ký khóa, cấp/truy xuất chứng chỉ, sao lưu gốc tùy chọn và xác thực chuỗi gốc của trình duyệt một cách độc lập; các API HTTPS đó vẫn có sẵn theo các hợp đồng ở trên.

Đích xuất nhật ký kiểm toán

Chỉ hỗ trợ PostgreSQL Exchange, trong phạm vi không gian làm việc đã xác thực. Chỉ quản trị viên và superadmin được sử dụng; tài khoản khác nhận 403. Không hỗ trợ exchange-worker; chưa có giao diện cấu hình trên Web/Mobile Console.

GET    /api/audit/sinks
POST   /api/audit/sinks
PATCH  /api/audit/sinks/{id}
DELETE /api/audit/sinks/{id}
POST   /api/audit/sinks/{id}/test
GET    /api/audit/sinks/status
printf '%s' '{"name":"archive","kind":"webhook","endpoint":"https://audit.example.net/events","secret":"REPLACE-WITH-RANDOM-SECRET","mode":"full"}' | remote-cli audit sink add
remote-cli audit sink list
printf '%s' '{"interval_ms":500,"batch_size":16}' | remote-cli audit sink update 1
remote-cli audit sink test 1
remote-cli audit sink status
remote-cli audit sink remove 1

Chế độ throttled mặc định xuất các bản ghi kiểm toán đã lưu: văn bản vượt 256 KiB giữ 250 KiB đầu và 6 KiB cuối, tệp được biểu diễn bằng hàm băm, luồng được xuất sau khi phiên kết thúc. Chế độ full thu thập trước khi cắt ngắn, chia JSON gốc và nội dung nhị phân thành các khối (mặc định 1 MiB), kèm ID thao tác/tài sản, số thứ tự, độ lệch, dấu kết thúc, SHA-256 và tổng kích thước. Với phiên kín, cả hai chế độ chỉ xuất siêu dữ liệu và tham chiếu/hàm băm của bản mã; không chế độ nào khôi phục văn bản rõ tại thiết bị đầu cuối.

Bí mật và tiêu đề được mã hóa và hiển thị lại dưới dạng ***. PATCH giữ nguyên giá trị ***; tiêu đề có giá trị null sẽ bị xóa. Việc gửi dùng hàng đợi FIFO bền vững bất đồng bộ và thử lại với thời gian chờ tăng theo cấp số nhân. Khi đầy, hàng đợi throttled loại bỏ và đếm bản ghi cũ nhất; hàng đợi full trên đĩa áp dụng cơ chế làm chậm bên gửi. Trạng thái bao gồm thành công/thất bại, tồn đọng, số bản ghi bị loại bỏ và khoảng trống. Xóa đích sẽ loại bỏ dữ liệu đang chờ và ghi lại số lượng. Thay đổi cấu hình được kiểm toán trong cùng giao dịch.

Webhook gửi mảng events trong JSON với dữ liệu byte dạng base64. Xác minh X-Remote-Timestamp và X-Remote-Signature: sha256=<hex> bằng HMAC-SHA256(timestamp + "." + raw body). OTel dùng OTLP/HTTP JSON /v1/logs, body.bytesValue cho các khối, thuộc tính remote.device.id / remote.operator / remote.action và service.name có thể cấu hình. gRPC cần Collector làm cầu nối; không có bộ xuất gRPC trực tiếp.

Bên dưới là ví dụ cấu hình mặc định, payload webhook, xác minh chữ ký và Collector. Xác minh phần thân HTTP thô; lưu bền vững và loại trùng theo delivery_id trước khi trả về 2xx. Bật allow_structured_metadata trong Loki 3.x, thêm nguồn dữ liệu Loki trong Grafana và truy vấn {service_name="remote-exchange"}. Để dùng gRPC, đổi exporters của pipeline thành [otlp/grpc]. Dùng TLS và xác thực trong môi trường sản xuất.

{"name":"collector","kind":"otel","mode":"throttled","endpoint":"https://collector.example.net:4318/v1/logs","headers":{"Authorization":"Bearer REPLACE"},"service_name":"remote-exchange","resource":{"deployment.environment.name":"production"},"batch_size":32,"interval_ms":1000,"chunk_bytes":1048576,"queue_limit":10000,"overflow_bytes":10737418240,"actions":[],"devices":[],"operators":[],"enabled":true,"ca_pem":null}
{"version":1,"events":[{"delivery_id":123,"type":"full","mode":"full","entry":{"id":42,"action":"exec","operator_name":"alice","device_id":"dev"},"data":{"kind":"binary","asset_id":"asset-uuid","path":"/data_base64","sequence":0,"offset":0,"last":true,"data_base64":"YWJj","total_size":3,"sha256":"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad","context":{"direction":"output","frame_sequence":0,"stream_offset":0}}}]}
import hashlib, hmac, time

def verify(headers, raw_body, secret):
    stamp = headers['X-Remote-Timestamp']
    if abs(time.time() - int(stamp)) > 300:
        raise ValueError('expired webhook')
    expected = 'sha256=' + hmac.new(
        secret.encode(), stamp.encode() + b'.' + raw_body, hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(expected, headers['X-Remote-Signature']):
        raise ValueError('invalid signature')
receivers:
  otlp:
    protocols:
      http:
        endpoint: 127.0.0.1:4318
processors:
  batch: {}
exporters:
  otlphttp/loki:
    endpoint: http://loki:3100/otlp
  otlp/grpc:
    endpoint: telemetry.example.net:4317
    headers:
      Authorization: "${env:OTEL_AUTHORIZATION}"
    tls:
      insecure: false
service:
  pipelines:
    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlphttp/loki]
Trường kiểm toán Trường OTLP
service_name / resource Resource service.name / attributes
entry.started_at timeUnixNano
entry.id / delivery_id remote.audit.id / remote.delivery.id
entry.device_id / operator_name / action remote.device.id / remote.operator / remote.action
entry.tenant_id remote.workspace.id
entry.started_at / ended_at / detail remote.started_at / remote.ended_at / remote.result
traceId / spanId traceId / spanId
data.data_base64 body.bytesValue / remote.chunk.*
Sự kiện đã lưu body.stringValue