dungnh
Intern
Tích hợp Headwind MDM (HMDM) thông qua eyeExtend connect với Forescout
Source app : GithubSource hmdm : Github
1. Tổng quan về Forescout eyeExtend Connect Module
Forescout eyeExtend Connect (trước đây được gọi là Connect Plugin) là một module tích hợp linh hoạt và mạnh mẽ của giải pháp bảo mật Forescout CounterACT. Module này đóng vai trò như một cầu nối vạn năng, cho phép Forescout dễ dàng tương tác và chia sẻ thông tin hai chiều với các hệ thống quản lý, bảo mật và vận hành CNTT của bên thứ ba (như MDM/EMM, SIEM, ITSM, Firewall, EDR) thông qua các giao thức giao tiếp tiêu chuẩn, đặc biệt là RESTful API, Webhooks và Scripting (Python).
Connect Plugin hoạt động dựa trên cơ chế hướng sự kiện và hướng chính sách. Thay vì cần phát triển mã nguồn đóng trong nhân của CounterACT, Connect cho phép quản trị viên hoặc các đối tác phát triển các ứng dụng độc lập (Connect Apps) được đóng gói dưới dạng tệp tin nén (.zip). Khi ứng dụng này được nhập (import) vào Forescout, hệ thống sẽ tự động sinh ra giao diện cấu hình, cơ sở dữ liệu lưu trữ tạm thời và cơ chế định kỳ chạy các kịch bản thực thi.
- Hệ thống Forescout CounterACT giữ vai trò điều phối chính sách (Policy Engine), phát hiện thiết bị trên mạng và đưa ra các quyết định hành động.
- Connect Plugin đóng vai trò môi giới chuyển dịch yêu cầu: Nó tiếp nhận thông tin từ Forescout, đóng gói dữ liệu và gọi API phù hợp tới hệ thống đích (ví dụ: HMDM). Ngược lại, nó nhận kết quả trả về từ API và phân dịch thành các thuộc tính máy chủ để Forescout xử lý.
- Môi trường thực thi kịch bản (Execution Engine): Hỗ trợ chạy các file kịch bản Python 3 trực tiếp trên Appliance của Forescout, có khả năng truy cập thư viện chuẩn và xử lý JSON, HTTP nâng cao.
1.2 Các thành phần chính trong một Connect App
Một ứng dụng eyeExtend Connect hoàn chỉnh luôn bao gồm các cấu trúc tệp tin cấu hình và thư mục mã nguồn cốt lõi sau:
Tệp system.conf, định nghĩa giao diện người dùng hiển thị trên giao diện điều khiển Forescout Console. Tệp tin này mô tả các tham số kết nối bắt buộc như:
Một ứng dụng eyeExtend Connect hoàn chỉnh luôn bao gồm các cấu trúc tệp tin cấu hình và thư mục mã nguồn cốt lõi sau:
Tệp system.conf, định nghĩa giao diện người dùng hiển thị trên giao diện điều khiển Forescout Console. Tệp tin này mô tả các tham số kết nối bắt buộc như:
- Địa chỉ máy chủ (URL)
- Thông tin đăng nhập (Username, Password mã hóa),
- Khoảng thời gian làm mới khóa token ủy quyền (Authorization Refresh Interval)
- Việc phân chia Focal Appliance (thiết bị CounterACT chịu trách nhiệm thực thi giao tiếp).
Tệp property.conf, tệp này định nghĩa các cấu hình như sau:
- Groups: Nhóm logic hiển thị các thuộc tính trên Forescout Console.
- Properties: Định nghĩa các thuộc tính máy chủ (Host Properties) sẽ được thu thập từ hệ thống đích. Mỗi thuộc tính có kiểu dữ liệu riêng (string, integer, boolean, composite list), cơ chế tự động phân giải (resolvable), và sự phụ thuộc vào các thuộc tính khác (ví dụ: phụ thuộc vào IP của thiết bị).
- Actions: Định nghĩa các hành động thực thi điều khiển (Control Actions) mà quản trị viên có thể kích hoạt thủ công hoặc tự động hóa thông qua chính sách trên Forescout. Mỗi hành động có thể yêu cầu các tham số đầu vào (ví dụ: nội dung tin nhắn gửi đi, ID cấu hình mới).
- Scripts: Ánh xạ trực tiếp từng chức năng (Test, Authorization, Resolve, Actions) với các tệp kịch bản Python tương ứng trong gói zip.
Các đoạn mã Python độc lập thực thi logic nghiệp vụ. Khi có sự kiện cần phân giải thuộc tính hoặc thực thi hành động, Forescout sẽ khởi chạy tiến trình Python và truyền các tham số thông qua một biến toàn cục có tên 'params'. Kết quả thực thi sau đó được lưu vào một biến dict có tên 'response' để gửi ngược về lõi Forescout.Các kịch bản thực thi Python (.py):
**QUY TẮC PHÁT TRIỂN PYTHON TRÊN CONNECT: Tất cả các kịch bản Python chạy trong môi trường Forescout eyeExtend Connect đều chạy dưới quyền hạn cô lập của tài khoản hệ thống không có đặc quyền (sandbox). Tránh sử dụng các lệnh gọi hệ điều hành trực tiếp như subprocess hoặc os.system trừ khi thực sự cần thiết, và luôn sử dụng thư viện tiêu chuẩn như urllib thay vì cài đặt thêm thư viện bên ngoài để đảm bảo tính tương thích và bảo mật.**
Tài liệu tham khảo : Documentation, Guide
2. Tổng quan về Headwind Mobile Device Management (HMDM)**QUY TẮC PHÁT TRIỂN PYTHON TRÊN CONNECT: Tất cả các kịch bản Python chạy trong môi trường Forescout eyeExtend Connect đều chạy dưới quyền hạn cô lập của tài khoản hệ thống không có đặc quyền (sandbox). Tránh sử dụng các lệnh gọi hệ điều hành trực tiếp như subprocess hoặc os.system trừ khi thực sự cần thiết, và luôn sử dụng thư viện tiêu chuẩn như urllib thay vì cài đặt thêm thư viện bên ngoài để đảm bảo tính tương thích và bảo mật.**
Tài liệu tham khảo : Documentation, Guide
Headwind Mobile Device Management (HMDM) là một nền tảng quản lý thiết bị di động (Mobile Device Management) mã nguồn mở mạnh mẽ, được thiết kế chuyên biệt cho hệ điều hành Android. HMDM cung cấp giải pháp toàn diện cho phép các doanh nghiệp và tổ chức cấu hình, giám sát, theo dõi vị trí, phân phối ứng dụng và bảo vệ các thiết bị di động thuộc sở hữu của doanh nghiệp hoặc thiết bị cá nhân tham gia vào mạng lưới nội bộ (BYOD - Bring Your Own Device).
2.1 Các thành phần chính trong một Connect App
Kiến trúc của Headwind MDM bao gồm hai phần chính hoạt động phối hợp chặt chẽ:- HMDM Web Console (Server-side): Được xây dựng trên nền tảng Java (Tomcat) và cơ sở dữ liệu PostgreSQL. Server này chịu trách nhiệm cung cấp giao diện quản trị đồ họa web, lưu trữ cơ sở dữ liệu thiết bị, quản lý các tập tin ứng dụng (.apk), định nghĩa các cấu hình (Configurations) và cung cấp hệ thống REST API phong phú phục vụ cho việc tích hợp với bên thứ ba.
- HMDM Launcher (Client-side): Là một ứng dụng Android đặc quyền (thường được thiết lập làm màn hình chính - Launcher mặc định và chạy dưới chế độ Device Owner). Launcher này liên tục kết nối với máy chủ HMDM qua giao thức HTTPS và WebSockets để đồng bộ hóa cấu hình, cài đặt ứng dụng âm thầm, thu thập trạng thái phần cứng và thực thi các mệnh lệnh từ xa.
| Tính năng | Mô tả chi tiết | Khả năng tương tác qua API |
| Quản lý cấu hình (Configuration) | Thiết lập hồ sơ chính sách cho thiết bị bao gồm ứng dụng được phép chạy, giao diện màn hình nền, độ sáng, Wi-Fi, quyền hạn hạn chế người dùng. | Có thể đọc danh sách và gán cấu hình mới cho thiết bị từ xa qua API. |
| Phân phối ứng dụng (App Deployment) | Tự động cài đặt, cập nhật hoặc gỡ bỏ ứng dụng Android (.apk) mà không cần sự can thiệp của người dùng cuối. | Theo dõi danh sách ứng dụng đã cài đặt trên từng thiết bị. |
| Giám sát thiết bị (Device Monitoring) | Thu thập thông tin phần cứng theo thời gian thực bao gồm: Mức pin, dung lượng bộ nhớ, địa chỉ IP (mạng ngoài/mạng trong), phiên bản Android, số Serial, nhà sản xuất, chip xử lý (CPU). | Cung cấp đầy đủ qua API plugin Device Info. |
| Chế độ Kiosk (Kiosk Mode) | Khóa thiết bị Android chỉ cho phép chạy một hoặc một nhóm ứng dụng chỉ định, ngăn chặn truy cập vào phần cài đặt hệ thống. | Cho phép thay đổi trạng thái cấu hình để bật/tắt Kiosk mode. |
| Nhóm thiết bị (Device Grouping) | Phân loại thiết bị thành các nhóm logic (như Sales, IT, Warehouse, Quarantine) để áp đặt chính sách hàng loạt. | Hỗ trợ thêm, xóa và chuyển đổi nhóm cho thiết bị qua API. |
| Tin nhắn đẩy (Push Messaging) | Hệ thống tin nhắn khẩn cấp gửi từ quản trị viên trực tiếp xuất hiện trên màn hình khóa hoặc màn hình chính của thiết bị Android. | Thực hiện gửi tin nhắn tức thời qua API plugin Messaging. |
3. Ứng dụng hmdm_connect
Ứng dụng `hmdm_connect` là một Connect App được thiết kế để tích hợp Forescout với Headwind MDM. Dưới đây là phân tích chi tiết cấu trúc thư mục, các tệp cấu hình và mã nguồn thực thi của ứng dụng này.
3.1 Cấu trúc thư mục của ứng dụng hmdm_connect
Thư mục của ứng dụng bao gồm các thành phần sau:
- system.conf: Định nghĩa các tham số kết nối đến server Headwind MDM.
- property.conf: Định nghĩa các thuộc tính thiết bị thu thập từ HMDM và các hành động thực thi.
- hmdm_authorization.py: Kịch bản xác thực định kỳ lấy JWT token.
- hmdm_resolve.py: Kịch bản phân giải thuộc tính thiết bị theo IP.
- hmdm_push_send.py: Hành động gửi tin nhắn đến thiết bị cụ thể.
- hmdm_push_send_group.py: Hành động gửi tin nhắn đến một nhóm thiết bị.
- hmdm_device_change_config.py: Hành động thay đổi Configuration của thiết bị.
- hmdm_device_change_group.py: Hành động thay đổi Nhóm (Group) của thiết bị. hmdm_test.py: Kịch bản kiểm tra kết nối từ Forescout tới HMDM server.
Tệp tin system.conf định cấu hình giao diện kết nối giữa Forescout Appliance và HMDM. Hệ thống yêu cầu 3 trường thông tin nhập liệu cơ bản:
- connect_hmdm_url (Server URL): Địa chỉ truy cập REST API của máy chủ Headwind MDM (Ví dụ: http://10.10.10.200:8080).
- connect_hmdm_username (Username): Tài khoản quản trị viên HMDM dùng để gọi API.
- connect_hmdm_password (Password): Mật khẩu quản trị viên (được mã hóa bảo mật dạng 'encrypted').
- Interval (Chu kỳ làm mới xác thực): Đặt mặc định là 4 phút để tự động chạy lại kịch bản hmdm_authorization.py lấy token mới.
Tệp tin này đóng vai trò bản đồ định tuyến, kết nối các thuộc tính và hành động của Forescout với các kịch bản Python cụ thể .
3.3.1 Danh sách Thuộc tính (Properties) được định nghĩa:
| Tên thuộc tính (Tag) | Nhãn hiển thị (Label) | Kiểu dữ liệu | Mô tả |
| connect_hmdm_device_number | HMDM Device Number | string | Mã số định danh duy nhất của thiết bị trong HMDM |
| connect_hmdm_model | HMDM Phone Model | string | Tên dòng máy/mẫu điện thoại Android |
| connect_hmdm_android_version | HMDM Android Version | string | Phiên bản hệ điều hành Android hiện tại |
| connect_hmdm_group | HMDM Group Name | string | Tên các nhóm thiết bị mà thiết bị này thuộc về |
| connect_hmdm_apps | HMDM Installed Apps | composite list | Danh sách tất cả tên ứng dụng được cài đặt trên thiết bị |
| connect_hmdm_serial | HMDM Serial Number | string | Số Serial phần cứng của thiết bị Android |
| connect_hmdm_cpu | HMDM CPU | string | Kiến trúc chip xử lý của thiết bị |
| connect_hmdm_config | HMDM Configuration Name | string | Tên cấu hình hiện tại đang được gán cho thiết bị |
3.3.2 Danh sách Hành động (Actions) được định nghĩa:
| Tên hành động | Nhãn hiển thị | Tham số yêu cầu | Mô tả hành động |
| connect_hmdm_push_send | HMDM Send Message | connect_hmdm_message (string, mandatory) | Gửi tin nhắn cảnh báo tới thiết bị Android tương ứng dựa trên IP của nó. |
| connect_hmdm_push_send_group | HMDM Send Message to Group | connect_hmdm_group_name (string, mandatory), connect_hmdm_message (string, mandatory) | Gửi tin nhắn đồng loạt tới tất cả các thiết bị thuộc một Nhóm nhất định trên HMDM. |
| connect_hmdm_change_group | HMDM Change Group | connect_hmdm_group_name (string, mandatory), connect_hmdm_group_action (string, optional - add/remove/replace) | Thêm, xóa hoặc thay thế nhóm thiết bị trên HMDM. |
| connect_hmdm_change_config | HMDM Change Configuration | connect_hmdm_config_id (integer, mandatory) | Thay đổi cấu hình/profile hoạt động của thiết bị dựa trên ID cấu hình trong HMDM. |
3.4 Phân tích chi tiết mã nguồn và thuật toán xử lý
Mỗi kịch bản Python trong ứng dụng được phát triển bằng ngôn ngữ Python 3, tuân thủ nghiêm ngặt chuẩn giao tiếp không dùng thư viện ngoài (sử dụng urllib.request để gọi API) nhằm đảm bảo hiệu năng và tính ổn định trên Forescout CounterACT Appliance.
3.4.1 Xác thực : hmdm_authorization.pyKịch bản này chịu trách nhiệm gửi yêu cầu đăng nhập đến Headwind MDM để nhận mã JWT token. Token này sau đó được lưu trữ trong bộ nhớ tạm thời của Connect và tự động truyền vào các kịch bản khác thông qua tham số `connect_authorization_token`.
Lưu ý đặc biệt: Thuật toán mã hóa mật khẩu:HMDM yêu cầu mật khẩu gửi qua API phải được băm (hash) bằng MD5 và chuyển thành chữ in hoa (uppercase). Do đó, kịch bản thực hiện băm như sau:
| md5_hash = hashlib.md5(password.encode("utf-8")).hexdigest() md5_upper = md5_hash.upper() |
Endpoint API sử dụng:
- Method: POST
- URI: /rest/public/jwt/login
- Request Headers: {'Content-Type': 'application/json; charset=utf-8'}
- Request Body: { "login": "<username>", "password": "<MD5_UPPERCASE_HASH>" }
- Response (Success 200): Trả về một đối tượng JSON chứa thuộc tính "id_token".
- Đọc tham số:Đọc thông tin cấu hình URL, Username, Password từ đối tượng toàn cục `params`.
- Mã hóa:Tính toán hash MD5 viết hoa của Password để bảo mật khi truyền trên mạng.
- Gọi API:Khởi tạo đối tượng `urllib.request.Request` gửi POST đến API Login của HMDM.
- Nhận Token:Đọc mã phản hồi HTTP. Nếu thành công (HTTP 200), phân tích JSON để trích xuất `id_token`.
- Trả kết quả:Ghi nhận token vào biến phản hồi: `response["token"] = token` và đặt `response["succeeded"] = True`.
Kịch bản này được kích hoạt khi Forescout phát hiện ra một thiết bị mạng có địa chỉ IP và cần phân giải các thuộc tính HMDM liên quan đến thiết bị đó. Kịch bản thực hiện một quy trình gồm 3 bước liên tuần tự:
Bước 1: Tìm kiếm thiết bị để ánh xạ địa chỉ IP. Do Forescout chỉ biết địa chỉ IP của thiết bị trong mạng, kịch bản phải truy vấn danh sách thiết bị trên HMDM để tìm thiết bị có `publicIp` trùng khớp với IP của Forescout.
- Endpoint: POST /rest/private/devices/search
- Request Headers: {'Authorization': 'Bearer <token>', 'Content-Type': 'application/json'}
- Request Body: { "pageSize": 1000, "pageNum": 1 }
- Xử lý khớp dữ liệu: Kịch bản duyệt qua mảng các thiết bị trả về trong trường `data.devices.items` hoặc `data.items`, so khớp trường `publicIp` với IP hiện tại của host. Khi tìm thấy thiết bị khớp, kịch bản sẽ lấy ra hai thông tin then chốt: `number` (Device Number) và `configurationId`.
- Endpoint: GET /rest/plugins/deviceinfo/deviceinfo/private/{deviceNumber}
- Dữ liệu thu thập: Model thiết bị (`model`), phiên bản hệ điều hành (`osVersion` hoặc `androidVersion`), thông tin phần cứng (`serial`, `cpu`), danh sách nhóm (`groups`), và danh sách các ứng dụng đã cài đặt (`applications` chứa tên các ứng dụng).
- Endpoint chính: GET /rest/private/configurations/{configurationId}
- Cơ chế dự phòng (Fallback): Nếu API chi tiết bị chặn do phân quyền, kịch bản sẽ gọi GET /rest/private/configurations/list để tải toàn bộ danh sách cấu hình của hệ thống, sau đó duyệt tìm bản ghi có `id == configurationId` để lấy thuộc tính `name`.
3.4.3 Thông tin chi tiết : hmm_device_change_config.py
Hành động này cho phép quản trị viên thay đổi tập chính sách (profile) đang áp đặt lên thiết bị Android từ xa thông qua Forescout.
Luồng xử lý:
- Tìm ID:Tìm kiếm ID thiết bị trong HMDM: Sử dụng API `/rest/private/devices/search` và lọc theo địa chỉ IP của thiết bị đầu cuối tương tự như bước Resolve để lấy ID thiết bị (`id`) và cấu hình hiện tại (`configurationId`).
- Endpoint: PUT /rest/private/devices
- Request Headers: Chứa JWT token xác thực.
- Request Body: { "ids": [device_id], "configurationId": <target_config_id> }
- Mô tả kỹ thuật: Định dạng cập nhật này sử dụng danh sách `ids` để gửi cập nhật cấu hình cho thiết bị cụ thể mà không làm ảnh hưởng hoặc ghi đè lên các thuộc tính bảo mật khác của thiết bị.
Kịch bản này hỗ trợ thay đổi phân loại nhóm của thiết bị di động trong HMDM. Đây là tính năng rất hữu ích để cách ly thiết bị khi phát hiện vi phạm.
Các tham số đầu vào:
- connect_hmdm_group_name: Tên nhóm đích (ví dụ: 'Quarantine', 'Sales').
- 'add': Thêm thiết bị vào nhóm mới (giữ nguyên các nhóm cũ của thiết bị).
- 'remove': Xóa thiết bị ra khỏi nhóm được chỉ định.
- 'replace' (Mặc định): Loại bỏ thiết bị khỏi tất cả các nhóm hiện tại của nó, chỉ gán duy nhất vào nhóm mới này.
Bước 1:Tìm thiết bị bằng IP thông qua POST `/rest/private/devices/search` để lấy ID thiết bị và danh sách nhóm hiện tại của thiết bị đó.
Bước 2:Truy vấn danh sách tất cả các nhóm trên HMDM bằng GET `/rest/private/groups/search` để đối chiếu tên nhóm nhập vào (`connect_hmdm_group_name`) và lấy ID của nhóm đích tương ứng.
Bước 3:Kiểm tra điều kiện: So khớp xem thiết bị đã nằm trong nhóm đích chưa để quyết định có cần gọi API hay không.
Bước 4:Thực hiện gọi API thay đổi nhóm hàng loạt (Group Bulk Update):
- Endpoint: POST /rest/private/devices/groupBulk
- Request Body: { "ids": [device_id], "action": "set" | "remove", "groups": [ { "id": <group_id>, "name": "<group_name>" } ] }
- Lưu ý: Đối với hành động 'replace', kịch bản sẽ thực hiện hai bước API liên tiếp: Đầu tiên gửi yêu cầu xóa ('remove') toàn bộ các nhóm cũ của thiết bị, sau đó gửi yêu cầu thiết lập ('set') nhóm mới duy nhất.
Hai kịch bản này hỗ trợ gửi tin nhắn cảnh báo dạng popup đẩy trực tiếp lên màn hình thiết bị Android của người dùng cuối.
- Cá nhân: hmdm_push_send.py (Gửi tới thiết bị cá nhân): Khớp thiết bị bằng địa chỉ IP thông qua tìm kiếm, lấy ra `deviceNumber` và gọi API gửi tin nhắn cá nhân.
- Toàn nhóm: hmdm_push_send_group.py (Gửi tới toàn nhóm): Lấy thông tin tên nhóm, truy vấn danh sách nhóm để lấy `groupId` của nhóm đích, sau đó gửi tin nhắn tới toàn bộ thiết bị thuộc nhóm đó.
- Endpoint: POST /rest/plugins/messaging/private/send
- Request Body (Gửi cá nhân):
| { "scope": "device", "deviceNumber": "DEVICE_NUM_XYZ", "groupId": 0, "configurationId": 0, "message": "Nội dung tin nhắn cảnh báo bảo mật" } |
- Request Body (Gửi nhóm):
| { "scope": "group", "groupId": 105, // ID của nhóm lấy từ API tìm kiếm nhóm "message": "Tin nhắn gửi tới toàn bộ thiết bị trong nhóm" } |
3.4.5 Bảng tổng hợp các API Endpoint của Headwind MDM sử dụng trong tích hợp
| Mục đích | Phương thức HTTP | URI Endpoint | Loại xác thực |
| Đăng nhập & Lấy JWT Token | POST | /rest/public/jwt/login | Không (Sử dụng Login/Password MD5) |
| Tìm kiếm & So khớp thiết bị theo IP | POST | /rest/private/devices/search | Bearer JWT Token |
| Lấy thông tin chi tiết thiết bị | GET | /rest/plugins/deviceinfo/deviceinfo/private/{deviceNumber} | Bearer JWT Token |
| Lấy chi tiết một cấu hình | GET | /rest/private/configurations/{id} | Bearer JWT Token |
| Tải toàn bộ danh sách cấu hình | GET | /rest/private/configurations/list | Bearer JWT Token |
| Tìm kiếm & Lấy ID của nhóm thiết bị | GET | /rest/private/groups/search | Bearer JWT Token |
| Cập nhật cấu hình thiết bị | PUT | /rest/private/devices | Bearer JWT Token |
| Cập nhật nhóm thiết bị (Thêm/Xóa) | POST | /rest/private/devices/groupBulk | Bearer JWT Token |
| Gửi tin nhắn đẩy (Cá nhân/Nhóm) | POST | /rest/plugins/messaging/private/send | Bearer JWT Token |
4. Tiến hành thực hành
Đầu tiên ta cần zip lại file để import vào Forescout, file .zip thì ở source trong link đầu trang.
Tiếp theo ta cần vào cli của Forescout để cấu hình cho phép import app unsigned (có nghĩa là app tự phát triển, chưa được Forescout ký)
fstool allow_unsigned_connect_app_install true
Tiếp đến ta cần license eyeExtend Connect Module để install module connect
Các bước này yêu cầu bạn phải triển khai hmdm-server rồi, triển khai hmdm-server thông qua link source trên hoặc vào phần link này : LINK
Tiếp đến ta sẽ vào hmdm-server và tạo device để add điện thoại vào
Khi mọi thử đã xong thi sẽ test thử các chức năng đã làm :
Đính kèm
Sửa lần cuối:
Bài viết liên quan
Bài viết mới