- 添加项目基础结构:Cargo.toml、.gitignore、设备UID和密钥文件 - 实现前端Vue3项目结构:路由、登录页面、设备管理页面 - 添加核心协议定义(crates/protocol):设备状态、资产、USB事件等 - 实现客户端监控模块:系统状态收集、资产收集 - 实现服务端基础API和插件系统 - 添加数据库迁移脚本:设备管理、资产跟踪、告警系统等 - 实现前端设备状态展示和基本交互 - 添加使用时长统计和水印功能插件
1647 lines
54 KiB
Markdown
1647 lines
54 KiB
Markdown
# 电脑终端监控系统开发计划
|
|
|
|
## 一、项目概述
|
|
|
|
### 1.1 项目背景
|
|
本项目旨在开发一个企业级电脑终端监控系统,用于监控企业内部Windows电脑终端的使用行为,保护企业信息安全,提升工作效率。系统采用客户端-服务器(C/S)架构,在员工电脑上部署客户端程序,在服务器端进行集中管理和监控。
|
|
|
|
### 1.2 系统目标
|
|
- **实时屏幕监控**: 实时查看员工电脑屏幕,支持多屏同时监控
|
|
- **上网行为监控**: 监控网站访问、应用程序使用、即时通讯等
|
|
- **文件操作监控**: 监控文件的创建、修改、删除、外发等操作
|
|
- **外设管理**: 管控USB设备、移动存储等外设的使用
|
|
- **资产管理**: 自动采集软硬件资产信息
|
|
- **远程控制**: 支持远程桌面控制,便于IT运维
|
|
|
|
### 1.3 系统特性
|
|
- **隐蔽性强**: 客户端后台运行,用户无感知
|
|
- **实时性高**: 屏幕监控延迟<1秒,行为监控实时上报
|
|
- **资源占用低**: 客户端CPU占用<5%,内存占用<100MB
|
|
- **稳定性好**: 7x24小时稳定运行,支持断线重连
|
|
- **安全性高**: 数据加密传输,防止信息泄露
|
|
|
|
## 二、系统架构设计
|
|
|
|
### 2.1 整体架构
|
|
采用全栈Rust架构,技术栈统一,性能卓越:
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 管理端(Tauri桌面应用) │
|
|
│ Tauri + Vue.js 3 + TypeScript │
|
|
│ - 实时屏幕墙(WebSocket接收) │
|
|
│ - 行为审计页面 │
|
|
│ - 资产管理页面 │
|
|
│ - 远程控制页面 │
|
|
│ - 报表统计页面 │
|
|
│ 体积: ~15MB | 内存: ~50MB | 启动: 0.3-0.6秒 │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓ HTTPS/WSS
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 服务端(Rust后端) │
|
|
│ Actix-web / Axum + Tokio + SQLx │
|
|
│ - 高性能异步Web框架 │
|
|
│ - WebSocket服务(屏幕流转发) │
|
|
│ - TCP服务(客户端连接) │
|
|
│ - MySQL + Redis连接池 │
|
|
│ - RESTful API │
|
|
│ 性能: 100k+ QPS | 内存: ~100MB │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓ TCP长连接 + 自定义协议
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 客户端(被监控端) │
|
|
│ Rust客户端(Windows服务) │
|
|
│ - 屏幕捕获模块(Windows API) │
|
|
│ - 行为监控模块(Hook技术) │
|
|
│ - 文件监控模块(ReadDirectoryChangesW) │
|
|
│ - 网络监控模块(WinPcap) │
|
|
│ - 外设管理模块(WMI) │
|
|
│ - 资产采集模块 │
|
|
│ 体积: ~3MB | 内存: ~30MB | CPU: <1% │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**架构优势:**
|
|
- ✅ **技术栈统一**: 客户端、服务端、管理端全部使用Rust
|
|
- ✅ **代码复用**: 共享协议定义、数据结构、工具函数
|
|
- ✅ **性能卓越**: Rust性能接近C++,内存安全无GC
|
|
- ✅ **体积小巧**: 管理端仅15MB,客户端仅3MB
|
|
- ✅ **开发高效**: Cargo统一构建,依赖管理简单
|
|
|
|
### 2.2 技术栈选型
|
|
|
|
#### 2.2.1 客户端技术栈(被监控端) - Rust
|
|
- **开发语言**: Rust (性能高、内存安全、无GC)
|
|
- **异步运行时**: Tokio 1.x (高性能异步IO)
|
|
- **屏幕捕获**: winapi + Windows GDI API
|
|
- **图像压缩**: image crate / jpeg-decoder
|
|
- **行为Hook**: retours库(Detours的Rust绑定) / minhook
|
|
- **网络通信**: tokio::net (异步TCP/UDP)
|
|
- **数据序列化**: serde + bincode / protobuf
|
|
- **加密传输**: rustls / native-tls (TLS 1.3)
|
|
- **本地存储**: sled / rocksdb (嵌入式数据库)
|
|
- **日志**: tracing + tracing-subscriber
|
|
- **错误处理**: anyhow / thiserror
|
|
|
|
**核心依赖:**
|
|
```toml
|
|
[dependencies]
|
|
tokio = { version = "1", features = ["full"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
bincode = "1"
|
|
image = "0.24"
|
|
retours = "0.1" # Hook库
|
|
winapi = { version = "0.3", features = ["winuser", "wingdi"] }
|
|
rustls = "0.21"
|
|
sled = "0.34"
|
|
tracing = "0.1"
|
|
anyhow = "1"
|
|
```
|
|
|
|
#### 2.2.2 服务端技术栈 - Rust
|
|
- **Web框架**: Actix-web 4.x (性能最强) 或 Axum 0.6 (更现代)
|
|
- **异步运行时**: Tokio 1.x
|
|
- **WebSocket**: actix-ws / tokio-tungstenite
|
|
- **数据库连接**: SQLx (编译时检查) 或 Diesel 2.x
|
|
- **数据库**: MySQL 8.0 / PostgreSQL
|
|
- **缓存**: Redis (redis crate)
|
|
- **连接池**: deadpool / mobc
|
|
- **文件存储**: 本地文件系统 / MinIO (对象存储)
|
|
- **日志**: tracing + tracing-subscriber
|
|
- **配置管理**: config crate
|
|
- **序列化**: serde + serde_json
|
|
|
|
**核心依赖:**
|
|
```toml
|
|
[dependencies]
|
|
actix-web = "4"
|
|
actix-ws = "0.2"
|
|
tokio = { version = "1", features = ["full"] }
|
|
sqlx = { version = "0.7", features = ["mysql", "runtime-tokio"] }
|
|
redis = { version = "0.23", features = ["tokio-comp"] }
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
tracing = "0.1"
|
|
tracing-subscriber = "0.3"
|
|
config = "0.13"
|
|
deadpool = "0.9"
|
|
```
|
|
|
|
#### 2.2.3 管理端技术栈 - Tauri + Vue.js
|
|
- **桌面框架**: Tauri 2.x (Rust后端 + WebView前端)
|
|
- **前端框架**: Vue.js 3 + TypeScript
|
|
- **UI组件库**: Element Plus
|
|
- **图表库**: ECharts 5
|
|
- **状态管理**: Pinia
|
|
- **路由**: Vue Router 4
|
|
- **HTTP客户端**: Axios / reqwest (Rust)
|
|
- **实时通信**: WebSocket (原生 / tokio-tungstenite)
|
|
- **构建工具**: Vite + Tauri CLI
|
|
- **IPC通信**: @tauri-apps/api
|
|
|
|
**Tauri优势:**
|
|
- ✅ 体积小: 最终应用仅15-20MB (vs Electron 150MB+)
|
|
- ✅ 内存低: 空窗口仅50MB (vs Electron 300MB+)
|
|
- ✅ 启动快: 0.3-0.6秒 (vs Electron 2秒+)
|
|
- ✅ 安全性: Rust后端,细粒度权限控制
|
|
- ✅ 原生API: 直接调用系统API,性能更好
|
|
|
|
**核心依赖:**
|
|
```toml
|
|
[build-dependencies]
|
|
tauri-build = { version = "2", features = [] }
|
|
|
|
[dependencies]
|
|
tauri = { version = "2", features = ["shell-open"] }
|
|
tauri-plugin-shell = "2"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
tokio = { version = "1", features = ["full"] }
|
|
reqwest = { version = "0.11", features = ["json"] }
|
|
```
|
|
|
|
```json
|
|
// package.json
|
|
{
|
|
"dependencies": {
|
|
"vue": "^3.3",
|
|
"vue-router": "^4.2",
|
|
"pinia": "^2.1",
|
|
"element-plus": "^2.4",
|
|
"echarts": "^5.4",
|
|
"axios": "^1.6",
|
|
"@tauri-apps/api": "^2.0"
|
|
},
|
|
"devDependencies": {
|
|
"@tauri-apps/cli": "^2.0",
|
|
"vite": "^5.0",
|
|
"typescript": "^5.3"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2.3 通信协议设计
|
|
|
|
#### 2.3.1 客户端与服务端通信
|
|
采用TCP长连接 + 自定义二进制协议:
|
|
|
|
**协议格式:**
|
|
```
|
|
┌──────────┬──────────┬──────────┬──────────────┐
|
|
│ 魔数(4B) │ 版本(1B) │ 类型(1B) │ 数据长度(4B) │
|
|
├──────────┴──────────┴──────────┴──────────────┤
|
|
│ 数据内容(变长) │
|
|
└────────────────────────────────────────────────┘
|
|
```
|
|
|
|
**消息类型:**
|
|
- 0x01: 心跳消息
|
|
- 0x02: 屏幕数据
|
|
- 0x03: 行为日志
|
|
- 0x04: 文件操作日志
|
|
- 0x05: 网络行为日志
|
|
- 0x06: 资产信息
|
|
- 0x07: 告警消息
|
|
- 0x10: 策略下发
|
|
- 0x11: 远程控制指令
|
|
|
|
#### 2.3.2 管理端与服务端通信
|
|
- HTTP/HTTPS: RESTful API
|
|
- WebSocket: 实时屏幕流、告警推送
|
|
|
|
## 三、核心功能模块设计
|
|
|
|
### 3.1 屏幕监控模块(核心功能)
|
|
|
|
#### 3.1.1 功能描述
|
|
- **实时屏幕查看**: 管理员可实时查看任意员工电脑屏幕
|
|
- **多屏监控墙**: 支持16/25/36屏同时监控,形成"屏幕墙"
|
|
- **屏幕快照**: 定时抓取屏幕截图并存储
|
|
- **屏幕录像**: 按需录制屏幕操作过程
|
|
- **远程控制**: 支持远程桌面控制,可进行远程操作
|
|
|
|
#### 3.1.2 技术实现(Rust)
|
|
|
|
**客户端实现(Rust):**
|
|
```rust
|
|
// src/screen_capture.rs
|
|
use anyhow::Result;
|
|
use image::{ImageBuffer, RgbImage};
|
|
use std::time::Duration;
|
|
use tokio::sync::mpsc::Sender;
|
|
use winapi::um::wingdi::*;
|
|
use winapi::um::winuser::*;
|
|
|
|
pub async fn start(tx: Sender<MonitorData>, config: Config) -> Result<()> {
|
|
let mut last_frame: Option<Vec<u8>> = None;
|
|
let mut frame_count = 0u32;
|
|
|
|
loop {
|
|
// 1. 捕获屏幕
|
|
let (width, height, buffer) = capture_screen()?;
|
|
|
|
// 2. 差分检测(降低带宽70%)
|
|
let frame_data = if let Some(ref last) = last_frame {
|
|
compute_diff(&last, &buffer, width, height)
|
|
} else {
|
|
buffer.clone()
|
|
};
|
|
|
|
// 3. 压缩为JPEG
|
|
let compressed = compress_image(&frame_data, width, height, config.quality)?;
|
|
|
|
// 4. 发送到服务端
|
|
tx.send(MonitorData::Screen {
|
|
frame_id: frame_count,
|
|
width,
|
|
height,
|
|
data: compressed,
|
|
}).await?;
|
|
|
|
last_frame = Some(buffer);
|
|
frame_count += 1;
|
|
|
|
// 5. 控制帧率
|
|
tokio::time::sleep(Duration::from_millis(1000 / config.fps)).await;
|
|
}
|
|
}
|
|
|
|
// 使用Windows GDI捕获屏幕
|
|
fn capture_screen() -> Result<(u32, u32, Vec<u8>)> {
|
|
unsafe {
|
|
let width = GetSystemMetrics(SM_CXSCREEN);
|
|
let height = GetSystemMetrics(SM_CYSCREEN);
|
|
|
|
let hdc_screen = GetDC(std::ptr::null_mut());
|
|
let hdc_mem = CreateCompatibleDC(hdc_screen);
|
|
let hbitmap = CreateCompatibleBitmap(hdc_screen, width, height);
|
|
|
|
SelectObject(hdc_mem, hbitmap as _);
|
|
BitBlt(hdc_mem, 0, 0, width, height, hdc_screen, 0, 0, SRCCOPY);
|
|
|
|
// 获取位图数据
|
|
let mut buffer = vec![0u8; (width * height * 3) as usize];
|
|
let mut bmi = BITMAPINFO {
|
|
bmiHeader: BITMAPINFOHEADER {
|
|
biSize: std::mem::size_of::<BITMAPINFOHEADER>() as u32,
|
|
biWidth: width,
|
|
biHeight: -height, // 自上而下
|
|
biPlanes: 1,
|
|
biBitCount: 24,
|
|
biCompression: BI_RGB,
|
|
..std::mem::zeroed()
|
|
},
|
|
..std::mem::zeroed()
|
|
};
|
|
|
|
GetDIBits(hdc_mem, hbitmap, 0, height as u32,
|
|
buffer.as_mut_ptr() as *mut _, &mut bmi, DIB_RGB_COLORS);
|
|
|
|
DeleteObject(hbitmap as _);
|
|
DeleteDC(hdc_mem);
|
|
ReleaseDC(std::ptr::null_mut(), hdc_screen);
|
|
|
|
Ok((width as u32, height as u32, buffer))
|
|
}
|
|
}
|
|
|
|
// 图像压缩
|
|
fn compress_image(data: &[u8], width: u32, height: u32, quality: u8) -> Result<Vec<u8>> {
|
|
let img: RgbImage = ImageBuffer::from_raw(width, height, data.to_vec())
|
|
.ok_or_else(|| anyhow::anyhow!("Failed to create image buffer"))?;
|
|
|
|
let mut compressed = Vec::new();
|
|
let mut encoder = jpeg_encoder::Encoder::new(&mut compressed, quality);
|
|
encoder.encode(&img, width as u16, height as u16, jpeg_encoder::ColorType::Rgb)?;
|
|
|
|
Ok(compressed)
|
|
}
|
|
|
|
// 差分检测
|
|
fn compute_diff(old: &[u8], new: &[u8], width: u32, height: u32) -> Vec<u8> {
|
|
let mut diff = Vec::with_capacity(new.len());
|
|
|
|
for (o, n) in old.iter().zip(new.iter()) {
|
|
// 简单的差分算法,实际可优化为块匹配
|
|
if (o as i16 - *n as i16).abs() > 10 {
|
|
diff.push(*n);
|
|
} else {
|
|
diff.push(0); // 未变化区域
|
|
}
|
|
}
|
|
|
|
diff
|
|
}
|
|
```
|
|
|
|
**服务端实现(Rust + Actix-web):**
|
|
```rust
|
|
// src/server/screen_stream.rs
|
|
use actix::prelude::*;
|
|
use actix_web_actors::ws;
|
|
use std::collections::HashMap;
|
|
|
|
pub struct ScreenStreamManager {
|
|
// 客户端ID -> 观看者列表
|
|
viewers: HashMap<String, Vec<Addr<ws::WebsocketContext>>>,
|
|
}
|
|
|
|
impl ScreenStreamManager {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
viewers: HashMap::new(),
|
|
}
|
|
}
|
|
|
|
// 处理屏幕数据
|
|
pub async fn handle_screen_data(&mut self, client_id: String, data: Vec<u8>) {
|
|
if let Some(viewers) = self.viewers.get(&client_id) {
|
|
// 转发给所有观看者
|
|
for viewer in viewers {
|
|
viewer.do_send(ws::Message::Binary(data.clone().into()));
|
|
}
|
|
}
|
|
}
|
|
|
|
// 添加观看者
|
|
pub fn add_viewer(&mut self, client_id: String, viewer: Addr<ws::WebsocketContext>) {
|
|
self.viewers
|
|
.entry(client_id)
|
|
.or_insert_with(Vec::new)
|
|
.push(viewer);
|
|
}
|
|
}
|
|
|
|
// WebSocket处理器
|
|
pub struct ScreenWebSocket {
|
|
manager: Addr<ScreenStreamManager>,
|
|
client_id: String,
|
|
}
|
|
|
|
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for ScreenWebSocket {
|
|
fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
|
|
match msg {
|
|
Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
|
|
Ok(ws::Message::Text(text)) => {
|
|
// 处理文本消息(如切换监控目标)
|
|
self.client_id = text.to_string();
|
|
self.manager.do_send(AddViewer {
|
|
client_id: self.client_id.clone(),
|
|
viewer: ctx.address(),
|
|
});
|
|
}
|
|
_ => (),
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**管理端实现(Tauri + Vue):**
|
|
```vue
|
|
<template>
|
|
<div class="screen-wall">
|
|
<div v-for="client in onlineClients" :key="client.id" class="screen-item">
|
|
<img :src="client.screenUrl" />
|
|
<div class="client-info">{{ client.name }}</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue';
|
|
import { invoke } from '@tauri-apps/api';
|
|
|
|
const onlineClients = ref<Client[]>([]);
|
|
|
|
onMounted(async () => {
|
|
// 通过Tauri调用Rust后端建立WebSocket连接
|
|
await invoke('connect_screen_stream', {
|
|
serverUrl: 'wss://server/screen-stream'
|
|
});
|
|
});
|
|
|
|
// Rust后端会通过事件推送屏幕数据
|
|
listen('screen-data', (event) => {
|
|
const { clientId, imageData } = event.payload;
|
|
updateClientScreen(clientId, imageData);
|
|
});
|
|
</script>
|
|
```
|
|
|
|
#### 3.1.3 性能优化
|
|
- **差分传输**: 只传输屏幕变化区域,降低带宽70%
|
|
- **动态帧率**: 根据网络状况自动调整帧率(1-10 FPS)
|
|
- **质量自适应**: 根据带宽自动调整图像质量
|
|
- **硬件加速**: 使用GPU加速屏幕捕获和编码
|
|
|
|
### 3.2 上网行为监控模块
|
|
|
|
#### 3.2.1 功能描述
|
|
- **网站访问监控**: 记录访问的网站URL、标题、时间、停留时长
|
|
- **应用程序监控**: 记录使用的应用程序、窗口标题、使用时长
|
|
- **即时通讯监控**: 监控QQ、微信、钉钉等聊天内容
|
|
- **邮件监控**: 监控发送的邮件内容、附件
|
|
- **搜索关键词**: 记录搜索引擎搜索的关键词
|
|
- **流量统计**: 统计每个应用的网络流量
|
|
|
|
#### 3.2.2 技术实现
|
|
|
|
**客户端实现:**
|
|
```cpp
|
|
// 1. 网络流量监控 - 使用WinPcap/Npcap抓包
|
|
pcap_t* fp = pcap_open_live(adapter, 65536, 1, 1000, errbuf);
|
|
while (true) {
|
|
struct pcap_pkthdr* header;
|
|
const u_char* pkt_data;
|
|
pcap_next_ex(fp, &header, &pkt_data);
|
|
|
|
// 解析IP头、TCP/UDP头
|
|
// 提取源IP、目的IP、端口、协议
|
|
// 记录到日志
|
|
}
|
|
|
|
// 2. 浏览器监控 - Hook网络API
|
|
HookFunction("wininet.dll", "InternetConnectA", MyInternetConnect);
|
|
HookFunction("wininet.dll", "HttpOpenRequestA", MyHttpOpenRequest);
|
|
|
|
// 3. 应用程序监控 - 轮询活动窗口
|
|
while (true) {
|
|
HWND hwnd = GetForegroundWindow();
|
|
GetWindowText(hwnd, title, 256);
|
|
GetWindowThreadProcessId(hwnd, &processId);
|
|
|
|
// 记录窗口标题、进程名、时间
|
|
LogActivity(processId, title);
|
|
Sleep(1000);
|
|
}
|
|
|
|
// 4. 即时通讯监控 - Hook剪贴板、键盘输入
|
|
SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);
|
|
SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, NULL, threadId);
|
|
```
|
|
|
|
**数据结构:**
|
|
```sql
|
|
-- 网站访问记录表
|
|
CREATE TABLE web_visit_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
url VARCHAR(500),
|
|
title VARCHAR(255),
|
|
visit_time TIMESTAMP,
|
|
stay_duration INT,
|
|
browser VARCHAR(50),
|
|
INDEX idx_device_time (device_id, visit_time)
|
|
);
|
|
|
|
-- 应用程序使用记录表
|
|
CREATE TABLE app_usage_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
process_name VARCHAR(100),
|
|
window_title VARCHAR(255),
|
|
start_time TIMESTAMP,
|
|
end_time TIMESTAMP,
|
|
duration INT,
|
|
INDEX idx_device_time (device_id, start_time)
|
|
);
|
|
|
|
-- 聊天记录表
|
|
CREATE TABLE chat_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
app_name VARCHAR(50),
|
|
chat_type VARCHAR(20),
|
|
content TEXT,
|
|
log_time TIMESTAMP,
|
|
INDEX idx_device_time (device_id, log_time)
|
|
);
|
|
```
|
|
|
|
### 3.3 文件操作监控模块
|
|
|
|
#### 3.3.1 功能描述
|
|
- **文件操作记录**: 记录文件的创建、修改、删除、重命名、复制
|
|
- **文件外发监控**: 监控通过QQ、邮件、网盘等方式外发文件
|
|
- **敏感文件识别**: 自动识别包含敏感关键词的文件
|
|
- **文件备份**: 重要文件自动备份到服务器
|
|
- **U盘文件监控**: 监控U盘文件的拷入拷出
|
|
|
|
#### 3.3.2 技术实现
|
|
|
|
**客户端实现:**
|
|
```cpp
|
|
// 1. 文件系统监控 - 使用ReadDirectoryChangesW
|
|
HANDLE hDir = CreateFile(path, FILE_LIST_DIRECTORY,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
|
|
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
|
|
|
BYTE buffer[4096];
|
|
DWORD bytesReturned;
|
|
while (true) {
|
|
ReadDirectoryChangesW(hDir, buffer, sizeof(buffer), TRUE,
|
|
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
|
|
FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE |
|
|
FILE_NOTIFY_CHANGE_LAST_WRITE,
|
|
&bytesReturned, NULL, NULL);
|
|
|
|
FILE_NOTIFY_INFORMATION* pNotify = (FILE_NOTIFY_INFORMATION*)buffer;
|
|
while (true) {
|
|
// 解析文件操作类型、文件名
|
|
LogFileOperation(pNotify->Action, pNotify->FileName);
|
|
|
|
if (pNotify->NextEntryOffset == 0) break;
|
|
pNotify = (FILE_NOTIFY_INFORMATION*)((BYTE*)pNotify + pNotify->NextEntryOffset);
|
|
}
|
|
}
|
|
|
|
// 2. 敏感文件检测
|
|
bool IsSensitiveFile(string filePath) {
|
|
// 读取文件内容
|
|
string content = ReadFileContent(filePath);
|
|
|
|
// 检查敏感关键词
|
|
for (auto keyword : sensitiveKeywords) {
|
|
if (content.find(keyword) != string::npos) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// 3. 文件外发拦截
|
|
HookFunction("kernel32.dll", "CopyFileA", MyCopyFile);
|
|
HookFunction("shell32.dll", "ShellExecuteA", MyShellExecute);
|
|
```
|
|
|
|
**数据结构:**
|
|
```sql
|
|
-- 文件操作记录表
|
|
CREATE TABLE file_operation_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
operation_type VARCHAR(20),
|
|
file_path VARCHAR(500),
|
|
file_name VARCHAR(255),
|
|
file_size BIGINT,
|
|
operation_time TIMESTAMP,
|
|
is_sensitive TINYINT,
|
|
INDEX idx_device_time (device_id, operation_time)
|
|
);
|
|
|
|
-- 文件外发记录表
|
|
CREATE TABLE file_send_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
file_path VARCHAR(500),
|
|
send_method VARCHAR(50),
|
|
send_target VARCHAR(255),
|
|
send_time TIMESTAMP,
|
|
is_blocked TINYINT,
|
|
INDEX idx_device_time (device_id, send_time)
|
|
);
|
|
```
|
|
|
|
### 3.4 外设管理模块
|
|
|
|
#### 3.4.1 功能描述
|
|
- **USB设备管控**: 禁止/允许USB设备使用,设置只读/只写权限
|
|
- **移动存储管理**: 监控U盘、移动硬盘的接入和文件操作
|
|
- **光驱管理**: 禁用光驱刻录功能
|
|
- **蓝牙管理**: 禁用蓝牙设备
|
|
- **打印机管理**: 监控打印操作,控制打印权限
|
|
|
|
#### 3.4.2 技术实现
|
|
|
|
**客户端实现:**
|
|
```cpp
|
|
// 1. USB设备监控 - 使用WMI查询
|
|
HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL,
|
|
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
|
|
pLoc->ConnectServer(L"ROOT\\CIMV2", NULL, NULL, 0, NULL, 0, 0, &pSvc);
|
|
|
|
// 查询USB设备
|
|
IEnumWbemClassObject* pEnumerator;
|
|
pSvc->ExecQuery(L"WQL", L"SELECT * FROM Win32_USBHub",
|
|
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
|
|
|
|
// 2. USB设备拦截 - 修改注册表
|
|
// 禁用USB存储设备
|
|
RegSetValueEx(HKEY_LOCAL_MACHINE,
|
|
L"SYSTEM\\CurrentControlSet\\Services\\USBSTOR",
|
|
L"Start", 0, REG_DWORD, (BYTE*)&value, sizeof(value));
|
|
|
|
// 3. 设备变化通知
|
|
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
|
|
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
|
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
|
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
|
|
|
|
HWND hWnd = CreateWindow(L"Static", NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
|
|
RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);
|
|
|
|
// 在窗口过程中处理WM_DEVICECHANGE消息
|
|
```
|
|
|
|
**数据结构:**
|
|
```sql
|
|
-- USB设备接入记录表
|
|
CREATE TABLE usb_device_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
usb_device_id VARCHAR(100),
|
|
usb_device_name VARCHAR(255),
|
|
vendor_id VARCHAR(50),
|
|
product_id VARCHAR(50),
|
|
action VARCHAR(20),
|
|
action_time TIMESTAMP,
|
|
INDEX idx_device_time (device_id, action_time)
|
|
);
|
|
|
|
-- 外设策略表
|
|
CREATE TABLE device_policy (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
policy_name VARCHAR(100),
|
|
device_type VARCHAR(50),
|
|
policy_type VARCHAR(20),
|
|
policy_value TEXT,
|
|
status TINYINT DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
```
|
|
|
|
### 3.5 资产管理模块
|
|
|
|
#### 3.5.1 功能描述
|
|
- **硬件资产**: CPU、内存、硬盘、网卡、显卡等硬件信息
|
|
- **软件资产**: 已安装软件列表、版本、安装时间
|
|
- **系统信息**: 操作系统版本、补丁列表、系统配置
|
|
- **资产变更**: 监控硬件更换、软件安装卸载
|
|
- **资产统计**: 生成资产清单和统计报表
|
|
|
|
#### 3.5.2 技术实现
|
|
|
|
**客户端实现:**
|
|
```cpp
|
|
// 1. 硬件信息采集
|
|
void CollectHardwareInfo() {
|
|
// CPU信息
|
|
SYSTEM_INFO sysInfo;
|
|
GetSystemInfo(&sysInfo);
|
|
|
|
// 内存信息
|
|
MEMORYSTATUSEX memInfo;
|
|
memInfo.dwLength = sizeof(memInfo);
|
|
GlobalMemoryStatusEx(&memInfo);
|
|
|
|
// 硬盘信息
|
|
GetDiskFreeSpaceEx(L"C:\\", &freeBytes, &totalBytes, &totalFreeBytes);
|
|
|
|
// 网卡信息
|
|
PIP_ADAPTER_INFO pAdapterInfo;
|
|
GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
|
|
|
|
// 发送到服务端
|
|
SendHardwareInfo(cpu, memory, disk, network);
|
|
}
|
|
|
|
// 2. 软件信息采集 - 读取注册表
|
|
void CollectSoftwareInfo() {
|
|
HKEY hKey;
|
|
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall",
|
|
0, KEY_READ, &hKey);
|
|
|
|
DWORD dwIndex = 0;
|
|
TCHAR szSubKey[MAX_PATH];
|
|
while (RegEnumKey(hKey, dwIndex, szSubKey, MAX_PATH) == ERROR_SUCCESS) {
|
|
// 读取软件名称、版本、安装时间
|
|
HKEY hSubKey;
|
|
RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey);
|
|
|
|
QueryValue(hSubKey, L"DisplayName", softwareName);
|
|
QueryValue(hSubKey, L"DisplayVersion", version);
|
|
QueryValue(hSubKey, L"InstallDate", installDate);
|
|
|
|
RegCloseKey(hSubKey);
|
|
dwIndex++;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
```
|
|
|
|
**数据结构:**
|
|
```sql
|
|
-- 硬件资产表
|
|
CREATE TABLE hardware_asset (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL UNIQUE,
|
|
cpu_model VARCHAR(100),
|
|
cpu_cores INT,
|
|
memory_size BIGINT,
|
|
disk_size BIGINT,
|
|
disk_model VARCHAR(100),
|
|
network_card VARCHAR(100),
|
|
mac_address VARCHAR(50),
|
|
graphics_card VARCHAR(100),
|
|
motherboard VARCHAR(100),
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- 软件资产表
|
|
CREATE TABLE software_asset (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
software_name VARCHAR(255),
|
|
software_version VARCHAR(50),
|
|
publisher VARCHAR(100),
|
|
install_date DATE,
|
|
install_location VARCHAR(255),
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
INDEX idx_device (device_id)
|
|
);
|
|
|
|
-- 资产变更记录表
|
|
CREATE TABLE asset_change_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100) NOT NULL,
|
|
change_type VARCHAR(50),
|
|
old_value TEXT,
|
|
new_value TEXT,
|
|
change_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX idx_device_time (device_id, change_time)
|
|
);
|
|
```
|
|
|
|
### 3.6 远程控制模块
|
|
|
|
#### 3.6.1 功能描述
|
|
- **远程桌面**: 远程查看和控制员工电脑桌面
|
|
- **远程命令**: 远程执行命令、启动程序
|
|
- **远程文件管理**: 远程浏览、上传、下载文件
|
|
- **远程开关机**: 远程关机、重启、注销
|
|
- **消息通知**: 向员工电脑发送通知消息
|
|
|
|
#### 3.6.2 技术实现
|
|
|
|
**客户端实现:**
|
|
```cpp
|
|
// 1. 远程桌面控制 - 接收鼠标键盘事件
|
|
void OnRemoteControlData(ControlData* data) {
|
|
switch (data->type) {
|
|
case MOUSE_MOVE:
|
|
SetCursorPos(data->x, data->y);
|
|
break;
|
|
case MOUSE_CLICK:
|
|
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
|
|
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
|
|
break;
|
|
case KEY_PRESS:
|
|
keybd_event(data->vkCode, 0, 0, 0);
|
|
keybd_event(data->vkCode, 0, KEYEVENTF_KEYUP, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 2. 远程命令执行
|
|
void ExecuteRemoteCommand(string command) {
|
|
STARTUPINFO si = {sizeof(si)};
|
|
PROCESS_INFORMATION pi;
|
|
CreateProcess(NULL, (LPSTR)command.c_str(), NULL, NULL,
|
|
FALSE, 0, NULL, NULL, &si, &pi);
|
|
}
|
|
|
|
// 3. 远程文件管理
|
|
void HandleFileOperation(FileOperation* op) {
|
|
switch (op->type) {
|
|
case LIST_FILES:
|
|
ListFiles(op->path);
|
|
break;
|
|
case UPLOAD_FILE:
|
|
ReceiveFile(op->remotePath);
|
|
break;
|
|
case DOWNLOAD_FILE:
|
|
SendFile(op->localPath);
|
|
break;
|
|
case DELETE_FILE:
|
|
DeleteFile(op->path);
|
|
break;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3.7 告警与通知模块
|
|
|
|
#### 3.7.1 功能描述
|
|
- **实时告警**: 检测到违规行为时立即告警
|
|
- **告警规则**: 可配置告警触发条件和通知方式
|
|
- **通知方式**: 支持弹窗、邮件、企业微信、钉钉等
|
|
- **告警处理**: 记录告警处理过程和结果
|
|
|
|
#### 3.7.2 告警规则示例
|
|
```sql
|
|
-- 告警规则表
|
|
CREATE TABLE alarm_rule (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
rule_name VARCHAR(100) NOT NULL,
|
|
rule_type VARCHAR(50),
|
|
condition_json TEXT,
|
|
notify_methods VARCHAR(255),
|
|
notify_receivers VARCHAR(500),
|
|
severity VARCHAR(20),
|
|
status TINYINT DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- 告警记录表
|
|
CREATE TABLE alarm_record (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
device_id VARCHAR(100),
|
|
rule_id BIGINT,
|
|
alarm_type VARCHAR(50),
|
|
alarm_level VARCHAR(20),
|
|
alarm_content VARCHAR(500),
|
|
alarm_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
status TINYINT DEFAULT 0,
|
|
handler VARCHAR(50),
|
|
handle_time TIMESTAMP,
|
|
handle_remark VARCHAR(255),
|
|
INDEX idx_device_time (device_id, alarm_time)
|
|
);
|
|
```
|
|
|
|
### 3.8 权限管理模块
|
|
|
|
#### 3.8.1 功能描述
|
|
- **用户管理**: 管理员账号的增删改查
|
|
- **角色管理**: 定义不同角色的权限
|
|
- **权限控制**: 控制用户可访问的功能和数据
|
|
- **操作审计**: 记录管理员的操作日志
|
|
|
|
#### 3.8.2 数据结构
|
|
```sql
|
|
-- 用户表
|
|
CREATE TABLE sys_user (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
username VARCHAR(50) NOT NULL UNIQUE,
|
|
password VARCHAR(255) NOT NULL,
|
|
real_name VARCHAR(50),
|
|
email VARCHAR(100),
|
|
phone VARCHAR(20),
|
|
role_id BIGINT,
|
|
status TINYINT DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- 角色表
|
|
CREATE TABLE sys_role (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
role_name VARCHAR(50) NOT NULL,
|
|
role_code VARCHAR(50) UNIQUE,
|
|
permissions TEXT,
|
|
status TINYINT DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
-- 操作日志表
|
|
CREATE TABLE operation_log (
|
|
id BIGINT PRIMARY KEY AUTO_INCREMENT,
|
|
user_id BIGINT,
|
|
username VARCHAR(50),
|
|
operation_type VARCHAR(50),
|
|
operation_module VARCHAR(50),
|
|
operation_desc VARCHAR(255),
|
|
ip_address VARCHAR(50),
|
|
operation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
INDEX idx_user_time (user_id, operation_time)
|
|
);
|
|
```
|
|
|
|
## 四、客户端详细设计(Rust实现)
|
|
|
|
### 4.1 客户端架构
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 客户端主程序(Rust) │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ 配置管理 │ 日志管理 │ 进程守护 │ 自动更新 │
|
|
│ (config crate) │ (tracing) │ (windows-service) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 功能模块层 │
|
|
├──────────┬──────────┬──────────┬──────────┬──────────┤
|
|
│ 屏幕捕获 │ 行为监控 │ 文件监控 │ 网络监控 │ 外设管理 │
|
|
│(winapi) │(retours) │(notify) │(pcap) │(wmi) │
|
|
└──────────┴──────────┴──────────┴──────────┴──────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 基础服务层 │
|
|
├──────────┬──────────┬──────────┬──────────┬──────────┤
|
|
│ 网络通信 │ 数据压缩 │ 加密传输 │ 本地存储 │ 序列化 │
|
|
│(tokio) │(image) │(rustls) │(sled) │(serde) │
|
|
└──────────┴──────────┴──────────┴──────────┴──────────┘
|
|
```
|
|
|
|
### 4.2 客户端核心流程(Rust)
|
|
|
|
```rust
|
|
// src/main.rs
|
|
use anyhow::Result;
|
|
use tokio::sync::mpsc;
|
|
use tracing::{info, error};
|
|
|
|
mod screen_capture;
|
|
mod behavior_monitor;
|
|
mod file_monitor;
|
|
mod network_monitor;
|
|
mod device_manager;
|
|
mod network;
|
|
mod config;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<()> {
|
|
// 1. 初始化日志
|
|
tracing_subscriber::fmt::init();
|
|
info!("客户端启动中...");
|
|
|
|
// 2. 加载配置
|
|
let config = config::load_config()?;
|
|
|
|
// 3. 注册为Windows服务(隐蔽运行)
|
|
#[cfg(target_os = "windows")]
|
|
{
|
|
windows_service::install_service("MonitorService")?;
|
|
}
|
|
|
|
// 4. 创建通信通道
|
|
let (tx, rx) = mpsc::channel(1000);
|
|
|
|
// 5. 启动各功能模块(异步任务)
|
|
let screen_handle = tokio::spawn(screen_capture::start(tx.clone(), config.clone()));
|
|
let behavior_handle = tokio::spawn(behavior_monitor::start(tx.clone(), config.clone()));
|
|
let file_handle = tokio::spawn(file_monitor::start(tx.clone(), config.clone()));
|
|
let network_handle = tokio::spawn(network_monitor::start(tx.clone(), config.clone()));
|
|
let device_handle = tokio::spawn(device_manager::start(tx.clone(), config.clone()));
|
|
|
|
// 6. 启动网络客户端
|
|
let mut client = network::Client::new(config.server_addr).await?;
|
|
|
|
// 7. 主循环
|
|
loop {
|
|
tokio::select! {
|
|
// 处理监控数据
|
|
Some(data) = rx.recv() => {
|
|
client.send_data(data).await?;
|
|
}
|
|
|
|
// 处理服务器指令
|
|
cmd = client.recv_command() => {
|
|
handle_command(cmd?).await?;
|
|
}
|
|
|
|
// 发送心跳
|
|
_ = tokio::time::sleep(Duration::from_secs(30)) => {
|
|
client.send_heartbeat().await?;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn handle_command(cmd: Command) -> Result<()> {
|
|
match cmd {
|
|
Command::UpdateConfig(new_config) => {
|
|
config::update_config(new_config)?;
|
|
}
|
|
Command::RemoteControl(action) => {
|
|
execute_remote_control(action).await?;
|
|
}
|
|
Command::StopMonitoring => {
|
|
info!("收到停止监控指令");
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
```
|
|
|
|
### 4.3 客户端隐蔽技术
|
|
|
|
```cpp
|
|
// 1. 进程隐藏
|
|
void HideProcess() {
|
|
// 方法1: 修改PEB
|
|
typedef NTSTATUS(NTAPI* pNtSetInformationProcess)(HANDLE, ULONG, PVOID, ULONG);
|
|
pNtSetInformationProcess NtSetInformationProcess =
|
|
(pNtSetInformationProcess)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtSetInformationProcess");
|
|
|
|
ULONG Hide = 1;
|
|
NtSetInformationProcess(GetCurrentProcess(), 0x1D, &Hide, sizeof(Hide));
|
|
|
|
// 方法2: 注册为系统服务
|
|
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
|
SC_HANDLE hService = CreateService(hSCManager, L"MonitorService", L"System Monitor Service",
|
|
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
|
L"C:\\Windows\\System32\\monitor.exe", NULL, NULL, NULL, NULL, NULL);
|
|
}
|
|
|
|
// 2. 文件隐藏
|
|
void HideFile(LPCWSTR filePath) {
|
|
SetFileAttributes(filePath, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
|
|
}
|
|
|
|
// 3. 注册表启动项隐藏
|
|
void InstallToRegistry() {
|
|
HKEY hKey;
|
|
RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
0, KEY_WRITE, &hKey);
|
|
RegSetValueEx(hKey, L"SystemMonitor", 0, REG_SZ, (BYTE*)L"C:\\Windows\\System32\\monitor.exe",
|
|
wcslen(L"C:\\Windows\\System32\\monitor.exe") * sizeof(WCHAR));
|
|
RegCloseKey(hKey);
|
|
}
|
|
|
|
// 4. 防止被杀毒软件查杀
|
|
void AvoidAntivirus() {
|
|
// 使用合法的数字签名
|
|
// 避免使用敏感API
|
|
// 使用代码混淆
|
|
// 定期更新特征码
|
|
}
|
|
```
|
|
|
|
## 五、服务端详细设计(Rust实现)
|
|
|
|
### 5.1 服务端架构
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 管理端(Tauri桌面应用) │
|
|
│ Tauri + Vue.js前端 │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓ HTTPS/WSS
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Rust服务端 │
|
|
│ Actix-web / Axum + Tokio │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ HTTP API: RESTful接口 │
|
|
│ WebSocket: 实时屏幕流转发 │
|
|
│ TCP Server: 客户端连接管理 │
|
|
│ Actor System: 业务逻辑处理 │
|
|
├─────────────────────────────────────────────────────────┤
|
|
│ 数据访问层: SQLx / Diesel │
|
|
│ 缓存层: Redis连接池 │
|
|
│ 定时任务: tokio-cron-scheduler │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 数据存储层 │
|
|
│ MySQL: 业务数据 │
|
|
│ Redis: 缓存、会话 │
|
|
│ 文件系统: 屏幕快照、录像 │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### 5.2 核心服务实现(Rust)
|
|
|
|
```rust
|
|
// src/main.rs
|
|
use actix_web::{middleware, web, App, HttpServer};
|
|
use actix::Actor;
|
|
use sqlx::mysql::MySqlPoolOptions;
|
|
|
|
mod api;
|
|
mod client_handler;
|
|
mod screen_stream;
|
|
mod models;
|
|
mod db;
|
|
|
|
#[actix_web::main]
|
|
async fn main() -> std::io::Result<()> {
|
|
// 1. 初始化日志
|
|
tracing_subscriber::fmt::init();
|
|
|
|
// 2. 连接数据库
|
|
let db_pool = MySqlPoolOptions::new()
|
|
.max_connections(10)
|
|
.connect("mysql://user:pass@localhost/monitor_db")
|
|
.await
|
|
.expect("Failed to connect to database");
|
|
|
|
// 3. 连接Redis
|
|
let redis_client = redis::Client::open("redis://127.0.0.1/")
|
|
.expect("Failed to connect to Redis");
|
|
|
|
// 4. 启动客户端连接管理器(Actor)
|
|
let client_manager = client_handler::ClientManager::new(db_pool.clone()).start();
|
|
|
|
// 5. 启动屏幕流管理器(Actor)
|
|
let screen_manager = screen_stream::ScreenStreamManager::new().start();
|
|
|
|
// 6. 启动TCP服务(接收客户端连接)
|
|
tokio::spawn(client_handler::start_tcp_server(
|
|
"0.0.0.0:9999".to_string(),
|
|
client_manager.clone(),
|
|
));
|
|
|
|
// 7. 启动HTTP服务
|
|
HttpServer::new(move || {
|
|
App::new()
|
|
.app_data(web::Data::new(db_pool.clone()))
|
|
.app_data(web::Data::new(redis_client.clone()))
|
|
.app_data(web::Data::new(client_manager.clone()))
|
|
.app_data(web::Data::new(screen_manager.clone()))
|
|
.wrap(middleware::Logger::default())
|
|
.service(api::routes())
|
|
})
|
|
.bind("0.0.0.0:8080")?
|
|
.run()
|
|
.await
|
|
}
|
|
|
|
// src/client_handler.rs
|
|
use actix::prelude::*;
|
|
use std::collections::HashMap;
|
|
use tokio::net::TcpListener;
|
|
|
|
pub struct ClientManager {
|
|
sessions: HashMap<String, Addr<ClientSession>>,
|
|
db_pool: sqlx::MySqlPool,
|
|
}
|
|
|
|
impl Actor for ClientManager {
|
|
type Context = Context<Self>;
|
|
}
|
|
|
|
// 处理客户端连接
|
|
#[derive(Message)]
|
|
#[rtype(result = "()")]
|
|
pub struct ClientConnected {
|
|
pub client_id: String,
|
|
pub addr: Addr<ClientSession>,
|
|
}
|
|
|
|
impl Handler<ClientConnected> for ClientManager {
|
|
type Result = ();
|
|
|
|
async fn handle(&mut self, msg: ClientConnected, _: &mut Self::Context) {
|
|
self.sessions.insert(msg.client_id.clone(), msg.addr);
|
|
|
|
// 更新数据库中的在线状态
|
|
sqlx::query!(
|
|
"UPDATE devices SET online_status = 1, last_heartbeat = NOW() WHERE device_id = ?",
|
|
msg.client_id
|
|
)
|
|
.execute(&self.db_pool)
|
|
.await
|
|
.ok();
|
|
}
|
|
}
|
|
|
|
// TCP服务器
|
|
pub async fn start_tcp_server(addr: String, manager: Addr<ClientManager>) -> std::io::Result<()> {
|
|
let listener = TcpListener::bind(&addr).await?;
|
|
info!("TCP server listening on {}", addr);
|
|
|
|
loop {
|
|
let (stream, addr) = listener.accept().await?;
|
|
let manager = manager.clone();
|
|
|
|
tokio::spawn(async move {
|
|
// 处理客户端连接
|
|
ClientSession::new(stream, manager).await;
|
|
});
|
|
}
|
|
}
|
|
|
|
// src/api.rs
|
|
use actix_web::{web, HttpResponse, Result};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct LoginRequest {
|
|
username: String,
|
|
password: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
pub struct LoginResponse {
|
|
token: String,
|
|
user: UserInfo,
|
|
}
|
|
|
|
// 用户登录
|
|
pub async fn login(
|
|
req: web::Json<LoginRequest>,
|
|
db: web::Data<sqlx::MysqlPool>,
|
|
) -> Result<HttpResponse> {
|
|
// 验证用户
|
|
let user = sqlx::query_as!(
|
|
User,
|
|
"SELECT * FROM sys_user WHERE username = ? AND password = ?",
|
|
req.username,
|
|
req.password
|
|
)
|
|
.fetch_optional(db.get_ref())
|
|
.await?;
|
|
|
|
match user {
|
|
Some(user) => {
|
|
// 生成JWT token
|
|
let token = generate_token(&user)?;
|
|
|
|
Ok(HttpResponse::Ok().json(LoginResponse {
|
|
token,
|
|
user: UserInfo::from(user),
|
|
}))
|
|
}
|
|
None => Ok(HttpResponse::Unauthorized().finish()),
|
|
}
|
|
}
|
|
|
|
// 获取设备列表
|
|
pub async fn get_devices(
|
|
db: web::Data<sqlx::MySqlPool>,
|
|
) -> Result<HttpResponse> {
|
|
let devices = sqlx::query_as!(
|
|
Device,
|
|
"SELECT * FROM devices ORDER BY created_at DESC"
|
|
)
|
|
.fetch_all(db.get_ref())
|
|
.await?;
|
|
|
|
Ok(HttpResponse::Ok().json(devices))
|
|
}
|
|
|
|
pub fn routes() -> actix_web::Scope {
|
|
web::scope("/api")
|
|
.route("/login", web::post().to(login))
|
|
.route("/devices", web::get().to(get_devices))
|
|
// ... 其他路由
|
|
}
|
|
```
|
|
```
|
|
|
|
## 六、管理端界面设计
|
|
|
|
### 6.1 主要页面
|
|
|
|
#### 6.1.1 实时监控页面
|
|
```vue
|
|
<template>
|
|
<div class="realtime-monitor">
|
|
<div class="toolbar">
|
|
<el-select v-model="layout" placeholder="布局">
|
|
<el-option label="4屏" :value="4" />
|
|
<el-option label="9屏" :value="9" />
|
|
<el-option label="16屏" :value="16" />
|
|
</el-select>
|
|
<el-button @click="refreshClients">刷新</el-button>
|
|
</div>
|
|
|
|
<div class="screen-wall" :style="gridStyle">
|
|
<div v-for="client in displayClients" :key="client.id" class="screen-item">
|
|
<img v-if="client.screenUrl" :src="client.screenUrl" />
|
|
<div v-else class="offline">离线</div>
|
|
<div class="client-info">
|
|
{{ client.name }} - {{ client.ip }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
|
|
const layout = ref(16);
|
|
const clients = ref([]);
|
|
const ws = ref(null);
|
|
|
|
const displayClients = computed(() => {
|
|
return clients.value.slice(0, layout.value);
|
|
});
|
|
|
|
const gridStyle = computed(() => {
|
|
const cols = Math.sqrt(layout.value);
|
|
return {
|
|
gridTemplateColumns: `repeat(${cols}, 1fr)`
|
|
};
|
|
});
|
|
|
|
onMounted(() => {
|
|
connectWebSocket();
|
|
loadClients();
|
|
});
|
|
|
|
function connectWebSocket() {
|
|
ws.value = new WebSocket('wss://server/realtime-monitor');
|
|
ws.value.onmessage = (event) => {
|
|
const data = JSON.parse(event.data);
|
|
updateClientScreen(data);
|
|
};
|
|
}
|
|
</script>
|
|
```
|
|
|
|
#### 6.1.2 行为审计页面
|
|
```vue
|
|
<template>
|
|
<div class="behavior-audit">
|
|
<el-form :inline="true">
|
|
<el-form-item label="设备">
|
|
<el-select v-model="deviceId" placeholder="选择设备">
|
|
<el-option v-for="device in devices" :key="device.id"
|
|
:label="device.name" :value="device.id" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="时间范围">
|
|
<el-date-picker v-model="timeRange" type="datetimerange" />
|
|
</el-form-item>
|
|
<el-form-item label="类型">
|
|
<el-select v-model="logType">
|
|
<el-option label="全部" value="" />
|
|
<el-option label="网站访问" value="web" />
|
|
<el-option label="应用程序" value="app" />
|
|
<el-option label="文件操作" value="file" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button type="primary" @click="search">查询</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<el-table :data="logs">
|
|
<el-table-column prop="time" label="时间" width="180" />
|
|
<el-table-column prop="type" label="类型" width="100" />
|
|
<el-table-column prop="content" label="内容" />
|
|
<el-table-column prop="detail" label="详情" />
|
|
</el-table>
|
|
|
|
<el-pagination
|
|
:total="total"
|
|
:page-size="pageSize"
|
|
@current-change="handlePageChange"
|
|
/>
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
## 七、开发计划
|
|
|
|
### 7.1 开发阶段划分(Rust + Tauri)
|
|
|
|
#### 第一阶段: 基础框架搭建(1.5周)
|
|
- 搭建Rust项目框架(Cargo workspace)
|
|
- 设计并创建数据库表
|
|
- 开发用户权限管理模块(Actix-web + SQLx)
|
|
- 搭建Tauri + Vue.js前端项目
|
|
- 实现基础API接口
|
|
- 配置CI/CD流水线
|
|
|
|
#### 第二阶段: 客户端开发(2.5周)
|
|
- 开发Rust客户端基础框架(Tokio异步运行时)
|
|
- 实现屏幕捕获功能(Windows API + image crate)
|
|
- 实现行为监控功能(retours Hook库)
|
|
- 实现文件监控功能(notify crate)
|
|
- 实现网络监控功能(pcap crate)
|
|
- 实现外设管理功能(WMI)
|
|
- 实现与服务端的TCP通信
|
|
|
|
#### 第三阶段: 服务端开发(2周)
|
|
- 实现客户端连接管理(TCP Server + Actor)
|
|
- 实现屏幕数据转发(WebSocket)
|
|
- 实现行为日志处理(SQLx + Redis)
|
|
- 实现告警规则引擎
|
|
- 实现远程控制功能
|
|
|
|
#### 第四阶段: 管理端开发(1.5周)
|
|
- 实现实时监控页面(Tauri + Vue)
|
|
- 实现行为审计页面
|
|
- 实现资产管理页面
|
|
- 实现远程控制页面
|
|
- 实现报表统计页面
|
|
|
|
#### 第五阶段: 测试与优化(1.5周)
|
|
- 功能测试
|
|
- 性能测试(压力测试)
|
|
- 兼容性测试(Windows各版本)
|
|
- 安全测试(渗透测试)
|
|
- Bug修复
|
|
|
|
#### 第六阶段: 部署与上线(1周)
|
|
- 编写部署文档
|
|
- 生产环境部署(Docker + Kubernetes)
|
|
- 用户培训
|
|
- 系统上线
|
|
|
|
**总计: 10周(2.5个月)**
|
|
|
|
### 7.2 开发团队配置(优化后)
|
|
- **项目经理**: 1人
|
|
- **Rust开发工程师**: 3人(负责客户端+服务端开发)
|
|
- 1人专攻客户端(Windows API + Hook)
|
|
- 1人专攻服务端(Actix-web + Actor)
|
|
- 1人负责公共模块和协议
|
|
- **前端开发工程师**: 1人(负责Tauri + Vue界面)
|
|
- **测试工程师**: 1人
|
|
- **运维工程师**: 1人
|
|
|
|
**团队优势:**
|
|
- ✅ 技术栈统一,沟通成本低
|
|
- ✅ 代码复用率高,开发效率高
|
|
- ✅ Rust安全性强,减少Bug数量
|
|
- ✅ 团队规模精简,管理成本低
|
|
|
|
### 7.3 技术风险与应对
|
|
|
|
#### 风险1: Rust学习曲线
|
|
- **应对**:
|
|
- 提供Rust培训课程
|
|
- 建立代码审查机制
|
|
- 使用成熟的crates生态
|
|
- 编写详细的开发文档
|
|
|
|
#### 风险2: 客户端被杀毒软件拦截
|
|
- **应对**:
|
|
- 申请代码数字签名
|
|
- 加入杀毒软件白名单
|
|
- 使用合法的Windows API
|
|
- 避免使用敏感特征
|
|
|
|
#### 风险3: 屏幕监控性能问题
|
|
- **应对**:
|
|
- 使用差分传输技术
|
|
- 动态调整帧率和质量
|
|
- 使用硬件加速(可选)
|
|
- 优化压缩算法
|
|
|
|
#### 风险4: 大规模客户端接入
|
|
- **应对**:
|
|
- Tokio异步运行时(支持百万级并发)
|
|
- Actor模型处理业务逻辑
|
|
- 数据库连接池优化
|
|
- Redis缓存热点数据
|
|
|
|
#### 风险5: 跨平台兼容性
|
|
- **应对**:
|
|
- 使用条件编译(#[cfg(target_os)])
|
|
- 抽象平台相关代码
|
|
- 多平台测试
|
|
- 使用跨平台crates
|
|
|
|
## 八、部署架构
|
|
|
|
### 8.1 生产环境部署
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 负载均衡 │
|
|
│ Nginx (HTTPS) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 应用服务器 │
|
|
│ Spring Boot应用 (多实例部署) │
|
|
│ - HTTP服务: 8080 │
|
|
│ - WebSocket服务: 8080 │
|
|
│ - TCP服务: 9999 │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 数据库服务器 │
|
|
│ MySQL 8.0 (主从复制) │
|
|
│ Redis 7.0 (哨兵模式) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
↓
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 文件存储 │
|
|
│ NFS / MinIO (屏幕快照、录像) │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### 8.2 客户端部署
|
|
- 制作客户端安装包(包含依赖库)
|
|
- 通过域控或手动方式分发安装
|
|
- 客户端自动注册到服务端
|
|
- 支持静默安装和自动更新
|
|
|
|
## 九、性能指标(Rust + Tauri优化版)
|
|
|
|
### 9.1 客户端性能(Rust)
|
|
- **CPU占用**: < 1% (vs C++ 5%)
|
|
- **内存占用**: ~30MB (vs C++ 100MB)
|
|
- **磁盘占用**: ~3MB可执行文件 (vs C++ 10MB)
|
|
- **网络带宽**: < 300KB/s (差分传输)
|
|
- **启动时间**: < 100ms
|
|
|
|
**性能优势:**
|
|
- ✅ Rust零成本抽象,性能接近C
|
|
- ✅ 无GC停顿,实时性更好
|
|
- ✅ 内存占用低,资源消耗小
|
|
- ✅ 编译优化,二进制体积小
|
|
|
|
### 9.2 服务端性能(Rust)
|
|
- **并发连接**: 支持10,000+客户端同时在线
|
|
- **API响应时间**: < 50ms (vs Java 200ms)
|
|
- **屏幕流转发延迟**: < 200ms (vs Java 500ms)
|
|
- **数据库查询**: < 50ms
|
|
- **内存占用**: ~100MB (vs Java 500MB)
|
|
- **吞吐量**: 100k+ QPS (Actix-web)
|
|
|
|
**性能优势:**
|
|
- ✅ Tokio异步运行时,高并发低延迟
|
|
- ✅ Actor模型,无锁并发
|
|
- ✅ 零拷贝技术,减少内存分配
|
|
- ✅ 编译期优化,运行效率高
|
|
|
|
### 9.3 管理端性能(Tauri)
|
|
- **应用体积**: ~15MB (vs Electron 150MB)
|
|
- **内存占用**: ~50MB (vs Electron 300MB)
|
|
- **启动时间**: 0.3-0.6秒 (vs Electron 2秒+)
|
|
- **CPU占用**: < 1% (空闲状态)
|
|
|
|
**性能优势:**
|
|
- ✅ 使用系统WebView,无需打包浏览器
|
|
- ✅ Rust后端,原生性能
|
|
- ✅ 体积小,下载快
|
|
- ✅ 启动快,用户体验好
|
|
|
|
### 9.4 系统可用性
|
|
- **系统可用性**: > 99.9% (Rust内存安全)
|
|
- **数据保留时长**: 90天
|
|
- **故障恢复时间**: < 10分钟
|
|
- **平均无故障时间(MTBF)**: > 10,000小时
|
|
|
|
### 9.5 性能对比总结
|
|
|
|
| 指标 | C++ + Java方案 | Rust + Tauri方案 | 提升 |
|
|
|------|---------------|-----------------|------|
|
|
| 客户端CPU | 5% | 1% | ⬇️ 80% |
|
|
| 客户端内存 | 100MB | 30MB | ⬇️ 70% |
|
|
| 服务端内存 | 500MB | 100MB | ⬇️ 80% |
|
|
| API响应 | 200ms | 50ms | ⚡ 4倍 |
|
|
| 管理端体积 | 150MB | 15MB | ⬇️ 90% |
|
|
| 启动时间 | 2秒 | 0.5秒 | ⚡ 4倍 |
|
|
| 并发连接 | 1,000 | 10,000 | ⬆️ 10倍 |
|
|
|
|
## 十、安全设计
|
|
|
|
### 10.1 客户端安全
|
|
- 代码混淆和加密
|
|
- 反调试和反逆向
|
|
- 数字签名验证
|
|
- 定期自检和更新
|
|
|
|
### 10.2 通信安全
|
|
- TLS 1.3加密传输
|
|
- 客户端证书认证
|
|
- 数据完整性校验
|
|
- 防重放攻击
|
|
|
|
### 10.3 数据安全
|
|
- 敏感数据加密存储
|
|
- 数据库访问控制
|
|
- 定期数据备份
|
|
- 数据脱敏展示
|
|
|
|
### 10.4 访问控制
|
|
- 基于角色的权限控制
|
|
- 操作审计日志
|
|
- 登录失败锁定
|
|
- 会话超时控制
|
|
|
|
## 十一、项目交付物
|
|
|
|
### 11.1 软件交付物
|
|
- 客户端安装包(Windows)
|
|
- 服务端部署包
|
|
- 数据库初始化脚本
|
|
- 配置文件模板
|
|
|
|
### 11.2 文档交付物
|
|
- 系统架构设计文档
|
|
- 数据库设计文档
|
|
- API接口文档
|
|
- 客户端开发文档
|
|
- 部署运维手册
|
|
- 用户操作手册
|
|
|
|
### 11.3 其他交付物
|
|
- 源代码(Git仓库)
|
|
- 测试报告
|
|
- 性能测试报告
|
|
- 安全测试报告
|
|
|
|
## 十二、总结
|
|
|
|
本系统采用C/S架构,专注于企业内部Windows电脑终端的实时监控和管理。核心功能包括:
|
|
1. **实时屏幕监控**: 支持多屏同时监控,延迟<1秒
|
|
2. **上网行为监控**: 全面的网络行为审计
|
|
3. **文件操作监控**: 防止敏感数据泄露
|
|
4. **外设管理**: 管控USB等外设使用
|
|
5. **资产管理**: 自动采集软硬件资产
|
|
6. **远程控制**: 支持远程桌面和命令执行
|
|
|
|
系统设计注重实用性、稳定性和隐蔽性,能够满足企业对终端安全管理的实际需求。通过分阶段开发,确保项目按时高质量交付。
|