Add files via upload
This commit is contained in:
@@ -0,0 +1,638 @@
|
||||
# NetBrain MCP 核心模块设计
|
||||
|
||||
本文档详细描述NetBrain MCP系统的核心模块设计,包括模块功能、接口以及之间的交互关系。
|
||||
|
||||
## 1. MCP服务器模块
|
||||
|
||||
### 1.1 模块概述
|
||||
|
||||
MCP服务器模块是整个系统的入口点,负责处理来自大型语言模型的请求,并将其路由到相应的工具或资源处理器。该模块基于FastMCP框架实现,封装了MCP协议的实现细节,提供了统一的API接口。
|
||||
|
||||
**实现文件**: `server.py`
|
||||
|
||||
### 1.2 核心类与接口
|
||||
|
||||
#### 1.2.1 FastMCP服务器
|
||||
|
||||
```python
|
||||
# 创建MCP服务器实例
|
||||
mcp = FastMCP("NetBrain MCP")
|
||||
|
||||
# 工具注册装饰器
|
||||
@mcp.tool()
|
||||
async def tool_function(param1: str, param2: int) -> Dict[str, Any]:
|
||||
"""工具功能实现"""
|
||||
pass
|
||||
|
||||
# 资源注册装饰器
|
||||
@mcp.resource("{uri}")
|
||||
async def mcp_resource_handler(uri: str) -> Any:
|
||||
"""MCP资源处理器,处理所有资源请求"""
|
||||
return await resource_manager.get_resource(uri)
|
||||
|
||||
# 提示模板注册装饰器
|
||||
@mcp.prompt("{name}")
|
||||
async def mcp_prompt_handler(name: str) -> str:
|
||||
"""MCP提示模板处理器"""
|
||||
return await template_manager.render_template(name)
|
||||
```
|
||||
|
||||
### 1.3 功能特性
|
||||
|
||||
- **工具注册与执行**:目前已实现32个MCP工具,涵盖设备管理、连接管理、拓扑发现等功能
|
||||
- **资源注册与提供**:实现13个MCP资源,包括设备、配置、拓扑等资源类型
|
||||
- **提示模板管理**:集成模板系统,支持动态模板渲染
|
||||
- **会话管理**:维护客户端会话状态和连接信息
|
||||
- **错误处理**:统一的错误处理机制和日志记录
|
||||
|
||||
### 1.4 与其他模块的交互
|
||||
|
||||
- 与工具管理模块交互,通过装饰器方式注册工具
|
||||
- 与资源模块交互,通过resource_manager获取和管理资源
|
||||
- 与模板系统交互,通过template_manager渲染提示模板
|
||||
- 与设备管理和连接模块交互,提供网络设备操作功能
|
||||
|
||||
## 2. 工具管理模块
|
||||
|
||||
### 2.1 模块概述
|
||||
|
||||
工具管理模块负责工具的注册、分类和执行管理,虽然MCP工具直接通过FastMCP注册,但该模块提供了工具的分类和管理功能。
|
||||
|
||||
**实现文件**: `tool_manager.py`
|
||||
|
||||
### 2.2 核心类与接口
|
||||
|
||||
#### 2.2.1 ToolManager类
|
||||
|
||||
```python
|
||||
class ToolManager:
|
||||
"""工具管理器,负责工具的注册和调用"""
|
||||
|
||||
def __init__(self):
|
||||
self.tools: Dict[str, ToolInfo] = {}
|
||||
self.categories: Dict[ToolCategory, List[str]] = {cat: [] for cat in ToolCategory}
|
||||
|
||||
def register_tool(self,
|
||||
name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
category: ToolCategory = ToolCategory.GENERAL) -> Callable:
|
||||
"""工具注册装饰器"""
|
||||
|
||||
def list_tools(self, category: Optional[ToolCategory] = None) -> List[Dict[str, Any]]:
|
||||
"""列出已注册的工具"""
|
||||
|
||||
def get_tool(self, name: str) -> Optional[ToolInfo]:
|
||||
"""获取工具信息"""
|
||||
|
||||
def execute_tool(self, name: str, *args, **kwargs) -> Any:
|
||||
"""执行工具"""
|
||||
```
|
||||
|
||||
#### 2.2.2 ToolCategory枚举
|
||||
|
||||
```python
|
||||
class ToolCategory(Enum):
|
||||
"""工具分类枚举"""
|
||||
GENERAL = "general" # 通用工具
|
||||
NETWORK_DEVICE = "network_device" # 网络设备相关工具
|
||||
CONFIGURATION = "configuration" # 配置管理工具
|
||||
TOPOLOGY = "topology" # 拓扑相关工具
|
||||
DIAGNOSTIC = "diagnostic" # 诊断工具
|
||||
SECURITY = "security" # 安全相关工具
|
||||
```
|
||||
|
||||
#### 2.2.3 ToolInfo数据类
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class ToolInfo:
|
||||
"""工具信息数据类"""
|
||||
name: str # 工具名称
|
||||
func: Callable # 工具函数
|
||||
description: str # 工具描述
|
||||
category: ToolCategory # 工具分类
|
||||
parameters: Dict[str, Dict[str, Any]] # 参数信息
|
||||
return_type: str # 返回类型
|
||||
```
|
||||
|
||||
### 2.3 实际工具实现
|
||||
|
||||
系统中实际实现的32个MCP工具分类如下:
|
||||
|
||||
#### 设备管理工具 (6个)
|
||||
- `list_devices` - 列出网络设备
|
||||
- `add_device` - 添加新的网络设备
|
||||
- `get_device` - 获取设备详细信息
|
||||
- `update_device` - 更新设备信息
|
||||
- `delete_device` - 删除设备
|
||||
|
||||
#### 凭据管理工具 (2个)
|
||||
- `add_credential` - 添加设备凭据
|
||||
- `list_credentials` - 列出所有设备凭据
|
||||
|
||||
#### 设备连接工具 (4个)
|
||||
- `connect_device` - 连接到网络设备
|
||||
- `disconnect_device` - 断开与网络设备的连接
|
||||
- `send_command` - 发送单个命令
|
||||
- `send_commands` - 发送多个命令
|
||||
- `get_active_connections` - 获取活动连接
|
||||
|
||||
#### 拓扑发现工具 (6个)
|
||||
- `discover_topology` - 发现网络拓扑
|
||||
- `get_topology` - 获取网络拓扑
|
||||
- `clear_topology` - 清除拓扑缓存
|
||||
- `get_device_neighbors` - 获取设备邻居
|
||||
- `discover_device_neighbors` - 发现设备邻居
|
||||
- `get_topology_statistics` - 获取拓扑统计
|
||||
|
||||
#### 网络扫描工具 (5个)
|
||||
- `scan_network_range` - 扫描网络范围
|
||||
- `get_scan_results` - 获取扫描结果
|
||||
- `get_scan_statistics` - 获取扫描统计
|
||||
- `discover_devices_from_scan_results` - 从扫描结果发现设备
|
||||
- `clear_scan_results` - 清除扫描结果
|
||||
- `scan_single_host` - 扫描单个主机
|
||||
|
||||
#### 资源管理工具 (3个)
|
||||
- `list_resources` - 列出可用资源
|
||||
- `get_resource` - 获取资源内容
|
||||
- `clear_resource_cache` - 清除资源缓存
|
||||
|
||||
#### 模板管理工具 (2个)
|
||||
- `list_templates` - 列出可用模板
|
||||
- `render_template` - 渲染模板
|
||||
|
||||
#### 测试工具 (4个)
|
||||
- `test_scrapli_connection` - 测试Scrapli连接
|
||||
- `test_telnet_connection` - 测试Telnet连接
|
||||
- `send_telnet_command` - 发送Telnet命令
|
||||
|
||||
## 3. 资源模块
|
||||
|
||||
### 3.1 模块概述
|
||||
|
||||
资源模块负责管理和提供各种网络资源,资源是客户端可以访问的数据对象,通过URI标识。系统实现了13个MCP资源。
|
||||
|
||||
**实现文件**: `mcp_resources.py`
|
||||
|
||||
### 3.2 核心类与接口
|
||||
|
||||
#### 3.2.1 ResourceManager类
|
||||
|
||||
```python
|
||||
class ResourceManager:
|
||||
"""MCP资源管理器,负责资源注册和提供"""
|
||||
|
||||
def __init__(self):
|
||||
self.resources = {}
|
||||
self.resource_patterns = {}
|
||||
self.resource_cache = {}
|
||||
self.cache_expiration = {}
|
||||
self.default_cache_ttl = 300 # 默认缓存5分钟
|
||||
self.cache_dir = os.path.join(os.getcwd(), "resource_cache")
|
||||
|
||||
def register_resource(self, uri_pattern: str, resource_type: str):
|
||||
"""注册资源装饰器"""
|
||||
|
||||
async def get_resource(self, uri: str, use_cache: bool = True, cache_ttl: Optional[int] = None) -> Dict[str, Any]:
|
||||
"""获取资源"""
|
||||
|
||||
def clear_cache(self, uri: Optional[str] = None) -> bool:
|
||||
"""清除资源缓存"""
|
||||
|
||||
def list_available_resources(self) -> List[Dict[str, Any]]:
|
||||
"""列出可用的资源"""
|
||||
```
|
||||
|
||||
#### 3.2.2 ResourceType类
|
||||
|
||||
```python
|
||||
class ResourceType:
|
||||
"""资源类型定义"""
|
||||
DEVICE = "device" # 设备资源
|
||||
CREDENTIAL = "credential" # 凭据资源
|
||||
TOPOLOGY = "topology" # 拓扑资源
|
||||
SYSTEM = "system" # 系统资源
|
||||
CONFIG = "config" # 配置资源
|
||||
LOG = "log" # 日志资源
|
||||
REPORT = "report" # 报告资源
|
||||
SCAN = "scan" # 扫描资源
|
||||
```
|
||||
|
||||
### 3.3 实际资源实现
|
||||
|
||||
系统中实际实现的13个MCP资源:
|
||||
|
||||
1. `greeting/{name}` - 问候信息(示例资源)
|
||||
2. `device/{device_id}` - 设备基本信息
|
||||
3. `device/{device_id}/config` - 设备配置信息
|
||||
4. `device/{device_id}/interfaces` - 设备接口信息
|
||||
5. `device/{device_id}/routes` - 设备路由信息
|
||||
6. `credentials` - 凭据列表
|
||||
7. `system/status` - 系统状态
|
||||
8. `topology` - 网络拓扑
|
||||
9. `topology/statistics` - 拓扑统计
|
||||
10. `device/{device_id}/neighbors` - 设备邻居
|
||||
11. `scan/results` - 扫描结果
|
||||
12. `scan/statistics` - 扫描统计
|
||||
13. `scan/result/{ip_address}` - 单个IP扫描结果
|
||||
|
||||
## 4. 设备管理模块
|
||||
|
||||
### 4.1 模块概述
|
||||
|
||||
设备管理模块负责网络设备的生命周期管理,包括设备的添加、查询、更新和删除,以及设备凭据的管理。
|
||||
|
||||
**实现文件**: `network_devices.py`
|
||||
|
||||
### 4.2 核心类与接口
|
||||
|
||||
#### 4.2.1 DeviceManager类
|
||||
|
||||
```python
|
||||
class DeviceManager:
|
||||
"""设备管理器,负责设备的创建、查询和管理"""
|
||||
|
||||
def __init__(self):
|
||||
self.devices: Dict[str, NetworkDevice] = {}
|
||||
self.credentials: Dict[str, DeviceCredential] = {}
|
||||
self.data_dir = "data"
|
||||
self.devices_file = os.path.join(self.data_dir, "devices.json")
|
||||
self.credentials_file = os.path.join(self.data_dir, "credentials.json")
|
||||
|
||||
def add_device(self, device: NetworkDevice) -> str:
|
||||
"""添加设备"""
|
||||
|
||||
def get_device(self, device_id: str) -> Optional[NetworkDevice]:
|
||||
"""获取设备"""
|
||||
|
||||
def update_device(self, device_id: str, **kwargs) -> Optional[NetworkDevice]:
|
||||
"""更新设备信息"""
|
||||
|
||||
def delete_device(self, device_id: str) -> bool:
|
||||
"""删除设备"""
|
||||
|
||||
def list_devices(self,
|
||||
vendor: Optional[DeviceVendor] = None,
|
||||
device_type: Optional[DeviceType] = None,
|
||||
status: Optional[DeviceStatus] = None,
|
||||
tag: Optional[str] = None) -> List[NetworkDevice]:
|
||||
"""列出设备,支持过滤"""
|
||||
|
||||
def add_credential(self, credential: DeviceCredential) -> str:
|
||||
"""添加凭据"""
|
||||
|
||||
def get_credential(self, credential_id: str) -> Optional[DeviceCredential]:
|
||||
"""获取凭据"""
|
||||
|
||||
def delete_credential(self, credential_id: str) -> bool:
|
||||
"""删除凭据"""
|
||||
|
||||
def list_credentials(self) -> List[DeviceCredential]:
|
||||
"""列出所有凭据"""
|
||||
```
|
||||
|
||||
#### 4.2.2 网络设备相关枚举
|
||||
|
||||
```python
|
||||
class DeviceType(Enum):
|
||||
"""网络设备类型枚举"""
|
||||
ROUTER = "router"
|
||||
SWITCH = "switch"
|
||||
FIREWALL = "firewall"
|
||||
LOAD_BALANCER = "load_balancer"
|
||||
WIRELESS_CONTROLLER = "wireless_controller"
|
||||
ACCESS_POINT = "access_point"
|
||||
OTHER = "other"
|
||||
|
||||
class DeviceVendor(Enum):
|
||||
"""网络设备厂商枚举"""
|
||||
CISCO = "cisco"
|
||||
HUAWEI = "huawei"
|
||||
H3C = "h3c"
|
||||
JUNIPER = "juniper"
|
||||
ARISTA = "arista"
|
||||
FORTINET = "fortinet"
|
||||
CHECKPOINT = "checkpoint"
|
||||
OTHER = "other"
|
||||
|
||||
class DeviceStatus(Enum):
|
||||
"""设备状态枚举"""
|
||||
ONLINE = "online"
|
||||
OFFLINE = "offline"
|
||||
UNREACHABLE = "unreachable"
|
||||
MAINTENANCE = "maintenance"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
class ConnectionProtocol(Enum):
|
||||
"""连接协议枚举"""
|
||||
SSH = "ssh"
|
||||
TELNET = "telnet"
|
||||
SNMP = "snmp"
|
||||
HTTP = "http"
|
||||
HTTPS = "https"
|
||||
NETCONF = "netconf"
|
||||
```
|
||||
|
||||
#### 4.2.3 设备数据模型
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class NetworkDevice:
|
||||
"""网络设备模型"""
|
||||
id: str = field(default_factory=lambda: str(uuid.uuid4()))
|
||||
name: str = ""
|
||||
ip_address: str = ""
|
||||
device_type: DeviceType = DeviceType.OTHER
|
||||
vendor: DeviceVendor = DeviceVendor.OTHER
|
||||
platform: str = "" # Scrapli平台类型
|
||||
model: str = ""
|
||||
os_version: str = ""
|
||||
status: DeviceStatus = DeviceStatus.UNKNOWN
|
||||
location: str = ""
|
||||
credential_id: Optional[str] = None
|
||||
description: str = ""
|
||||
tags: List[str] = field(default_factory=list)
|
||||
last_seen: Optional[datetime] = None
|
||||
created_at: datetime = field(default_factory=datetime.now)
|
||||
updated_at: datetime = field(default_factory=datetime.now)
|
||||
custom_attributes: Dict[str, Any] = field(default_factory=dict)
|
||||
```
|
||||
|
||||
#### 4.2.4 凭据数据模型
|
||||
|
||||
```python
|
||||
class DeviceCredential:
|
||||
"""设备认证凭据"""
|
||||
def __init__(self,
|
||||
id: str = None,
|
||||
name: str = "",
|
||||
username: str = "",
|
||||
password: str = "",
|
||||
protocol: ConnectionProtocol = ConnectionProtocol.SSH,
|
||||
port: int = None,
|
||||
enable_password: str = None,
|
||||
ssh_key_file: str = None):
|
||||
# 实现细节...
|
||||
```
|
||||
|
||||
## 5. 设备连接模块
|
||||
|
||||
### 5.1 模块概述
|
||||
|
||||
设备连接模块负责与网络设备建立连接并执行命令。该模块基于Scrapli库实现,支持SSH、Telnet等多种连接协议,并提供统一的命令执行接口。
|
||||
|
||||
**实现文件**: `device_connector.py`
|
||||
|
||||
### 5.2 核心类与接口
|
||||
|
||||
#### 5.2.1 ConnectionManager类
|
||||
|
||||
```python
|
||||
class ConnectionManager:
|
||||
"""连接管理器,负责管理所有设备连接"""
|
||||
|
||||
def __init__(self):
|
||||
self.active_connections: Dict[str, DeviceConnector] = {}
|
||||
|
||||
async def connect_device(self,
|
||||
device: NetworkDevice,
|
||||
credential: DeviceCredential) -> Tuple[bool, Optional[str]]:
|
||||
"""连接设备"""
|
||||
|
||||
async def disconnect_device(self, device_id: str, credential_id: str) -> Tuple[bool, Optional[str]]:
|
||||
"""断开设备连接"""
|
||||
|
||||
async def send_command(self,
|
||||
device_id: str,
|
||||
credential_id: str,
|
||||
command: str,
|
||||
timeout: int = 30) -> Tuple[Optional[CommandResult], Optional[str]]:
|
||||
"""发送命令到设备"""
|
||||
|
||||
async def send_commands(self,
|
||||
device_id: str,
|
||||
credential_id: str,
|
||||
commands: List[str],
|
||||
timeout: int = 30) -> Tuple[Optional[List[CommandResult]], Optional[str]]:
|
||||
"""发送多个命令到设备"""
|
||||
|
||||
def get_active_connections(self) -> List[Dict[str, Any]]:
|
||||
"""获取活动连接列表"""
|
||||
```
|
||||
|
||||
#### 5.2.2 ConnectorFactory类
|
||||
|
||||
```python
|
||||
class ConnectorFactory:
|
||||
"""连接器工厂,根据设备和凭据创建合适的连接器"""
|
||||
|
||||
@staticmethod
|
||||
def create_connector(device: NetworkDevice, credential: DeviceCredential) -> DeviceConnector:
|
||||
"""创建设备连接器,目前主要使用ScrapliConnector"""
|
||||
return ScrapliConnector(device, credential)
|
||||
```
|
||||
|
||||
#### 5.2.3 DeviceConnector抽象基类
|
||||
|
||||
```python
|
||||
class DeviceConnector(ABC):
|
||||
"""设备连接器抽象基类"""
|
||||
|
||||
def __init__(self, device: NetworkDevice, credential: DeviceCredential):
|
||||
self.device = device
|
||||
self.credential = credential
|
||||
self.connection = None
|
||||
self.connected = False
|
||||
self.last_activity = None
|
||||
|
||||
@abstractmethod
|
||||
async def connect(self) -> bool:
|
||||
"""连接到设备"""
|
||||
|
||||
@abstractmethod
|
||||
async def disconnect(self) -> bool:
|
||||
"""断开与设备的连接"""
|
||||
|
||||
@abstractmethod
|
||||
async def send_command(self, command: str, timeout: int = 30) -> CommandResult:
|
||||
"""发送命令到设备"""
|
||||
|
||||
@abstractmethod
|
||||
async def send_commands(self, commands: List[str], timeout: int = 30) -> List[CommandResult]:
|
||||
"""发送多个命令到设备"""
|
||||
```
|
||||
|
||||
#### 5.2.4 ScrapliConnector实现
|
||||
|
||||
```python
|
||||
class ScrapliConnector(DeviceConnector):
|
||||
"""Scrapli连接器实现,支持混合异步/同步模式"""
|
||||
|
||||
async def connect(self) -> bool:
|
||||
"""通过Scrapli连接到设备,支持多种平台"""
|
||||
# 根据设备平台选择合适的驱动
|
||||
# 支持异步和同步两种模式
|
||||
# 实现自动重连机制
|
||||
|
||||
async def send_command(self, command: str, timeout: int = 30) -> CommandResult:
|
||||
"""发送命令,支持异步/同步混合模式"""
|
||||
# 根据连接对象类型选择调用方式
|
||||
if asyncio.iscoroutinefunction(self.connection.send_command):
|
||||
# 异步方法直接调用
|
||||
response = await self.connection.send_command(command=command, timeout_ops=timeout)
|
||||
else:
|
||||
# 同步方法需要在线程中运行
|
||||
response = await asyncio.to_thread(self.connection.send_command, command=command, timeout_ops=timeout)
|
||||
```
|
||||
|
||||
#### 5.2.5 CommandResult类
|
||||
|
||||
```python
|
||||
class CommandResult:
|
||||
"""命令执行结果类"""
|
||||
|
||||
def __init__(self,
|
||||
command: str,
|
||||
output: str,
|
||||
success: bool = True,
|
||||
error_message: Optional[str] = None):
|
||||
self.command = command
|
||||
self.output = output
|
||||
self.success = success
|
||||
self.error_message = error_message
|
||||
self.execution_time = datetime.now()
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""转换为字典表示"""
|
||||
```
|
||||
|
||||
## 6. 模板系统
|
||||
|
||||
### 6.1 模块概述
|
||||
|
||||
模板系统负责管理和渲染各种提示和命令模板,提高系统的灵活性和扩展性。系统实现了13个提示模板。
|
||||
|
||||
**实现文件**: `template_system.py`, `device_prompts.py`
|
||||
|
||||
### 6.2 核心类与接口
|
||||
|
||||
#### 6.2.1 TemplateManager类
|
||||
|
||||
```python
|
||||
class TemplateManager:
|
||||
"""高级提示模板管理器"""
|
||||
|
||||
def __init__(self):
|
||||
self.templates = {}
|
||||
self.templates_dir = os.path.join(os.getcwd(), "templates")
|
||||
|
||||
def register_template(self, name: str = None, description: str = None):
|
||||
"""注册模板装饰器"""
|
||||
|
||||
def get_template(self, name: str) -> Optional[PromptTemplate]:
|
||||
"""获取模板"""
|
||||
|
||||
def render_template(self, name: str, arguments: Dict[str, Any] = None) -> Optional[Union[str, List[Message]]]:
|
||||
"""渲染模板"""
|
||||
|
||||
def list_templates(self) -> List[Dict[str, Any]]:
|
||||
"""列出所有可用模板"""
|
||||
```
|
||||
|
||||
#### 6.2.2 消息模型
|
||||
|
||||
```python
|
||||
@dataclass
|
||||
class Message:
|
||||
"""基础消息类"""
|
||||
role: str
|
||||
content: str
|
||||
|
||||
class SystemMessage(Message):
|
||||
"""系统消息"""
|
||||
def __init__(self, content: str):
|
||||
super().__init__(role="system", content=content)
|
||||
|
||||
class UserMessage(Message):
|
||||
"""用户消息"""
|
||||
def __init__(self, content: str):
|
||||
super().__init__(role="user", content=content)
|
||||
|
||||
class AssistantMessage(Message):
|
||||
"""助手消息"""
|
||||
def __init__(self, content: str):
|
||||
super().__init__(role="assistant", content=content)
|
||||
```
|
||||
|
||||
### 6.3 实际模板实现
|
||||
|
||||
系统中实际实现的13个提示模板:
|
||||
|
||||
#### template_system.py中的模板 (8个)
|
||||
1. `network_diagnosis` - 网络诊断提示模板
|
||||
2. `device_configuration` - 设备配置会话模板
|
||||
3. `device_diagnosis` - 网络设备诊断模板
|
||||
4. `config_review` - 网络设备配置审查模板
|
||||
5. `route_analysis` - 网络路由分析模板
|
||||
6. `vlan_config` - VLAN配置生成模板
|
||||
7. `network_topology` - 网络拓扑分析模板
|
||||
8. `network_security` - 网络安全评估模板
|
||||
|
||||
#### device_prompts.py中的模板 (5个)
|
||||
1. `cisco_device_analysis` - 思科设备分析模板
|
||||
2. `huawei_device_analysis` - 华为设备分析模板
|
||||
3. `network_troubleshooting` - 网络故障排除模板
|
||||
4. `security_audit` - 网络安全审计模板
|
||||
5. `performance_optimization` - 网络性能优化模板
|
||||
|
||||
#### 6.2.3 模板渲染函数
|
||||
|
||||
```python
|
||||
async def render_template_with_resources(
|
||||
template_name: str,
|
||||
context: Dict[str, Any],
|
||||
resource_uris: Dict[str, str],
|
||||
resource_manager=None
|
||||
) -> Union[str, List[Message]]:
|
||||
"""渲染包含资源引用的模板"""
|
||||
```
|
||||
|
||||
## 7. 扩展模块
|
||||
|
||||
### 7.1 拓扑发现模块
|
||||
|
||||
**实现文件**: `topology_discovery_improved.py`
|
||||
|
||||
该模块实现了基于CDP/LLDP协议的网络拓扑自动发现功能,支持多厂商设备的邻居发现和拓扑构建。
|
||||
|
||||
### 7.2 网络扫描模块
|
||||
|
||||
**实现文件**: `network_scanner.py`
|
||||
|
||||
该模块实现了网络范围扫描和设备发现功能,支持ping检测、端口扫描、SNMP检测等多种发现方式。
|
||||
|
||||
## 8. 数据持久化
|
||||
|
||||
系统采用JSON文件存储方式进行数据持久化:
|
||||
|
||||
- **设备数据**: `data/devices.json`
|
||||
- **凭据数据**: `data/credentials.json`
|
||||
- **资源缓存**: `resource_cache/` 目录
|
||||
- **模板缓存**: `templates/` 目录
|
||||
|
||||
## 9. 模块间交互
|
||||
|
||||
```
|
||||
MCP服务器 (server.py)
|
||||
↓
|
||||
├── 工具管理 (tool_manager.py) → 功能分类
|
||||
├── 资源管理 (mcp_resources.py) → 数据提供
|
||||
├── 模板系统 (template_system.py + device_prompts.py) → 提示生成
|
||||
├── 设备管理 (network_devices.py) → 设备CRUD
|
||||
├── 设备连接 (device_connector.py) → 连接管理
|
||||
├── 拓扑发现 (topology_discovery_improved.py) → 拓扑构建
|
||||
└── 网络扫描 (network_scanner.py) → 设备发现
|
||||
```
|
||||
|
||||
这种模块化设计确保了系统的可维护性和扩展性,每个模块都有明确的职责和接口,便于独立开发和测试。
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,729 @@
|
||||
# NetBrain MCP 项目教程
|
||||
|
||||
本教程详细介绍如何使用NetBrain MCP项目,包括MCP协议的基本概念、实际实现方式和高级使用技巧。
|
||||
|
||||
## 1. MCP协议概述
|
||||
|
||||
### 1.1 什么是MCP?
|
||||
|
||||
MCP(Model Context Protocol)是一个开放标准,用于连接LLM(大型语言模型)应用程序与外部数据源和工具。可以将MCP视为"AI领域的USB-C"——一种通用连接器,使AI模型能够与外部工具或数据源建立安全的双向连接。
|
||||
|
||||
### 1.2 NetBrain MCP的实现特点
|
||||
|
||||
NetBrain MCP基于**FastMCP框架**实现,具有以下特点:
|
||||
|
||||
- **32个MCP工具**:涵盖设备管理、连接控制、拓扑发现、网络扫描等
|
||||
- **13个MCP资源**:提供设备、配置、拓扑、扫描等数据资源
|
||||
- **13个提示模板**:专业的网络运维AI提示模板
|
||||
- **混合异步/同步模式**:智能适配不同类型的设备连接
|
||||
- **多厂商支持**:思科、华为、H3C、Juniper等主流设备
|
||||
|
||||
## 2. MCP核心概念
|
||||
|
||||
### 2.1 工具(Tools)
|
||||
|
||||
工具是模型控制的函数,允许LLM执行动作和产生副作用。
|
||||
|
||||
#### 2.1.1 NetBrain MCP工具分类
|
||||
|
||||
**设备管理工具(6个)**
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def list_devices(vendor: str = None, device_type: str = None, status: str = None, tag: str = None) -> List[Dict[str, Any]]:
|
||||
"""列出网络设备,支持过滤条件"""
|
||||
|
||||
@mcp.tool()
|
||||
async def add_device(name: str, ip_address: str, device_type: str, vendor: str, platform: str = None, ...) -> Dict[str, Any]:
|
||||
"""添加新的网络设备"""
|
||||
|
||||
@mcp.tool()
|
||||
async def get_device(device_id: str) -> Optional[Dict[str, Any]]:
|
||||
"""获取设备详细信息"""
|
||||
|
||||
@mcp.tool()
|
||||
async def update_device(device_id: str, **kwargs) -> Optional[Dict[str, Any]]:
|
||||
"""更新设备信息"""
|
||||
|
||||
@mcp.tool()
|
||||
async def delete_device(device_id: str) -> bool:
|
||||
"""删除设备"""
|
||||
```
|
||||
|
||||
**连接管理工具(5个)**
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def connect_device(device_id: str, credential_id: str) -> Dict[str, Any]:
|
||||
"""连接到网络设备"""
|
||||
|
||||
@mcp.tool()
|
||||
async def disconnect_device(device_id: str, credential_id: str) -> Dict[str, Any]:
|
||||
"""断开设备连接"""
|
||||
|
||||
@mcp.tool()
|
||||
async def send_command(device_id: str, credential_id: str, command: str, timeout: int = 30) -> Dict[str, Any]:
|
||||
"""发送单个命令到设备"""
|
||||
|
||||
@mcp.tool()
|
||||
async def send_commands(device_id: str, credential_id: str, commands: List[str], timeout: int = 30) -> List[Dict[str, Any]]:
|
||||
"""发送多个命令到设备"""
|
||||
|
||||
@mcp.tool()
|
||||
async def get_active_connections() -> List[Dict[str, Any]]:
|
||||
"""获取当前活动的设备连接"""
|
||||
```
|
||||
|
||||
**拓扑发现工具(6个)**
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def discover_topology(device_ids: List[str]) -> Dict[str, Any]:
|
||||
"""发现网络拓扑结构"""
|
||||
|
||||
@mcp.tool()
|
||||
async def get_topology() -> Dict[str, Any]:
|
||||
"""获取当前网络拓扑"""
|
||||
|
||||
@mcp.tool()
|
||||
async def clear_topology() -> Dict[str, Any]:
|
||||
"""清除拓扑缓存"""
|
||||
|
||||
@mcp.tool()
|
||||
async def get_device_neighbors(device_id: str) -> Dict[str, Any]:
|
||||
"""获取设备的邻居信息"""
|
||||
|
||||
@mcp.tool()
|
||||
async def discover_device_neighbors(device_id: str) -> Dict[str, Any]:
|
||||
"""发现设备邻居"""
|
||||
|
||||
@mcp.tool()
|
||||
async def get_topology_statistics() -> Dict[str, Any]:
|
||||
"""获取拓扑统计信息"""
|
||||
```
|
||||
|
||||
#### 2.1.2 工具实现方式
|
||||
|
||||
NetBrain MCP使用FastMCP的装饰器方式注册工具:
|
||||
|
||||
```python
|
||||
# 在server.py中的实际实现
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from network_devices import device_manager
|
||||
from device_connector import connection_manager
|
||||
|
||||
# 创建FastMCP服务器实例
|
||||
mcp = FastMCP("NetBrain MCP")
|
||||
|
||||
@mcp.tool()
|
||||
async def add_device(
|
||||
name: str,
|
||||
ip_address: str,
|
||||
device_type: str,
|
||||
vendor: str,
|
||||
platform: str = None,
|
||||
model: str = None,
|
||||
os_version: str = None,
|
||||
location: str = None,
|
||||
description: str = None
|
||||
) -> Dict[str, Any]:
|
||||
"""添加新的网络设备到系统中"""
|
||||
try:
|
||||
# 创建设备对象
|
||||
device = NetworkDevice(
|
||||
name=name,
|
||||
ip_address=ip_address,
|
||||
device_type=DeviceType(device_type),
|
||||
vendor=DeviceVendor(vendor),
|
||||
platform=platform or "",
|
||||
model=model or "",
|
||||
os_version=os_version or "",
|
||||
location=location or "",
|
||||
description=description or ""
|
||||
)
|
||||
|
||||
# 添加设备
|
||||
device_id = device_manager.add_device(device)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"device_id": device_id,
|
||||
"message": f"设备 {name} 添加成功"
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"添加设备失败: {str(e)}")
|
||||
return {
|
||||
"success": False,
|
||||
"error": str(e)
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 资源(Resources)
|
||||
|
||||
资源是应用程序控制的数据对象,通过URI标识,用于为LLM提供上下文信息。
|
||||
|
||||
#### 2.2.1 NetBrain MCP资源列表
|
||||
|
||||
系统实现了13个MCP资源:
|
||||
|
||||
**设备相关资源(5个)**
|
||||
```python
|
||||
@resource_manager.register_resource("device/{device_id}", ResourceType.DEVICE)
|
||||
async def get_device_resource(device_id: str) -> Dict[str, Any]:
|
||||
"""获取设备基本信息"""
|
||||
|
||||
@resource_manager.register_resource("device/{device_id}/config", ResourceType.CONFIG)
|
||||
async def get_device_config_resource(device_id: str) -> Dict[str, Any]:
|
||||
"""获取设备配置信息"""
|
||||
|
||||
@resource_manager.register_resource("device/{device_id}/interfaces", ResourceType.DEVICE)
|
||||
async def get_device_interfaces_resource(device_id: str) -> Dict[str, Any]:
|
||||
"""获取设备接口信息"""
|
||||
|
||||
@resource_manager.register_resource("device/{device_id}/routes", ResourceType.DEVICE)
|
||||
async def get_device_routes_resource(device_id: str) -> Dict[str, Any]:
|
||||
"""获取设备路由信息"""
|
||||
|
||||
@resource_manager.register_resource("device/{device_id}/neighbors", ResourceType.TOPOLOGY)
|
||||
async def get_device_neighbors_resource(device_id: str) -> Dict[str, Any]:
|
||||
"""获取设备邻居信息"""
|
||||
```
|
||||
|
||||
**系统资源(4个)**
|
||||
```python
|
||||
@resource_manager.register_resource("greeting/{name}", ResourceType.SYSTEM)
|
||||
async def get_greeting_resource(name: str) -> Dict[str, Any]:
|
||||
"""问候信息资源(示例)"""
|
||||
|
||||
@resource_manager.register_resource("credentials", ResourceType.CREDENTIAL)
|
||||
async def get_credentials_resource() -> Dict[str, Any]:
|
||||
"""获取凭据列表"""
|
||||
|
||||
@resource_manager.register_resource("system/status", ResourceType.SYSTEM)
|
||||
async def get_system_status_resource() -> Dict[str, Any]:
|
||||
"""获取系统状态"""
|
||||
|
||||
@resource_manager.register_resource("topology", ResourceType.TOPOLOGY)
|
||||
async def get_topology_resource() -> Dict[str, Any]:
|
||||
"""获取网络拓扑"""
|
||||
```
|
||||
|
||||
#### 2.2.2 资源实现方式
|
||||
|
||||
```python
|
||||
# 在server.py中的实际资源处理器
|
||||
@mcp.resource("{uri}")
|
||||
async def mcp_resource_handler(uri: str) -> Any:
|
||||
"""
|
||||
MCP资源处理器,处理所有资源请求
|
||||
|
||||
Args:
|
||||
uri: 资源URI
|
||||
|
||||
Returns:
|
||||
资源内容
|
||||
"""
|
||||
try:
|
||||
result = await resource_manager.get_resource(uri)
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"获取资源失败: {uri}, 错误: {str(e)}")
|
||||
return {"error": f"获取资源失败: {str(e)}"}
|
||||
```
|
||||
|
||||
### 2.3 提示模板(Prompts)
|
||||
|
||||
提示模板是用户控制的交互模板,帮助构造有效的LLM提示。
|
||||
|
||||
#### 2.3.1 NetBrain MCP提示模板
|
||||
|
||||
系统实现了13个专业网络运维提示模板:
|
||||
|
||||
**template_system.py中的模板(8个)**
|
||||
```python
|
||||
@template_manager.register_template(
|
||||
name="device_diagnosis",
|
||||
description="网络设备诊断模板"
|
||||
)
|
||||
def device_diagnosis_template(device_info: Dict[str, Any], interfaces_info: str = None, logs: str = None) -> List[Message]:
|
||||
"""网络设备诊断提示模板,用于分析设备状态和接口信息"""
|
||||
system_prompt = f"""你是一位专业的网络工程师,负责诊断{device_info.get('vendor', '未知厂商')}的{device_info.get('device_type', '网络设备')}。
|
||||
请根据提供的设备信息、接口状态和日志,进行专业分析并提供诊断报告。"""
|
||||
|
||||
return [
|
||||
SystemMessage(system_prompt),
|
||||
UserMessage(f"请诊断设备:{device_info}")
|
||||
]
|
||||
|
||||
@template_manager.register_template(
|
||||
name="config_review",
|
||||
description="网络设备配置审查模板"
|
||||
)
|
||||
def config_review_template(device_info: Dict[str, Any], config_content: str, focus_area: str = None) -> List[Message]:
|
||||
"""网络配置审查提示模板,用于审查设备配置并提供改进建议"""
|
||||
# 实现...
|
||||
```
|
||||
|
||||
**device_prompts.py中的模板(5个)**
|
||||
```python
|
||||
@template_manager.register_template(
|
||||
name="cisco_device_analysis",
|
||||
description="思科设备专业分析模板"
|
||||
)
|
||||
def cisco_device_analysis_template(device_info: Dict[str, Any], command_outputs: Dict[str, str]) -> List[Message]:
|
||||
"""思科设备专业分析模板"""
|
||||
# 实现...
|
||||
|
||||
@template_manager.register_template(
|
||||
name="huawei_device_analysis",
|
||||
description="华为设备专业分析模板"
|
||||
)
|
||||
def huawei_device_analysis_template(device_info: Dict[str, Any], command_outputs: Dict[str, str]) -> List[Message]:
|
||||
"""华为设备专业分析模板"""
|
||||
# 实现...
|
||||
```
|
||||
|
||||
#### 2.3.2 模板实现方式
|
||||
|
||||
```python
|
||||
# 在server.py中的模板处理器
|
||||
@mcp.prompt("{name}")
|
||||
async def mcp_prompt_handler(name: str, arguments: dict = None) -> str:
|
||||
"""
|
||||
MCP提示模板处理器
|
||||
|
||||
Args:
|
||||
name: 模板名称
|
||||
arguments: 模板参数
|
||||
|
||||
Returns:
|
||||
渲染后的提示内容
|
||||
"""
|
||||
try:
|
||||
result = template_manager.render_template(name, arguments or {})
|
||||
if isinstance(result, list):
|
||||
# 如果返回消息列表,转换为字符串
|
||||
return "\n".join([msg.content for msg in result])
|
||||
return result or ""
|
||||
except Exception as e:
|
||||
logger.error(f"渲染模板失败: {name}, 错误: {str(e)}")
|
||||
return f"模板渲染失败: {str(e)}"
|
||||
```
|
||||
|
||||
## 3. 实际使用示例
|
||||
|
||||
### 3.1 基本设备管理
|
||||
|
||||
#### 3.1.1 添加设备凭据
|
||||
|
||||
```
|
||||
# 在Claude或其他MCP客户端中输入:
|
||||
请帮我添加一个思科设备的SSH凭据,用户名是admin,密码是cisco123,端口是22
|
||||
```
|
||||
|
||||
AI将自动调用`add_credential`工具:
|
||||
```python
|
||||
# 实际调用的工具
|
||||
await add_credential(
|
||||
name="思科SSH凭据",
|
||||
username="admin",
|
||||
password="cisco123",
|
||||
protocol="ssh",
|
||||
port=22
|
||||
)
|
||||
```
|
||||
|
||||
#### 3.1.2 添加网络设备
|
||||
|
||||
```
|
||||
请添加一台思科路由器,名称是Router-01,IP地址是192.168.1.1,型号是ISR4321,使用刚才添加的凭据
|
||||
```
|
||||
|
||||
AI将调用`add_device`工具:
|
||||
```python
|
||||
await add_device(
|
||||
name="Router-01",
|
||||
ip_address="192.168.1.1",
|
||||
device_type="router",
|
||||
vendor="cisco",
|
||||
platform="cisco_iosxe",
|
||||
model="ISR4321"
|
||||
)
|
||||
```
|
||||
|
||||
### 3.2 设备连接和命令执行
|
||||
|
||||
#### 3.2.1 连接设备
|
||||
|
||||
```
|
||||
请连接到Router-01设备
|
||||
```
|
||||
|
||||
AI将调用连接工具:
|
||||
```python
|
||||
await connect_device(
|
||||
device_id="router-01-uuid",
|
||||
credential_id="credential-uuid"
|
||||
)
|
||||
```
|
||||
|
||||
#### 3.2.2 执行命令
|
||||
|
||||
```
|
||||
在Router-01上执行 show version 命令
|
||||
```
|
||||
|
||||
AI将调用命令执行工具:
|
||||
```python
|
||||
await send_command(
|
||||
device_id="router-01-uuid",
|
||||
credential_id="credential-uuid",
|
||||
command="show version",
|
||||
timeout=30
|
||||
)
|
||||
```
|
||||
|
||||
### 3.3 拓扑发现
|
||||
|
||||
```
|
||||
请发现Router-01的网络拓扑
|
||||
```
|
||||
|
||||
AI将调用拓扑发现工具:
|
||||
```python
|
||||
await discover_topology(
|
||||
device_ids=["router-01-uuid"]
|
||||
)
|
||||
```
|
||||
|
||||
### 3.4 使用提示模板
|
||||
|
||||
```
|
||||
使用设备诊断模板分析Router-01的状态
|
||||
```
|
||||
|
||||
AI将:
|
||||
1. 获取设备信息资源
|
||||
2. 获取设备接口信息
|
||||
3. 使用device_diagnosis模板进行分析
|
||||
|
||||
## 4. 高级功能
|
||||
|
||||
### 4.1 批量操作
|
||||
|
||||
#### 4.1.1 批量命令执行
|
||||
|
||||
```
|
||||
在Router-01上依次执行以下命令:
|
||||
1. show running-config
|
||||
2. show ip route
|
||||
3. show interface status
|
||||
```
|
||||
|
||||
AI将调用`send_commands`工具:
|
||||
```python
|
||||
await send_commands(
|
||||
device_id="router-01-uuid",
|
||||
credential_id="credential-uuid",
|
||||
commands=[
|
||||
"show running-config",
|
||||
"show ip route",
|
||||
"show interface status"
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
#### 4.1.2 网络扫描
|
||||
|
||||
```
|
||||
请扫描192.168.1.0/24网段,发现网络设备
|
||||
```
|
||||
|
||||
AI将调用网络扫描工具:
|
||||
```python
|
||||
await scan_network_range(
|
||||
network="192.168.1.0/24",
|
||||
timeout=5,
|
||||
max_concurrent=50,
|
||||
ports=[22, 23, 80, 443, 161]
|
||||
)
|
||||
```
|
||||
|
||||
### 4.2 资源访问
|
||||
|
||||
#### 4.2.1 获取设备配置
|
||||
|
||||
```
|
||||
请获取Router-01的配置信息
|
||||
```
|
||||
|
||||
AI将访问配置资源:
|
||||
```
|
||||
资源URI: device/router-01-uuid/config
|
||||
```
|
||||
|
||||
#### 4.2.2 获取拓扑信息
|
||||
|
||||
```
|
||||
显示当前网络拓扑的统计信息
|
||||
```
|
||||
|
||||
AI将访问拓扑资源:
|
||||
```
|
||||
资源URI: topology/statistics
|
||||
```
|
||||
|
||||
### 4.3 智能诊断
|
||||
|
||||
#### 4.3.1 使用诊断模板
|
||||
|
||||
```
|
||||
使用华为设备分析模板检查Switch-01的状态
|
||||
```
|
||||
|
||||
AI将:
|
||||
1. 识别设备是华为设备
|
||||
2. 获取设备相关信息和命令输出
|
||||
3. 使用`huawei_device_analysis`模板
|
||||
4. 提供专业的分析报告
|
||||
|
||||
#### 4.3.2 配置审查
|
||||
|
||||
```
|
||||
使用配置审查模板检查Router-01的安全配置
|
||||
```
|
||||
|
||||
AI将使用`config_review`模板,重点关注安全配置。
|
||||
|
||||
## 5. 系统集成
|
||||
|
||||
### 5.1 连接到Claude Desktop
|
||||
|
||||
#### 5.1.1 配置文件
|
||||
|
||||
编辑Claude Desktop配置文件:
|
||||
|
||||
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
**Linux**: `~/.config/Claude/claude_desktop_config.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"netbrain-mcp": {
|
||||
"command": "python",
|
||||
"args": ["/path/to/NetBrainMCP/server.py"],
|
||||
"env": {
|
||||
"LOG_LEVEL": "INFO"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5.1.2 验证连接
|
||||
|
||||
重启Claude Desktop后,在对话中输入:
|
||||
```
|
||||
请列出所有可用的网络设备
|
||||
```
|
||||
|
||||
如果看到工具图标并得到设备列表响应,说明连接成功。
|
||||
|
||||
### 5.2 连接到Cursor IDE
|
||||
|
||||
#### 5.2.1 启动SSE模式
|
||||
|
||||
```bash
|
||||
cd /path/to/NetBrainMCP
|
||||
python server.py --mode sse --port 8000
|
||||
```
|
||||
|
||||
#### 5.2.2 配置Cursor
|
||||
|
||||
1. 打开Cursor → 设置 → 功能 → MCP服务器
|
||||
2. 添加新服务器:
|
||||
- **名称**: netbrain-mcp
|
||||
- **类型**: sse
|
||||
- **URL**: http://localhost:8000/sse
|
||||
|
||||
### 5.3 Web界面使用
|
||||
|
||||
#### 5.3.1 启动Web服务器
|
||||
|
||||
```bash
|
||||
python server.py --web --port 8080
|
||||
```
|
||||
|
||||
#### 5.3.2 访问Web界面
|
||||
|
||||
在浏览器中访问:http://localhost:8080
|
||||
|
||||
Web界面提供:
|
||||
- 设备管理页面
|
||||
- 多标签页终端
|
||||
- 交互式拓扑图
|
||||
|
||||
## 6. 故障排除
|
||||
|
||||
### 6.1 常见问题
|
||||
|
||||
#### 6.1.1 MCP服务器无法启动
|
||||
|
||||
**问题症状**:
|
||||
```
|
||||
ModuleNotFoundError: No module named 'mcp'
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
#### 6.1.2 设备连接失败
|
||||
|
||||
**问题症状**:
|
||||
```
|
||||
{"success": false, "error": "连接超时"}
|
||||
```
|
||||
|
||||
**解决方案**:
|
||||
1. 检查网络连通性:`ping 192.168.1.1`
|
||||
2. 验证SSH/Telnet服务:`telnet 192.168.1.1 22`
|
||||
3. 确认凭据正确性
|
||||
4. 检查防火墙设置
|
||||
|
||||
#### 6.1.3 Claude Desktop连接问题
|
||||
|
||||
**问题症状**:Claude Desktop不显示工具图标
|
||||
|
||||
**解决方案**:
|
||||
1. 检查配置文件路径和格式
|
||||
2. 验证Python路径和脚本路径
|
||||
3. 查看Claude Desktop日志
|
||||
4. 重启Claude Desktop
|
||||
|
||||
### 6.2 调试技巧
|
||||
|
||||
#### 6.2.1 启用详细日志
|
||||
|
||||
```bash
|
||||
export LOG_LEVEL=DEBUG
|
||||
python server.py
|
||||
```
|
||||
|
||||
#### 6.2.2 测试工具连接
|
||||
|
||||
```python
|
||||
# 测试Scrapli连接
|
||||
python -c "
|
||||
import asyncio
|
||||
from server import test_scrapli_connection
|
||||
result = asyncio.run(test_scrapli_connection(
|
||||
host='192.168.1.1',
|
||||
username='admin',
|
||||
password='cisco123',
|
||||
platform='cisco_iosxe'
|
||||
))
|
||||
print(result)
|
||||
"
|
||||
```
|
||||
|
||||
## 7. 扩展开发
|
||||
|
||||
### 7.1 添加自定义工具
|
||||
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def custom_network_tool(param1: str, param2: int) -> Dict[str, Any]:
|
||||
"""自定义网络工具"""
|
||||
try:
|
||||
# 实现自定义逻辑
|
||||
result = perform_custom_operation(param1, param2)
|
||||
return {"success": True, "result": result}
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
```
|
||||
|
||||
### 7.2 添加自定义资源
|
||||
|
||||
```python
|
||||
@resource_manager.register_resource("custom/{id}", ResourceType.CUSTOM)
|
||||
async def get_custom_resource(id: str) -> Dict[str, Any]:
|
||||
"""自定义资源处理器"""
|
||||
# 实现自定义资源获取逻辑
|
||||
return {"data": f"自定义数据 for {id}"}
|
||||
```
|
||||
|
||||
### 7.3 添加自定义模板
|
||||
|
||||
```python
|
||||
@template_manager.register_template(
|
||||
name="custom_analysis",
|
||||
description="自定义分析模板"
|
||||
)
|
||||
def custom_analysis_template(data: Dict[str, Any]) -> str:
|
||||
"""自定义分析模板"""
|
||||
return f"基于数据 {data} 进行自定义分析..."
|
||||
```
|
||||
|
||||
## 8. 最佳实践
|
||||
|
||||
### 8.1 设备管理最佳实践
|
||||
|
||||
1. **统一命名规范**:使用一致的设备命名格式
|
||||
2. **合理分组标签**:按功能、位置、环境分组
|
||||
3. **定期更新信息**:保持设备信息的准确性
|
||||
4. **备份配置数据**:定期备份重要配置
|
||||
|
||||
### 8.2 使用技巧
|
||||
|
||||
1. **充分利用模板**:使用专业模板获得更好的分析结果
|
||||
2. **批量操作**:对多个设备执行相同操作时使用批量工具
|
||||
3. **资源组合**:结合多个资源获得全面的设备视图
|
||||
4. **缓存机制**:利用系统缓存提高查询效率
|
||||
|
||||
### 8.3 安全建议
|
||||
|
||||
1. **凭据管理**:使用强密码和定期轮换
|
||||
2. **网络隔离**:在安全的网络环境中部署
|
||||
3. **访问控制**:限制MCP服务器的访问权限
|
||||
4. **日志监控**:定期检查操作日志
|
||||
|
||||
## 9. 性能优化
|
||||
|
||||
### 9.1 连接优化
|
||||
|
||||
```python
|
||||
# 调整连接池设置
|
||||
MAX_CONNECTIONS = 10
|
||||
CONNECTION_TIMEOUT = 30
|
||||
COMMAND_TIMEOUT = 60
|
||||
```
|
||||
|
||||
### 9.2 缓存优化
|
||||
|
||||
```python
|
||||
# 调整缓存策略
|
||||
RESOURCE_CACHE_TTL = 300 # 5分钟
|
||||
CONFIG_CACHE_TTL = 600 # 10分钟
|
||||
TOPOLOGY_CACHE_TTL = 900 # 15分钟
|
||||
```
|
||||
|
||||
### 9.3 并发控制
|
||||
|
||||
```python
|
||||
# 网络扫描并发控制
|
||||
DEFAULT_MAX_CONCURRENT = 50
|
||||
SCAN_TIMEOUT = 5
|
||||
```
|
||||
|
||||
## 10. 总结
|
||||
|
||||
NetBrain MCP项目提供了一个完整的网络运维AI集成平台,通过MCP协议实现:
|
||||
|
||||
- **32个专业工具**:涵盖网络设备管理的各个方面
|
||||
- **13个数据资源**:提供丰富的网络设备和拓扑信息
|
||||
- **13个提示模板**:专业的网络运维AI指导
|
||||
- **多厂商支持**:思科、华为等主流设备厂商
|
||||
- **灵活部署**:支持Claude Desktop、Cursor IDE和Web界面
|
||||
|
||||
通过本教程,您应该能够熟练使用NetBrain MCP系统进行AI驱动的网络运维工作。系统的模块化设计和丰富的扩展机制,也为进一步的定制和开发提供了良好的基础。
|
||||
@@ -0,0 +1,917 @@
|
||||
# NetBrain MCP 安全认证机制设计
|
||||
|
||||
本文档详细描述NetBrain MCP系统的安全认证机制设计,包括当前已实现的安全措施和未来计划的安全增强方案。
|
||||
|
||||
## 1. 当前安全实现状态
|
||||
|
||||
### 1.1 已实现的安全措施
|
||||
|
||||
NetBrain MCP系统当前已实现以下安全措施:
|
||||
|
||||
#### 1.1.1 日志记录和审计
|
||||
- **操作日志记录**:完整记录所有MCP工具调用和系统操作
|
||||
- **连接日志**:记录设备连接、断开和命令执行活动
|
||||
- **错误日志**:记录系统错误和异常事件
|
||||
- **UTF-8编码支持**:JsonFormatter确保日志中文字符正确处理
|
||||
|
||||
#### 1.1.2 输入验证和类型检查
|
||||
- **工具参数验证**:MCP工具的输入参数类型验证
|
||||
- **设备信息验证**:设备添加和更新时的数据格式验证
|
||||
- **命令注入防护**:基本的命令参数清理
|
||||
|
||||
#### 1.1.3 连接安全
|
||||
- **SSH连接**:优先使用SSH协议连接设备
|
||||
- **Telnet备用**:支持Telnet作为备用连接方式
|
||||
- **连接超时**:设置合理的连接和命令执行超时时间
|
||||
- **自动重连**:连接断开时的自动重连机制
|
||||
|
||||
#### 1.1.4 日志脱敏
|
||||
- **密码脱敏**:避免在日志中记录明文密码
|
||||
- **敏感信息标识**:明确识别和处理敏感数据字段
|
||||
|
||||
### 1.2 当前安全限制
|
||||
|
||||
#### 1.2.1 凭据存储安全
|
||||
- **明文存储**:设备凭据当前以明文形式存储在JSON文件中
|
||||
- **文件权限**:依赖操作系统文件权限保护数据文件
|
||||
- **无加密传输**:本地文件读写无额外加密层
|
||||
|
||||
#### 1.2.2 访问控制
|
||||
- **无认证机制**:MCP服务器当前无用户认证要求
|
||||
- **无授权检查**:所有连接的客户端均有完全访问权限
|
||||
- **无会话管理**:缺乏会话超时和管理机制
|
||||
|
||||
## 2. 安全需求分析
|
||||
|
||||
### 2.1 威胁模型
|
||||
|
||||
NetBrain MCP系统面临以下潜在安全威胁:
|
||||
|
||||
#### 2.1.1 数据安全威胁
|
||||
1. **凭据泄露**:设备登录凭据存储在明文文件中,存在泄露风险
|
||||
2. **配置数据窃取**:设备配置信息可能包含敏感网络架构信息
|
||||
3. **日志信息泄露**:操作日志可能包含敏感的网络操作信息
|
||||
|
||||
#### 2.1.2 访问控制威胁
|
||||
1. **未授权访问**:任何能连接到MCP服务器的客户端都能执行所有操作
|
||||
2. **权限提升**:缺乏细粒度权限控制机制
|
||||
3. **会话劫持**:缺乏会话管理和验证机制
|
||||
|
||||
#### 2.1.3 网络安全威胁
|
||||
1. **中间人攻击**:设备连接可能被拦截或篡改
|
||||
2. **网络扫描滥用**:网络扫描功能可能被恶意使用
|
||||
3. **设备连接滥用**:设备连接功能可能被用于非授权访问
|
||||
|
||||
#### 2.1.4 系统安全威胁
|
||||
1. **文件系统访问**:数据文件可能被本地用户非授权访问
|
||||
2. **进程劫持**:MCP服务器进程可能被恶意程序控制
|
||||
3. **资源耗尽**:恶意客户端可能消耗系统资源
|
||||
|
||||
### 2.2 安全要求
|
||||
|
||||
基于威胁模型,系统需要满足以下安全要求:
|
||||
|
||||
#### 2.2.1 数据保护要求
|
||||
- **凭据加密存储**:设备凭据必须加密存储
|
||||
- **敏感数据标识**:明确标识和保护敏感数据
|
||||
- **数据传输保护**:保护数据在传输过程中的安全性
|
||||
|
||||
#### 2.2.2 访问控制要求
|
||||
- **身份认证**:验证客户端身份
|
||||
- **权限授权**:基于角色的细粒度权限控制
|
||||
- **会话管理**:安全的会话创建、维护和销毁
|
||||
|
||||
#### 2.2.3 网络安全要求
|
||||
- **通信加密**:保护MCP通信通道
|
||||
- **设备连接安全**:安全的设备连接和命令执行
|
||||
- **网络隔离**:适当的网络访问限制
|
||||
|
||||
## 3. 安全实现计划
|
||||
|
||||
### 3.1 优先级分类
|
||||
|
||||
#### 3.1.1 高优先级(安全关键)
|
||||
1. **凭据加密存储**:立即实施
|
||||
2. **基础访问控制**:API密钥认证
|
||||
3. **通信安全**:HTTPS/WSS支持
|
||||
|
||||
#### 3.1.2 中优先级(安全重要)
|
||||
1. **细粒度权限控制**:基于角色的访问控制
|
||||
2. **审计增强**:安全事件审计
|
||||
3. **会话管理**:会话超时和管理
|
||||
|
||||
#### 3.1.3 低优先级(安全增强)
|
||||
1. **高级认证**:OAuth2集成
|
||||
2. **安全监控**:实时安全监控
|
||||
3. **加密通信**:端到端加密
|
||||
|
||||
### 3.2 凭据加密存储方案
|
||||
|
||||
#### 3.2.1 加密算法选择
|
||||
使用AES-256-GCM算法进行数据加密:
|
||||
|
||||
```python
|
||||
# 在network_devices.py中增强DeviceCredential类
|
||||
import os
|
||||
import base64
|
||||
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||
|
||||
class SecureCredentialStorage:
|
||||
"""安全凭据存储实现"""
|
||||
|
||||
def __init__(self, master_key: str = None):
|
||||
self.master_key = master_key or os.environ.get('NETBRAIN_MASTER_KEY')
|
||||
if not self.master_key:
|
||||
raise ValueError("Master encryption key not provided")
|
||||
|
||||
# 派生加密密钥
|
||||
salt = b'netbrain_mcp_salt' # 生产环境应使用随机盐
|
||||
kdf = PBKDF2HMAC(
|
||||
algorithm=hashes.SHA256(),
|
||||
length=32,
|
||||
salt=salt,
|
||||
iterations=100000,
|
||||
)
|
||||
self.encryption_key = kdf.derive(self.master_key.encode())
|
||||
|
||||
def encrypt_credential(self, credential_data: str) -> str:
|
||||
"""加密凭据数据"""
|
||||
if not credential_data:
|
||||
return ""
|
||||
|
||||
# 生成随机IV
|
||||
iv = os.urandom(12)
|
||||
|
||||
# 加密数据
|
||||
aesgcm = AESGCM(self.encryption_key)
|
||||
ciphertext = aesgcm.encrypt(iv, credential_data.encode('utf-8'), None)
|
||||
|
||||
# 返回IV+密文的base64编码
|
||||
encrypted_data = base64.b64encode(iv + ciphertext).decode('utf-8')
|
||||
return f"aes256gcm:{encrypted_data}"
|
||||
|
||||
def decrypt_credential(self, encrypted_data: str) -> str:
|
||||
"""解密凭据数据"""
|
||||
if not encrypted_data or not encrypted_data.startswith("aes256gcm:"):
|
||||
return encrypted_data # 向后兼容明文数据
|
||||
|
||||
try:
|
||||
# 解析加密格式
|
||||
encrypted_content = encrypted_data[10:] # 移除"aes256gcm:"前缀
|
||||
data = base64.b64decode(encrypted_content)
|
||||
|
||||
# 提取IV和密文
|
||||
iv = data[:12]
|
||||
ciphertext = data[12:]
|
||||
|
||||
# 解密数据
|
||||
aesgcm = AESGCM(self.encryption_key)
|
||||
plaintext = aesgcm.decrypt(iv, ciphertext, None)
|
||||
return plaintext.decode('utf-8')
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to decrypt credential: {str(e)}")
|
||||
raise ValueError("Invalid encrypted credential data")
|
||||
|
||||
# 增强DeviceCredential类
|
||||
class DeviceCredential:
|
||||
def __init__(self,
|
||||
id: str = None,
|
||||
name: str = "",
|
||||
username: str = "",
|
||||
password: str = "",
|
||||
protocol: ConnectionProtocol = ConnectionProtocol.SSH,
|
||||
port: int = None,
|
||||
enable_password: str = None,
|
||||
ssh_key_file: str = None,
|
||||
encrypted: bool = True):
|
||||
self.id = id or str(uuid.uuid4())
|
||||
self.name = name
|
||||
self.username = username
|
||||
self.protocol = protocol
|
||||
self.port = port or (22 if protocol == ConnectionProtocol.SSH else 23)
|
||||
self.ssh_key_file = ssh_key_file
|
||||
self.encrypted = encrypted
|
||||
|
||||
# 初始化加密存储
|
||||
if encrypted:
|
||||
self._storage = SecureCredentialStorage()
|
||||
self._encrypted_password = self._storage.encrypt_credential(password) if password else ""
|
||||
self._encrypted_enable_password = self._storage.encrypt_credential(enable_password) if enable_password else ""
|
||||
else:
|
||||
self._encrypted_password = password
|
||||
self._encrypted_enable_password = enable_password
|
||||
|
||||
@property
|
||||
def password(self) -> str:
|
||||
"""获取解密后的密码"""
|
||||
if self.encrypted and self._storage:
|
||||
return self._storage.decrypt_credential(self._encrypted_password)
|
||||
return self._encrypted_password
|
||||
|
||||
@password.setter
|
||||
def password(self, value: str):
|
||||
"""设置密码(自动加密)"""
|
||||
if self.encrypted and self._storage:
|
||||
self._encrypted_password = self._storage.encrypt_credential(value)
|
||||
else:
|
||||
self._encrypted_password = value
|
||||
|
||||
@property
|
||||
def enable_password(self) -> str:
|
||||
"""获取解密后的启用密码"""
|
||||
if self.encrypted and self._storage:
|
||||
return self._storage.decrypt_credential(self._encrypted_enable_password)
|
||||
return self._encrypted_enable_password
|
||||
|
||||
@enable_password.setter
|
||||
def enable_password(self, value: str):
|
||||
"""设置启用密码(自动加密)"""
|
||||
if self.encrypted and self._storage:
|
||||
self._encrypted_enable_password = self._storage.encrypt_credential(value)
|
||||
else:
|
||||
self._encrypted_enable_password = value
|
||||
```
|
||||
|
||||
#### 3.2.2 密钥管理方案
|
||||
|
||||
**主密钥管理:**
|
||||
```python
|
||||
# 环境变量方式
|
||||
export NETBRAIN_MASTER_KEY="your-secure-master-key"
|
||||
|
||||
# 配置文件方式(不推荐生产环境)
|
||||
master_key = config.get('security', 'master_key')
|
||||
|
||||
# 密钥文件方式
|
||||
with open('/secure/path/master.key', 'r') as f:
|
||||
master_key = f.read().strip()
|
||||
```
|
||||
|
||||
**密钥轮换策略:**
|
||||
```python
|
||||
class KeyRotationManager:
|
||||
"""密钥轮换管理器"""
|
||||
|
||||
def __init__(self):
|
||||
self.current_key_version = 1
|
||||
self.key_versions = {}
|
||||
|
||||
def rotate_master_key(self, new_key: str) -> bool:
|
||||
"""轮换主密钥"""
|
||||
try:
|
||||
# 使用新密钥重新加密所有凭据
|
||||
old_storage = SecureCredentialStorage(self.get_current_key())
|
||||
new_storage = SecureCredentialStorage(new_key)
|
||||
|
||||
# 重新加密过程...
|
||||
self.current_key_version += 1
|
||||
self.key_versions[self.current_key_version] = new_key
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Key rotation failed: {str(e)}")
|
||||
return False
|
||||
```
|
||||
|
||||
### 3.3 API认证机制
|
||||
|
||||
#### 3.3.1 API密钥认证实现
|
||||
|
||||
```python
|
||||
# 新增文件:security/api_auth.py
|
||||
import secrets
|
||||
import hashlib
|
||||
import hmac
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
class APIKeyManager:
|
||||
"""API密钥管理器"""
|
||||
|
||||
def __init__(self):
|
||||
self.api_keys: Dict[str, Dict[str, Any]] = {}
|
||||
self.load_api_keys()
|
||||
|
||||
def generate_api_key(self, name: str, permissions: List[str] = None, expires_days: int = 90) -> str:
|
||||
"""生成新的API密钥"""
|
||||
# 生成32字节随机密钥
|
||||
key = secrets.token_urlsafe(32)
|
||||
|
||||
# 计算密钥哈希用于存储
|
||||
key_hash = hashlib.sha256(key.encode()).hexdigest()
|
||||
|
||||
# 设置过期时间
|
||||
expires_at = datetime.now() + timedelta(days=expires_days) if expires_days > 0 else None
|
||||
|
||||
# 存储密钥信息
|
||||
self.api_keys[key_hash] = {
|
||||
"name": name,
|
||||
"permissions": permissions or ["read", "write"],
|
||||
"created_at": datetime.now().isoformat(),
|
||||
"expires_at": expires_at.isoformat() if expires_at else None,
|
||||
"last_used": None,
|
||||
"usage_count": 0
|
||||
}
|
||||
|
||||
self.save_api_keys()
|
||||
logger.info(f"Generated API key for: {name}")
|
||||
return key
|
||||
|
||||
def validate_api_key(self, key: str) -> Optional[Dict[str, Any]]:
|
||||
"""验证API密钥"""
|
||||
if not key:
|
||||
return None
|
||||
|
||||
key_hash = hashlib.sha256(key.encode()).hexdigest()
|
||||
key_info = self.api_keys.get(key_hash)
|
||||
|
||||
if not key_info:
|
||||
logger.warning(f"Invalid API key attempted: {key[:8]}...")
|
||||
return None
|
||||
|
||||
# 检查过期时间
|
||||
if key_info.get("expires_at"):
|
||||
expires_at = datetime.fromisoformat(key_info["expires_at"])
|
||||
if datetime.now() > expires_at:
|
||||
logger.warning(f"Expired API key used: {key_info['name']}")
|
||||
return None
|
||||
|
||||
# 更新使用统计
|
||||
key_info["last_used"] = datetime.now().isoformat()
|
||||
key_info["usage_count"] += 1
|
||||
|
||||
return key_info
|
||||
|
||||
def revoke_api_key(self, key: str) -> bool:
|
||||
"""撤销API密钥"""
|
||||
key_hash = hashlib.sha256(key.encode()).hexdigest()
|
||||
if key_hash in self.api_keys:
|
||||
del self.api_keys[key_hash]
|
||||
self.save_api_keys()
|
||||
return True
|
||||
return False
|
||||
|
||||
# MCP服务器认证中间件
|
||||
class MCPAuthMiddleware:
|
||||
"""MCP认证中间件"""
|
||||
|
||||
def __init__(self, api_key_manager: APIKeyManager):
|
||||
self.api_key_manager = api_key_manager
|
||||
self.enabled = os.environ.get('NETBRAIN_AUTH_ENABLED', 'false').lower() == 'true'
|
||||
|
||||
def authenticate_request(self, headers: Dict[str, str]) -> Optional[Dict[str, Any]]:
|
||||
"""认证请求"""
|
||||
if not self.enabled:
|
||||
return {"name": "anonymous", "permissions": ["read", "write"]}
|
||||
|
||||
# 从请求头获取API密钥
|
||||
api_key = headers.get('Authorization', '').replace('Bearer ', '')
|
||||
if not api_key:
|
||||
api_key = headers.get('X-API-Key', '')
|
||||
|
||||
if not api_key:
|
||||
logger.warning("No API key provided in request")
|
||||
return None
|
||||
|
||||
return self.api_key_manager.validate_api_key(api_key)
|
||||
```
|
||||
|
||||
#### 3.3.2 权限控制实现
|
||||
|
||||
```python
|
||||
# 新增文件:security/permissions.py
|
||||
from enum import Enum
|
||||
from typing import List, Dict, Any
|
||||
from functools import wraps
|
||||
|
||||
class Permission(Enum):
|
||||
"""权限枚举"""
|
||||
# 设备管理权限
|
||||
DEVICE_READ = "device:read"
|
||||
DEVICE_WRITE = "device:write"
|
||||
DEVICE_DELETE = "device:delete"
|
||||
|
||||
# 连接管理权限
|
||||
CONNECT_DEVICE = "connect:device"
|
||||
EXECUTE_COMMAND = "execute:command"
|
||||
|
||||
# 拓扑发现权限
|
||||
DISCOVER_TOPOLOGY = "topology:discover"
|
||||
VIEW_TOPOLOGY = "topology:view"
|
||||
|
||||
# 扫描权限
|
||||
SCAN_NETWORK = "scan:network"
|
||||
VIEW_SCAN_RESULTS = "scan:view"
|
||||
|
||||
# 系统管理权限
|
||||
MANAGE_CREDENTIALS = "credentials:manage"
|
||||
MANAGE_TEMPLATES = "templates:manage"
|
||||
SYSTEM_ADMIN = "system:admin"
|
||||
|
||||
class Role(Enum):
|
||||
"""角色枚举"""
|
||||
ADMIN = "admin"
|
||||
ENGINEER = "engineer"
|
||||
OPERATOR = "operator"
|
||||
VIEWER = "viewer"
|
||||
|
||||
# 角色权限映射
|
||||
ROLE_PERMISSIONS = {
|
||||
Role.ADMIN: [perm for perm in Permission], # 管理员拥有所有权限
|
||||
Role.ENGINEER: [
|
||||
Permission.DEVICE_READ,
|
||||
Permission.DEVICE_WRITE,
|
||||
Permission.CONNECT_DEVICE,
|
||||
Permission.EXECUTE_COMMAND,
|
||||
Permission.DISCOVER_TOPOLOGY,
|
||||
Permission.VIEW_TOPOLOGY,
|
||||
Permission.SCAN_NETWORK,
|
||||
Permission.VIEW_SCAN_RESULTS,
|
||||
Permission.MANAGE_CREDENTIALS,
|
||||
],
|
||||
Role.OPERATOR: [
|
||||
Permission.DEVICE_READ,
|
||||
Permission.CONNECT_DEVICE,
|
||||
Permission.EXECUTE_COMMAND,
|
||||
Permission.VIEW_TOPOLOGY,
|
||||
Permission.VIEW_SCAN_RESULTS,
|
||||
],
|
||||
Role.VIEWER: [
|
||||
Permission.DEVICE_READ,
|
||||
Permission.VIEW_TOPOLOGY,
|
||||
Permission.VIEW_SCAN_RESULTS,
|
||||
]
|
||||
}
|
||||
|
||||
def require_permission(required_permission: Permission):
|
||||
"""权限检查装饰器"""
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
async def wrapper(*args, **kwargs):
|
||||
# 从上下文获取用户权限
|
||||
user_permissions = get_current_user_permissions()
|
||||
|
||||
if required_permission not in user_permissions:
|
||||
logger.warning(f"Permission denied: {required_permission.value}")
|
||||
raise PermissionError(f"Insufficient permissions: {required_permission.value}")
|
||||
|
||||
return await func(*args, **kwargs)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
# 在MCP工具中使用权限检查
|
||||
@mcp.tool()
|
||||
@require_permission(Permission.DEVICE_WRITE)
|
||||
async def add_device(...) -> Dict[str, Any]:
|
||||
"""添加设备(需要设备写权限)"""
|
||||
# 实现...
|
||||
|
||||
@mcp.tool()
|
||||
@require_permission(Permission.SCAN_NETWORK)
|
||||
async def scan_network_range(...) -> Dict[str, Any]:
|
||||
"""扫描网络(需要扫描权限)"""
|
||||
# 实现...
|
||||
```
|
||||
|
||||
### 3.4 审计日志增强
|
||||
|
||||
#### 3.4.1 安全事件审计
|
||||
|
||||
```python
|
||||
# 新增文件:security/audit.py
|
||||
import json
|
||||
import hashlib
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, Optional
|
||||
from enum import Enum
|
||||
|
||||
class AuditEventType(Enum):
|
||||
"""审计事件类型"""
|
||||
# 认证事件
|
||||
AUTH_LOGIN = "auth.login"
|
||||
AUTH_LOGOUT = "auth.logout"
|
||||
AUTH_FAILED = "auth.failed"
|
||||
API_KEY_CREATED = "auth.api_key_created"
|
||||
API_KEY_REVOKED = "auth.api_key_revoked"
|
||||
|
||||
# 设备操作事件
|
||||
DEVICE_ADDED = "device.added"
|
||||
DEVICE_UPDATED = "device.updated"
|
||||
DEVICE_DELETED = "device.deleted"
|
||||
DEVICE_CONNECTED = "device.connected"
|
||||
DEVICE_DISCONNECTED = "device.disconnected"
|
||||
|
||||
# 命令执行事件
|
||||
COMMAND_EXECUTED = "command.executed"
|
||||
COMMAND_FAILED = "command.failed"
|
||||
|
||||
# 权限事件
|
||||
PERMISSION_DENIED = "permission.denied"
|
||||
ROLE_CHANGED = "permission.role_changed"
|
||||
|
||||
# 系统事件
|
||||
SYSTEM_STARTED = "system.started"
|
||||
SYSTEM_STOPPED = "system.stopped"
|
||||
CONFIG_CHANGED = "system.config_changed"
|
||||
|
||||
class AuditLogger:
|
||||
"""安全审计日志记录器"""
|
||||
|
||||
def __init__(self, log_file: str = "logs/audit.log"):
|
||||
self.log_file = log_file
|
||||
self.sequence_number = 0
|
||||
|
||||
def log_event(self,
|
||||
event_type: AuditEventType,
|
||||
user_id: str = "anonymous",
|
||||
resource: str = None,
|
||||
action: str = None,
|
||||
result: str = "success",
|
||||
details: Dict[str, Any] = None,
|
||||
client_ip: str = None) -> str:
|
||||
"""记录审计事件"""
|
||||
|
||||
self.sequence_number += 1
|
||||
timestamp = datetime.utcnow()
|
||||
|
||||
# 构建审计记录
|
||||
audit_record = {
|
||||
"timestamp": timestamp.isoformat() + "Z",
|
||||
"sequence": self.sequence_number,
|
||||
"event_type": event_type.value,
|
||||
"user_id": user_id,
|
||||
"client_ip": client_ip,
|
||||
"resource": resource,
|
||||
"action": action,
|
||||
"result": result,
|
||||
"details": details or {},
|
||||
}
|
||||
|
||||
# 计算记录哈希(用于完整性验证)
|
||||
record_hash = self._calculate_hash(audit_record)
|
||||
audit_record["hash"] = record_hash
|
||||
|
||||
# 写入日志文件
|
||||
try:
|
||||
with open(self.log_file, 'a', encoding='utf-8') as f:
|
||||
f.write(json.dumps(audit_record, ensure_ascii=False) + '\n')
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to write audit log: {str(e)}")
|
||||
|
||||
return record_hash
|
||||
|
||||
def _calculate_hash(self, record: Dict[str, Any]) -> str:
|
||||
"""计算审计记录哈希"""
|
||||
# 创建用于哈希的记录副本(不包含hash字段)
|
||||
hash_record = {k: v for k, v in record.items() if k != "hash"}
|
||||
|
||||
# 序列化并计算哈希
|
||||
record_str = json.dumps(hash_record, sort_keys=True, ensure_ascii=False)
|
||||
return hashlib.sha256(record_str.encode('utf-8')).hexdigest()
|
||||
|
||||
def verify_log_integrity(self) -> bool:
|
||||
"""验证审计日志完整性"""
|
||||
try:
|
||||
with open(self.log_file, 'r', encoding='utf-8') as f:
|
||||
for line_num, line in enumerate(f, 1):
|
||||
if line.strip():
|
||||
record = json.loads(line.strip())
|
||||
stored_hash = record.get("hash")
|
||||
calculated_hash = self._calculate_hash(record)
|
||||
|
||||
if stored_hash != calculated_hash:
|
||||
logger.error(f"Audit log integrity violation at line {line_num}")
|
||||
return False
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to verify audit log integrity: {str(e)}")
|
||||
return False
|
||||
|
||||
# 全局审计日志器实例
|
||||
audit_logger = AuditLogger()
|
||||
|
||||
# 在MCP工具中集成审计日志
|
||||
@mcp.tool()
|
||||
async def add_device(...) -> Dict[str, Any]:
|
||||
"""添加设备"""
|
||||
user_id = get_current_user_id()
|
||||
client_ip = get_client_ip()
|
||||
|
||||
try:
|
||||
# 执行设备添加操作
|
||||
result = device_manager.add_device(device)
|
||||
|
||||
# 记录成功事件
|
||||
audit_logger.log_event(
|
||||
event_type=AuditEventType.DEVICE_ADDED,
|
||||
user_id=user_id,
|
||||
resource=f"device:{device.id}",
|
||||
action="add",
|
||||
result="success",
|
||||
details={"device_name": device.name, "ip_address": device.ip_address},
|
||||
client_ip=client_ip
|
||||
)
|
||||
|
||||
return {"success": True, "device_id": result}
|
||||
|
||||
except Exception as e:
|
||||
# 记录失败事件
|
||||
audit_logger.log_event(
|
||||
event_type=AuditEventType.DEVICE_ADDED,
|
||||
user_id=user_id,
|
||||
resource="device:unknown",
|
||||
action="add",
|
||||
result="failed",
|
||||
details={"error": str(e)},
|
||||
client_ip=client_ip
|
||||
)
|
||||
raise
|
||||
```
|
||||
|
||||
### 3.5 通信安全增强
|
||||
|
||||
#### 3.5.1 HTTPS/WSS支持计划
|
||||
|
||||
```python
|
||||
# 在server.py中添加SSL支持
|
||||
import ssl
|
||||
from pathlib import Path
|
||||
|
||||
class SecureServerConfig:
|
||||
"""安全服务器配置"""
|
||||
|
||||
def __init__(self):
|
||||
self.ssl_enabled = os.environ.get('NETBRAIN_SSL_ENABLED', 'false').lower() == 'true'
|
||||
self.ssl_cert_file = os.environ.get('NETBRAIN_SSL_CERT', 'certs/server.crt')
|
||||
self.ssl_key_file = os.environ.get('NETBRAIN_SSL_KEY', 'certs/server.key')
|
||||
self.ssl_ca_file = os.environ.get('NETBRAIN_SSL_CA', 'certs/ca.crt')
|
||||
|
||||
def create_ssl_context(self) -> ssl.SSLContext:
|
||||
"""创建SSL上下文"""
|
||||
if not self.ssl_enabled:
|
||||
return None
|
||||
|
||||
# 创建SSL上下文
|
||||
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
|
||||
# 加载证书和私钥
|
||||
context.load_cert_chain(self.ssl_cert_file, self.ssl_key_file)
|
||||
|
||||
# 如果有CA证书,启用客户端证书验证
|
||||
if Path(self.ssl_ca_file).exists():
|
||||
context.load_verify_locations(self.ssl_ca_file)
|
||||
context.verify_mode = ssl.CERT_REQUIRED
|
||||
|
||||
return context
|
||||
|
||||
# 启动安全服务器
|
||||
def start_secure_server():
|
||||
config = SecureServerConfig()
|
||||
ssl_context = config.create_ssl_context()
|
||||
|
||||
if ssl_context:
|
||||
logger.info("Starting secure MCP server with SSL/TLS")
|
||||
# 使用SSL上下文启动服务器
|
||||
else:
|
||||
logger.warning("Starting MCP server without SSL/TLS encryption")
|
||||
# 启动普通服务器
|
||||
```
|
||||
|
||||
## 4. 数据保护实现
|
||||
|
||||
### 4.1 敏感数据分类
|
||||
|
||||
根据实际代码分析,系统中的敏感数据包括:
|
||||
|
||||
#### 4.1.1 高敏感数据
|
||||
- **设备凭据**:username, password, enable_password
|
||||
- **SSH私钥**:ssh_key_file内容
|
||||
- **API密钥**:认证令牌和密钥
|
||||
|
||||
#### 4.1.2 中敏感数据
|
||||
- **设备配置**:网络设备配置信息
|
||||
- **网络拓扑**:网络架构和连接信息
|
||||
- **日志数据**:操作日志中的敏感信息
|
||||
|
||||
#### 4.1.3 低敏感数据
|
||||
- **设备元数据**:设备名称、IP地址、型号等
|
||||
- **系统状态**:系统运行状态信息
|
||||
- **公共模板**:通用提示模板内容
|
||||
|
||||
### 4.2 数据保护策略
|
||||
|
||||
#### 4.2.1 存储保护
|
||||
```python
|
||||
# 敏感字段标识
|
||||
SENSITIVE_FIELDS = {
|
||||
'password', 'enable_password', 'ssh_key', 'api_key',
|
||||
'secret_key', 'private_key', 'token'
|
||||
}
|
||||
|
||||
def mask_sensitive_data(data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""脱敏敏感数据用于日志和显示"""
|
||||
masked_data = data.copy()
|
||||
|
||||
for key, value in masked_data.items():
|
||||
if any(sensitive in key.lower() for sensitive in SENSITIVE_FIELDS):
|
||||
if value:
|
||||
masked_data[key] = "***MASKED***"
|
||||
|
||||
return masked_data
|
||||
```
|
||||
|
||||
#### 4.2.2 传输保护
|
||||
```python
|
||||
def secure_data_transfer(data: Any, encryption_key: bytes) -> str:
|
||||
"""安全数据传输加密"""
|
||||
# 序列化数据
|
||||
json_data = json.dumps(data, ensure_ascii=False)
|
||||
|
||||
# 加密传输
|
||||
encrypted_data = encrypt_data(json_data, encryption_key)
|
||||
|
||||
return encrypted_data
|
||||
```
|
||||
|
||||
## 5. 安全配置管理
|
||||
|
||||
### 5.1 安全配置文件
|
||||
|
||||
```yaml
|
||||
# config/security.yaml
|
||||
security:
|
||||
# 认证配置
|
||||
authentication:
|
||||
enabled: true
|
||||
method: "api_key" # api_key, jwt, oauth2
|
||||
api_key:
|
||||
header_name: "X-API-Key"
|
||||
require_https: false # 生产环境设为true
|
||||
key_length: 32
|
||||
default_expiration_days: 90
|
||||
|
||||
# 加密配置
|
||||
encryption:
|
||||
enabled: true
|
||||
algorithm: "aes-256-gcm"
|
||||
master_key_source: "environment" # environment, file, vault
|
||||
key_rotation_days: 365
|
||||
|
||||
# 审计配置
|
||||
audit:
|
||||
enabled: true
|
||||
log_file: "logs/audit.log"
|
||||
log_level: "INFO"
|
||||
include_sensitive_data: false
|
||||
retention_days: 365
|
||||
|
||||
# 访问控制配置
|
||||
access_control:
|
||||
default_role: "viewer"
|
||||
session_timeout_minutes: 30
|
||||
max_failed_attempts: 5
|
||||
lockout_duration_minutes: 15
|
||||
|
||||
# SSL/TLS配置
|
||||
ssl:
|
||||
enabled: false
|
||||
cert_file: "certs/server.crt"
|
||||
key_file: "certs/server.key"
|
||||
ca_file: "certs/ca.crt"
|
||||
require_client_cert: false
|
||||
```
|
||||
|
||||
### 5.2 安全最佳实践
|
||||
|
||||
#### 5.2.1 部署安全建议
|
||||
1. **文件权限**:设置适当的文件和目录权限
|
||||
```bash
|
||||
chmod 600 data/credentials.json
|
||||
chmod 700 data/
|
||||
chmod 600 config/security.yaml
|
||||
```
|
||||
|
||||
2. **环境变量**:使用环境变量管理敏感配置
|
||||
```bash
|
||||
export NETBRAIN_MASTER_KEY="your-secure-master-key"
|
||||
export NETBRAIN_AUTH_ENABLED="true"
|
||||
export NETBRAIN_SSL_ENABLED="true"
|
||||
```
|
||||
|
||||
3. **网络隔离**:部署在受保护的网络环境中
|
||||
- 使用防火墙限制访问
|
||||
- 部署在专用VLAN或子网
|
||||
- 限制出站网络连接
|
||||
|
||||
#### 5.2.2 运维安全建议
|
||||
1. **定期安全检查**
|
||||
- 审查API密钥和权限
|
||||
- 检查审计日志异常
|
||||
- 验证加密密钥轮换
|
||||
- 更新依赖包版本
|
||||
|
||||
2. **监控和告警**
|
||||
- 监控异常登录尝试
|
||||
- 监控权限提升操作
|
||||
- 监控敏感数据访问
|
||||
- 设置安全事件告警
|
||||
|
||||
3. **备份和恢复**
|
||||
- 定期备份加密数据
|
||||
- 测试数据恢复流程
|
||||
- 保护备份数据安全
|
||||
- 记录恢复操作
|
||||
|
||||
## 6. 安全测试计划
|
||||
|
||||
### 6.1 安全测试类型
|
||||
|
||||
#### 6.1.1 功能安全测试
|
||||
- 认证机制测试
|
||||
- 权限控制测试
|
||||
- 数据加密测试
|
||||
- 审计日志测试
|
||||
|
||||
#### 6.1.2 安全漏洞测试
|
||||
- 输入验证测试
|
||||
- 权限绕过测试
|
||||
- 数据泄露测试
|
||||
- 注入攻击测试
|
||||
|
||||
#### 6.1.3 渗透测试
|
||||
- 外部渗透测试
|
||||
- 内部渗透测试
|
||||
- 社会工程测试
|
||||
- 物理安全测试
|
||||
|
||||
### 6.2 安全测试实施
|
||||
|
||||
```python
|
||||
# tests/security/test_authentication.py
|
||||
import pytest
|
||||
from security.api_auth import APIKeyManager, MCPAuthMiddleware
|
||||
|
||||
class TestAuthentication:
|
||||
def setup_method(self):
|
||||
self.api_key_manager = APIKeyManager()
|
||||
self.auth_middleware = MCPAuthMiddleware(self.api_key_manager)
|
||||
|
||||
def test_api_key_generation(self):
|
||||
"""测试API密钥生成"""
|
||||
key = self.api_key_manager.generate_api_key("test_user")
|
||||
assert len(key) > 0
|
||||
assert self.api_key_manager.validate_api_key(key) is not None
|
||||
|
||||
def test_invalid_api_key(self):
|
||||
"""测试无效API密钥"""
|
||||
assert self.api_key_manager.validate_api_key("invalid_key") is None
|
||||
|
||||
def test_expired_api_key(self):
|
||||
"""测试过期API密钥"""
|
||||
# 实现过期密钥测试...
|
||||
pass
|
||||
|
||||
# tests/security/test_encryption.py
|
||||
class TestEncryption:
|
||||
def test_credential_encryption(self):
|
||||
"""测试凭据加密"""
|
||||
from security.encryption import SecureCredentialStorage
|
||||
|
||||
storage = SecureCredentialStorage("test_key")
|
||||
original_password = "secret123"
|
||||
|
||||
# 加密
|
||||
encrypted = storage.encrypt_credential(original_password)
|
||||
assert encrypted != original_password
|
||||
assert encrypted.startswith("aes256gcm:")
|
||||
|
||||
# 解密
|
||||
decrypted = storage.decrypt_credential(encrypted)
|
||||
assert decrypted == original_password
|
||||
```
|
||||
|
||||
## 7. 实施时间表
|
||||
|
||||
### 7.1 短期实施(1-2个月)
|
||||
- [x] **基础日志审计**:已实现完整的操作日志记录
|
||||
- [ ] **凭据加密存储**:实现AES-256-GCM加密
|
||||
- [ ] **API密钥认证**:基础API密钥认证机制
|
||||
- [ ] **基础权限控制**:实现角色基础权限检查
|
||||
|
||||
### 7.2 中期实施(3-6个月)
|
||||
- [ ] **SSL/TLS支持**:HTTPS和WSS加密通信
|
||||
- [ ] **细粒度权限**:完整的RBAC权限系统
|
||||
- [ ] **安全审计增强**:完整的安全事件审计
|
||||
- [ ] **密钥轮换**:自动密钥轮换机制
|
||||
|
||||
### 7.3 长期实施(6-12个月)
|
||||
- [ ] **OAuth2集成**:企业身份认证集成
|
||||
- [ ] **安全监控**:实时安全监控和告警
|
||||
- [ ] **端到端加密**:客户端到服务器端到端加密
|
||||
- [ ] **安全认证**:第三方安全认证和合规
|
||||
|
||||
---
|
||||
|
||||
NetBrain MCP系统的安全设计兼顾了当前实际实现状态和未来安全增强需求。通过分阶段实施安全措施,系统将逐步达到企业级安全标准,为网络运维提供安全可靠的AI驱动平台。
|
||||
@@ -0,0 +1,618 @@
|
||||
# NetBrain MCP 系统架构设计
|
||||
|
||||
## 1. 整体架构
|
||||
|
||||
NetBrain MCP是一个通过MCP协议连接大型语言模型与网络设备的平台。系统采用模块化设计,基于FastMCP框架实现,主要由以下几个核心部分组成:
|
||||
|
||||
```
|
||||
+------------------+
|
||||
| 客户端 |
|
||||
| (Claude/Cursor) |
|
||||
+--------+---------+
|
||||
|
|
||||
| MCP 协议 (FastMCP)
|
||||
|
|
||||
+----------------------------v-----------------------------+
|
||||
| NetBrain MCP |
|
||||
| (server.py) |
|
||||
| |
|
||||
| +----------------+ +----------------+ +---------+ |
|
||||
| | MCP服务器模块 |<->| 工具管理模块 |<->| 资源模块 | |
|
||||
| | (FastMCP) | | (tool_manager) | |(mcp_res) | |
|
||||
| +----------------+ +----------------+ +---------+ |
|
||||
| ^ ^ ^ |
|
||||
| | | | |
|
||||
| v v v |
|
||||
| +----------------+ +----------------+ +---------+ |
|
||||
| | 设备管理模块 |<->| 设备连接模块 |<->| 模板系统 | |
|
||||
| |(network_devices)| |(device_connector)| |(template)| |
|
||||
| +----------------+ +----------------+ +---------+ |
|
||||
| ^ ^ |
|
||||
| | | |
|
||||
| v v |
|
||||
| +----------------+ +----------------+ |
|
||||
| | 拓扑发现模块 |<->| 网络扫描模块 | |
|
||||
| |(topology_disc) | |(network_scanner)| |
|
||||
| +----------------+ +----------------+ |
|
||||
+-------------------------------------------------------- +
|
||||
|
|
||||
| Scrapli (SSH/Telnet/混合模式)
|
||||
|
|
||||
+--------v---------+
|
||||
| 网络设备 |
|
||||
| (多厂商支持) |
|
||||
+------------------+
|
||||
```
|
||||
|
||||
## 2. 核心模块说明
|
||||
|
||||
### 2.1 MCP服务器模块 (server.py)
|
||||
|
||||
MCP服务器模块是整个系统的核心,基于FastMCP框架实现,负责处理来自大型语言模型(如Claude、GPT等)的请求,并将请求路由到相应的工具或资源处理器。
|
||||
|
||||
**主要功能:**
|
||||
- 实现FastMCP协议的服务器端(32个工具,13个资源,13个模板)
|
||||
- 处理工具调用和资源请求
|
||||
- 管理会话和上下文
|
||||
- 提供服务器配置和日志记录
|
||||
|
||||
**核心组件:**
|
||||
- FastMCP服务器实例
|
||||
- 工具注册装饰器 `@mcp.tool()`
|
||||
- 资源处理器 `@mcp.resource("{uri}")`
|
||||
- 提示模板处理器 `@mcp.prompt("{name}")`
|
||||
|
||||
**实际实现状态:** ✅ 已完成,包含所有32个工具实现
|
||||
|
||||
### 2.2 工具管理模块 (tool_manager.py)
|
||||
|
||||
工具管理模块负责工具的注册、管理和分类,虽然MCP工具直接通过FastMCP注册,但该模块提供了工具的分类和管理功能。
|
||||
|
||||
**主要功能:**
|
||||
- 工具注册和分类管理(6个分类)
|
||||
- 工具执行和错误处理
|
||||
- 工具元数据管理
|
||||
|
||||
**核心组件:**
|
||||
- ToolManager类:管理所有工具
|
||||
- ToolCategory枚举:工具分类(general, network_device, configuration, topology, diagnostic, security)
|
||||
- ToolInfo数据类:工具元数据
|
||||
|
||||
**实际实现状态:** ✅ 已完成,支持32个MCP工具的分类管理
|
||||
|
||||
### 2.3 资源模块 (mcp_resources.py)
|
||||
|
||||
资源模块负责管理和提供各种网络资源,包括设备信息、配置数据、拓扑数据等。
|
||||
|
||||
**主要功能:**
|
||||
- 资源注册和管理(13个MCP资源)
|
||||
- 资源缓存和刷新(内存+文件双层缓存)
|
||||
- URI模式匹配和参数提取
|
||||
|
||||
**核心组件:**
|
||||
- ResourceManager类:管理资源
|
||||
- ResourceType类:资源类型定义(device, credential, topology, system, config, scan等)
|
||||
- 缓存机制:默认5分钟TTL,支持文件持久化
|
||||
|
||||
**实际实现状态:** ✅ 已完成,实现13个MCP资源
|
||||
|
||||
### 2.4 设备管理模块 (network_devices.py)
|
||||
|
||||
设备管理模块负责网络设备的生命周期管理,包括设备的添加、查询、更新和删除。
|
||||
|
||||
**主要功能:**
|
||||
- 设备信息管理(支持多厂商:cisco, huawei, h3c, juniper等)
|
||||
- 设备凭据管理(SSH/Telnet/SNMP等协议)
|
||||
- 设备状态监控
|
||||
- JSON文件持久化存储
|
||||
|
||||
**核心组件:**
|
||||
- DeviceManager类:设备管理器
|
||||
- NetworkDevice类:设备数据模型(包含platform字段支持Scrapli)
|
||||
- DeviceCredential类:设备凭据模型
|
||||
- 枚举类:DeviceType, DeviceVendor, DeviceStatus, ConnectionProtocol
|
||||
|
||||
**实际实现状态:** ✅ 已完成,支持完整的设备生命周期管理
|
||||
|
||||
### 2.5 设备连接模块 (device_connector.py)
|
||||
|
||||
设备连接模块负责与网络设备建立连接并执行命令,基于Scrapli库实现混合异步/同步模式。
|
||||
|
||||
**主要功能:**
|
||||
- 设备连接管理(基于Scrapli混合模式)
|
||||
- 命令执行和结果处理
|
||||
- 连接池管理和自动重连
|
||||
- 多协议支持(SSH/Telnet)
|
||||
|
||||
**核心组件:**
|
||||
- ConnectionManager类:连接管理器
|
||||
- ScrapliConnector类:主要连接器实现(支持异步/同步混合)
|
||||
- DeviceConnector抽象类:连接器接口
|
||||
- CommandResult类:命令执行结果
|
||||
|
||||
**技术特色:**
|
||||
- 混合异步/同步模式:智能检测连接对象类型,自动选择异步或同步调用方式
|
||||
- 平台自适应:根据设备厂商自动选择合适的Scrapli驱动
|
||||
- 自动重连机制:连接断开时自动重连并重试命令
|
||||
|
||||
**实际实现状态:** ✅ 已完成,支持思科、华为等多厂商设备
|
||||
|
||||
### 2.6 模板系统 (template_system.py + device_prompts.py)
|
||||
|
||||
模板系统负责管理和渲染各种提示和命令模板,提高系统的灵活性和扩展性。
|
||||
|
||||
**主要功能:**
|
||||
- 提示模板管理(13个专业模板)
|
||||
- 模板渲染和上下文处理
|
||||
- 消息模型支持(System, User, Assistant)
|
||||
- 资源集成渲染
|
||||
|
||||
**核心组件:**
|
||||
- TemplateManager类:高级提示模板管理器
|
||||
- Message模型:结构化消息格式
|
||||
- 模板函数:支持字符串和消息列表两种返回格式
|
||||
- 资源集成函数:`render_template_with_resources`
|
||||
|
||||
**模板分布:**
|
||||
- template_system.py:8个通用模板
|
||||
- device_prompts.py:5个设备专用模板
|
||||
|
||||
**实际实现状态:** ✅ 已完成,实现13个专业网络运维模板
|
||||
|
||||
### 2.7 拓扑发现模块 (topology_discovery_improved.py)
|
||||
|
||||
拓扑发现模块负责自动发现和维护网络拓扑,基于CDP/LLDP协议实现。
|
||||
|
||||
**主要功能:**
|
||||
- 基于CDP/LLDP的拓扑发现
|
||||
- 多厂商设备邻居发现适配
|
||||
- 拓扑数据模型维护
|
||||
- 智能拓扑构建算法
|
||||
|
||||
**核心组件:**
|
||||
- ImprovedTopologyDiscovery类:改进的拓扑发现引擎
|
||||
- NetworkTopology类:拓扑数据模型
|
||||
- 厂商适配方法:discover_cisco_neighbors, discover_huawei_neighbors等
|
||||
|
||||
**实际实现状态:** ✅ 已完成,支持自动拓扑发现
|
||||
|
||||
### 2.8 网络扫描模块 (network_scanner.py)
|
||||
|
||||
网络扫描模块负责网络范围扫描和设备识别功能。
|
||||
|
||||
**主要功能:**
|
||||
- 网络范围扫描(ping检测、端口扫描)
|
||||
- 厂商MAC地址识别
|
||||
- SNMP设备发现
|
||||
- 扫描结果分析和设备推荐
|
||||
|
||||
**核心组件:**
|
||||
- ImprovedNetworkScanner类:网络扫描引擎
|
||||
- 并发扫描机制:支持可配置的并发数
|
||||
- 厂商识别:内置厂商MAC地址数据库
|
||||
|
||||
**实际实现状态:** ✅ 已完成,支持智能网络扫描
|
||||
|
||||
## 3. 数据模型
|
||||
|
||||
### 3.1 实际数据存储架构
|
||||
|
||||
系统采用JSON文件存储架构,具体结构如下:
|
||||
|
||||
```
|
||||
NetBrainMCP/
|
||||
├── data/ # 主数据存储目录
|
||||
│ ├── devices.json # 设备信息(NetworkDevice对象序列化)
|
||||
│ └── credentials.json # 凭据信息(DeviceCredential对象序列化,包含敏感信息)
|
||||
├── resource_cache/ # 资源缓存目录
|
||||
│ └── *.json # 缓存文件(按URI哈希命名)
|
||||
├── templates/ # 模板缓存目录
|
||||
│ └── *.json # 模板元数据文件
|
||||
└── logs/ # 日志文件目录
|
||||
├── netbrain_mcp.log # 主日志
|
||||
├── device_connector.log # 连接日志
|
||||
└── audit.log # 审计日志
|
||||
```
|
||||
|
||||
### 3.2 核心数据实体关系
|
||||
|
||||
```
|
||||
NetworkDevice (network_devices.py)
|
||||
├── id: str (UUID)
|
||||
├── name: str
|
||||
├── ip_address: str
|
||||
├── device_type: DeviceType (enum)
|
||||
├── vendor: DeviceVendor (enum)
|
||||
├── platform: str (Scrapli平台类型)
|
||||
├── model: str
|
||||
├── os_version: str
|
||||
├── status: DeviceStatus (enum)
|
||||
├── credential_id: str (关联DeviceCredential)
|
||||
├── tags: List[str]
|
||||
└── custom_attributes: Dict[str, Any]
|
||||
|
||||
DeviceCredential (network_devices.py)
|
||||
├── id: str (UUID)
|
||||
├── name: str
|
||||
├── username: str
|
||||
├── password: str (明文存储,生产环境应加密)
|
||||
├── protocol: ConnectionProtocol (enum)
|
||||
├── port: int
|
||||
├── enable_password: str
|
||||
└── ssh_key_file: str
|
||||
|
||||
ConnectionManager (device_connector.py)
|
||||
├── active_connections: Dict[str, DeviceConnector]
|
||||
└── ScrapliConnector instances
|
||||
```
|
||||
|
||||
## 4. 接口设计
|
||||
|
||||
### 4.1 实际MCP工具接口
|
||||
|
||||
系统通过FastMCP协议提供以下32个工具:
|
||||
|
||||
#### 设备管理工具 (6个)
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def list_devices(vendor, device_type, status, tag) -> List[Dict[str, Any]]
|
||||
|
||||
@mcp.tool()
|
||||
async def add_device(name, ip_address, device_type, vendor, platform, ...) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_device(device_id) -> Optional[Dict[str, Any]]
|
||||
|
||||
@mcp.tool()
|
||||
async def update_device(device_id, **kwargs) -> Optional[Dict[str, Any]]
|
||||
|
||||
@mcp.tool()
|
||||
async def delete_device(device_id) -> bool
|
||||
```
|
||||
|
||||
#### 连接管理工具 (5个)
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def connect_device(device_id, credential_id) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def disconnect_device(device_id, credential_id) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def send_command(device_id, credential_id, command, timeout) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def send_commands(device_id, credential_id, commands, timeout) -> List[Dict[str, Any]]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_active_connections() -> List[Dict[str, Any]]
|
||||
```
|
||||
|
||||
#### 拓扑发现工具 (6个)
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def discover_topology(device_ids) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_topology() -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def clear_topology() -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_device_neighbors(device_id) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def discover_device_neighbors(device_id) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_topology_statistics() -> Dict[str, Any]
|
||||
```
|
||||
|
||||
#### 网络扫描工具 (6个)
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def scan_network_range(network, timeout, max_concurrent, ...) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_scan_results(ip_address, alive_only) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def get_scan_statistics() -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def discover_devices_from_scan_results(...) -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def clear_scan_results() -> Dict[str, Any]
|
||||
|
||||
@mcp.tool()
|
||||
async def scan_single_host(ip_address, timeout, ...) -> Dict[str, Any]
|
||||
```
|
||||
|
||||
#### 其他工具 (9个)
|
||||
- 凭据管理:2个
|
||||
- 资源管理:3个
|
||||
- 模板管理:2个
|
||||
- 测试工具:2个
|
||||
|
||||
### 4.2 实际MCP资源接口
|
||||
|
||||
系统提供以下13个MCP资源:
|
||||
|
||||
```python
|
||||
# 设备相关资源 (5个)
|
||||
@resource_manager.register_resource("device/{device_id}", ResourceType.DEVICE)
|
||||
@resource_manager.register_resource("device/{device_id}/config", ResourceType.CONFIG)
|
||||
@resource_manager.register_resource("device/{device_id}/interfaces", ResourceType.DEVICE)
|
||||
@resource_manager.register_resource("device/{device_id}/routes", ResourceType.DEVICE)
|
||||
@resource_manager.register_resource("device/{device_id}/neighbors", ResourceType.TOPOLOGY)
|
||||
|
||||
# 系统资源 (4个)
|
||||
@resource_manager.register_resource("greeting/{name}", ResourceType.SYSTEM)
|
||||
@resource_manager.register_resource("credentials", ResourceType.CREDENTIAL)
|
||||
@resource_manager.register_resource("system/status", ResourceType.SYSTEM)
|
||||
@resource_manager.register_resource("topology", ResourceType.TOPOLOGY)
|
||||
|
||||
# 拓扑资源 (1个)
|
||||
@resource_manager.register_resource("topology/statistics", ResourceType.TOPOLOGY)
|
||||
|
||||
# 扫描资源 (3个)
|
||||
@resource_manager.register_resource("scan/results", ResourceType.SCAN)
|
||||
@resource_manager.register_resource("scan/statistics", ResourceType.SCAN)
|
||||
@resource_manager.register_resource("scan/result/{ip_address}", ResourceType.SCAN)
|
||||
```
|
||||
|
||||
## 5. 安全设计
|
||||
|
||||
### 5.1 当前安全实现状态
|
||||
|
||||
**已实现的安全措施:**
|
||||
- 日志记录:完整的操作日志和审计跟踪
|
||||
- 凭据存储:JSON文件存储(明文,需要加密改进)
|
||||
- 连接安全:基于SSH/Telnet的设备连接
|
||||
- 输入验证:工具参数验证和类型检查
|
||||
|
||||
**待实现的安全措施:**
|
||||
- 凭据加密:计划实现AES-256加密存储
|
||||
- 访问控制:计划实现基于角色的权限管理
|
||||
- 传输加密:计划支持HTTPS/WSS
|
||||
- API认证:计划实现API密钥认证
|
||||
|
||||
### 5.2 数据安全
|
||||
|
||||
当前数据保护措施:
|
||||
- 敏感数据标识:明确识别设备凭据等敏感信息
|
||||
- 日志脱敏:避免在日志中记录明文密码
|
||||
- 文件权限:建议设置适当的文件系统权限
|
||||
|
||||
## 6. 扩展性设计
|
||||
|
||||
### 6.1 模块化架构
|
||||
|
||||
系统采用高度模块化的设计:
|
||||
- **独立模块**:每个模块都有明确的职责和接口
|
||||
- **装饰器模式**:工具、资源、模板均通过装饰器注册
|
||||
- **抽象接口**:DeviceConnector抽象基类支持多种连接器实现
|
||||
- **工厂模式**:ConnectorFactory根据设备类型创建合适的连接器
|
||||
|
||||
### 6.2 多厂商支持
|
||||
|
||||
**已支持的厂商:**
|
||||
- Cisco:IOS, IOS-XE, NX-OS
|
||||
- Huawei:VRP系统
|
||||
- H3C:Comware系统
|
||||
- Juniper:JUNOS系统
|
||||
- Arista:EOS系统
|
||||
|
||||
**扩展机制:**
|
||||
- Scrapli平台适配:通过platform字段指定驱动类型
|
||||
- 命令模板适配:针对不同厂商的命令差异进行适配
|
||||
- 邻居发现适配:为不同厂商实现专用的邻居发现方法
|
||||
|
||||
### 6.3 协议支持
|
||||
|
||||
**当前支持的协议:**
|
||||
- SSH:主要连接协议,支持密钥和密码认证
|
||||
- Telnet:备用连接协议
|
||||
- SNMP:计划支持
|
||||
- NETCONF:计划支持
|
||||
|
||||
## 7. 部署架构
|
||||
|
||||
### 7.1 单机部署(当前实现)
|
||||
|
||||
适用于小型网络环境和开发测试:
|
||||
|
||||
```
|
||||
+-----------------+
|
||||
| NetBrain MCP |
|
||||
| Python应用 |
|
||||
| FastMCP服务器 |
|
||||
| JSON文件存储 |
|
||||
+-----------------+
|
||||
|
|
||||
| Scrapli
|
||||
|
|
||||
+-------v-------+
|
||||
| 网络设备 |
|
||||
| (多厂商) |
|
||||
+--------------+
|
||||
```
|
||||
|
||||
**部署要求:**
|
||||
- Python 3.10+
|
||||
- 依赖包:scrapli, mcp, fastapi等
|
||||
- 网络访问:能够SSH/Telnet到目标设备
|
||||
|
||||
### 7.2 容器化部署(计划)
|
||||
|
||||
支持Docker容器化部署:
|
||||
|
||||
```
|
||||
+------------------+
|
||||
| Docker容器 |
|
||||
| ├── NetBrain MCP |
|
||||
| ├── Python环境 |
|
||||
| └── 数据卷 |
|
||||
+------------------+
|
||||
```
|
||||
|
||||
### 7.3 分布式部署(未来规划)
|
||||
|
||||
适用于大型网络环境:
|
||||
|
||||
```
|
||||
+-------------+ +-------------+ +-------------+
|
||||
| MCP API服务 |--->| 设备管理服务 |--->| 数据库服务 |
|
||||
+-------------+ +-------------+ +-------------+
|
||||
^ ^
|
||||
| |
|
||||
v v
|
||||
+-------------+ +-------------+
|
||||
| 拓扑服务 |<-->| 扫描服务 |
|
||||
+-------------+ +-------------+
|
||||
```
|
||||
|
||||
## 8. 技术栈
|
||||
|
||||
### 8.1 实际技术栈
|
||||
|
||||
**核心框架:**
|
||||
- **MCP框架**:FastMCP(基于mcp Python包)
|
||||
- **异步框架**:asyncio
|
||||
- **设备连接**:Scrapli(支持异步/同步混合模式)
|
||||
|
||||
**编程语言:**
|
||||
- **Python**:3.10+
|
||||
- **类型提示**:完整的类型注解支持
|
||||
|
||||
**数据存储:**
|
||||
- **文件存储**:JSON格式
|
||||
- **缓存**:内存缓存 + 文件缓存
|
||||
- **数据持久化**:自动加载和保存机制
|
||||
|
||||
**网络协议:**
|
||||
- **SSH**:asyncssh(异步)/ paramiko(同步)
|
||||
- **Telnet**:telnetlib3
|
||||
- **其他**:计划支持SNMP、NETCONF
|
||||
|
||||
**日志系统:**
|
||||
- **日志框架**:Python logging
|
||||
- **格式化**:JsonFormatter支持UTF-8
|
||||
- **文件管理**:日志轮转和归档
|
||||
|
||||
### 8.2 依赖包版本
|
||||
|
||||
根据requirements.txt:
|
||||
```
|
||||
scrapli>=2025.1.30 # 网络设备连接
|
||||
mcp # MCP协议支持
|
||||
fastapi # Web框架(Web界面)
|
||||
asyncio # 异步支持
|
||||
jinja2 # 模板引擎
|
||||
pydantic # 数据验证
|
||||
websockets # WebSocket支持
|
||||
```
|
||||
|
||||
## 9. 性能特征
|
||||
|
||||
### 9.1 并发性能
|
||||
|
||||
**异步架构优势:**
|
||||
- 全异步设计,支持高并发操作
|
||||
- 混合异步/同步模式,兼容不同类型的连接器
|
||||
- 连接池管理,减少连接开销
|
||||
|
||||
**性能指标:**
|
||||
- 并发连接:支持多设备同时连接
|
||||
- 命令执行:支持批量命令并发执行
|
||||
- 资源缓存:5分钟默认TTL,减少重复获取
|
||||
|
||||
### 9.2 内存管理
|
||||
|
||||
**缓存策略:**
|
||||
- 资源缓存:内存 + 文件双层缓存
|
||||
- 连接缓存:活动连接池管理
|
||||
- 模板缓存:编译后的模板缓存
|
||||
|
||||
**内存优化:**
|
||||
- 按需加载:资源和连接按需创建
|
||||
- 自动清理:过期缓存自动清理
|
||||
- 连接管理:空闲连接自动断开
|
||||
|
||||
## 10. 开发路线图
|
||||
|
||||
### 10.1 已完成阶段 ✅
|
||||
|
||||
**阶段一:MCP协议实现与基础框架**
|
||||
- [x] FastMCP服务器架构
|
||||
- [x] 32个MCP工具实现
|
||||
- [x] 13个MCP资源实现
|
||||
- [x] 基础架构设计
|
||||
|
||||
**阶段二:网络设备管理**
|
||||
- [x] 基于Scrapli的设备连接引擎
|
||||
- [x] 多厂商设备支持
|
||||
- [x] 设备认证管理系统
|
||||
- [x] JSON文件数据存储
|
||||
|
||||
**阶段三:配置管理与MCP增强**
|
||||
- [x] 13个提示模板系统
|
||||
- [x] 资源缓存机制
|
||||
- [x] 拓扑发现功能
|
||||
- [x] 网络扫描功能
|
||||
|
||||
**阶段四:测试与文档**
|
||||
- [x] 系统功能测试
|
||||
- [x] 技术文档编写
|
||||
- [x] 用户操作指南
|
||||
|
||||
### 10.2 当前系统状态
|
||||
|
||||
**项目状态:✅ 已完成所有计划功能**
|
||||
|
||||
**核心功能完成度:**
|
||||
- MCP协议实现:100%
|
||||
- 设备管理功能:100%
|
||||
- 连接管理功能:100%
|
||||
- 拓扑发现功能:100%
|
||||
- 网络扫描功能:100%
|
||||
- 模板系统:100%
|
||||
- 资源系统:100%
|
||||
|
||||
**生产就绪状态:**
|
||||
- 功能完整性:✅ 完成
|
||||
- 稳定性测试:✅ 完成
|
||||
- 文档完善:✅ 完成
|
||||
- 部署准备:✅ 完成
|
||||
|
||||
### 10.3 未来增强方向
|
||||
|
||||
**安全增强:**
|
||||
- [ ] 凭据加密存储
|
||||
- [ ] 基于角色的访问控制
|
||||
- [ ] API认证机制
|
||||
- [ ] 审计日志增强
|
||||
|
||||
**性能优化:**
|
||||
- [ ] 数据库支持(SQLite/PostgreSQL)
|
||||
- [ ] 分布式架构支持
|
||||
- [ ] 缓存优化策略
|
||||
- [ ] 连接池调优
|
||||
|
||||
**功能扩展:**
|
||||
- [ ] Web管理界面增强
|
||||
- [ ] 更多厂商设备支持
|
||||
- [ ] 高级网络分析功能
|
||||
- [ ] 监控告警系统
|
||||
|
||||
**集成能力:**
|
||||
- [ ] 第三方API集成
|
||||
- [ ] 企业身份认证集成
|
||||
- [ ] 监控系统集成
|
||||
- [ ] 配置管理平台集成
|
||||
|
||||
---
|
||||
|
||||
NetBrain MCP系统已成功完成所有预定目标,具备生产环境部署条件。系统架构设计合理,技术栈成熟稳定,功能完整丰富,为AI驱动的网络运维提供了强大的基础平台。
|
||||
@@ -0,0 +1,657 @@
|
||||
# NetBrain MCP 用户操作指南
|
||||
|
||||
本文档是NetBrain MCP系统的完整用户操作指南,将指导您从安装配置到高级功能使用的全过程。
|
||||
|
||||
## 1. 项目简介
|
||||
|
||||
### 1.1 什么是NetBrain MCP?
|
||||
|
||||
NetBrain MCP(Model Context Protocol)是一个开源的网络运维整合平台,通过MCP协议连接大型语言模型(LLM)与网络设备。它允许AI助手通过标准化协议执行网络配置、诊断和管理任务。
|
||||
|
||||
### 1.2 核心功能
|
||||
|
||||
#### 🔧 设备管理功能
|
||||
- **统一设备管理**:支持思科、华为、H3C、Juniper等主流厂商设备
|
||||
- **多协议连接**:支持SSH、Telnet、SNMP等连接协议
|
||||
- **凭据安全管理**:加密存储设备访问凭据
|
||||
- **设备状态监控**:实时监控设备连接状态
|
||||
|
||||
#### 🌐 网络操作功能
|
||||
- **命令执行**:远程执行网络设备命令
|
||||
- **配置管理**:设备配置备份、比较和部署
|
||||
- **拓扑发现**:基于CDP/LLDP的自动拓扑发现
|
||||
- **网络扫描**:网络范围扫描和设备识别
|
||||
|
||||
#### 🤖 AI集成功能
|
||||
- **32个MCP工具**:涵盖设备管理、连接控制、拓扑分析等
|
||||
- **13个MCP资源**:提供设备信息、配置数据、拓扑数据等
|
||||
- **13个提示模板**:专业的网络诊断和配置模板
|
||||
- **智能诊断**:AI驱动的网络问题分析和解决方案
|
||||
|
||||
#### 💻 Web界面功能
|
||||
- **专业终端**:基于XTerm.js的多标签页终端体验
|
||||
- **拓扑可视化**:基于D3.js的交互式网络拓扑图
|
||||
- **设备管理界面**:直观的设备添加、编辑和监控界面
|
||||
- **主题系统**:支持暗色/明亮主题切换
|
||||
|
||||
## 2. 系统要求
|
||||
|
||||
### 2.1 硬件要求
|
||||
- **CPU**:2核心以上
|
||||
- **内存**:4GB以上
|
||||
- **存储**:10GB可用空间
|
||||
- **网络**:能够访问目标网络设备
|
||||
|
||||
### 2.2 软件要求
|
||||
- **操作系统**:Windows 10+、Linux、macOS
|
||||
- **Python版本**:Python 3.10或更高版本
|
||||
- **网络访问**:SSH/Telnet访问目标设备的权限
|
||||
|
||||
### 2.3 支持的设备
|
||||
- **思科设备**:IOS、IOS-XE、NX-OS
|
||||
- **华为设备**:VRP系统
|
||||
- **H3C设备**:Comware系统
|
||||
- **Juniper设备**:JUNOS系统
|
||||
- **其他厂商**:支持标准SSH/Telnet协议的设备
|
||||
|
||||
## 3. 安装和配置
|
||||
|
||||
### 3.1 获取项目代码
|
||||
|
||||
```bash
|
||||
# 克隆项目(假设从Git仓库)
|
||||
git clone https://github.com/your-org/NetBrainMCP.git
|
||||
cd NetBrainMCP
|
||||
|
||||
# 或者下载项目压缩包并解压
|
||||
# wget https://github.com/your-org/NetBrainMCP/archive/main.zip
|
||||
# unzip main.zip
|
||||
# cd NetBrainMCP-main
|
||||
```
|
||||
|
||||
### 3.2 创建Python虚拟环境
|
||||
|
||||
```bash
|
||||
# 创建虚拟环境
|
||||
python -m venv venv
|
||||
|
||||
# 激活虚拟环境
|
||||
# Windows:
|
||||
venv\Scripts\activate
|
||||
# Linux/macOS:
|
||||
source venv/bin/activate
|
||||
```
|
||||
|
||||
### 3.3 安装依赖
|
||||
|
||||
```bash
|
||||
# 安装项目依赖
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 验证关键依赖安装
|
||||
python -c "import scrapli; print('Scrapli版本:', scrapli.__version__)"
|
||||
python -c "import mcp; print('MCP已安装')"
|
||||
```
|
||||
|
||||
### 3.4 配置环境变量(可选)
|
||||
|
||||
```bash
|
||||
# 设置日志级别
|
||||
export LOG_LEVEL=INFO
|
||||
|
||||
# 设置数据目录
|
||||
export DATA_DIR=./data
|
||||
|
||||
# 设置加密密钥(用于凭据加密)
|
||||
export ENCRYPTION_KEY=your-secret-key
|
||||
```
|
||||
|
||||
## 4. 快速开始
|
||||
|
||||
### 4.1 启动MCP服务器
|
||||
|
||||
```bash
|
||||
# 启动MCP服务器(标准输入输出模式)
|
||||
python server.py
|
||||
|
||||
# 或启动Web服务器模式
|
||||
python server.py --web
|
||||
```
|
||||
|
||||
### 4.2 连接到Claude Desktop
|
||||
|
||||
1. **安装Claude Desktop**
|
||||
- 从 https://claude.ai/download 下载并安装Claude Desktop
|
||||
|
||||
2. **配置MCP服务器**
|
||||
|
||||
编辑Claude Desktop配置文件:
|
||||
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
||||
|
||||
添加配置:
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"netbrain-mcp": {
|
||||
"command": "python",
|
||||
"args": ["/path/to/NetBrainMCP/server.py"],
|
||||
"env": {
|
||||
"LOG_LEVEL": "INFO"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **重启Claude Desktop**
|
||||
- 重启Claude Desktop,您将看到工具图标,表示MCP服务器已连接
|
||||
|
||||
### 4.3 连接到Cursor IDE
|
||||
|
||||
1. **启动SSE模式**
|
||||
```bash
|
||||
python server.py --mode sse --port 8000
|
||||
```
|
||||
|
||||
2. **配置Cursor**
|
||||
- 打开Cursor → 设置 → 功能 → MCP服务器
|
||||
- 添加新服务器:
|
||||
- **名称**: netbrain-mcp
|
||||
- **类型**: sse
|
||||
- **URL**: http://localhost:8000/sse
|
||||
|
||||
## 5. 基本操作指南
|
||||
|
||||
### 5.1 设备管理
|
||||
|
||||
#### 添加设备凭据
|
||||
|
||||
首先添加设备访问凭据:
|
||||
|
||||
```
|
||||
# 在Claude或Cursor中输入:
|
||||
请帮我添加一个思科设备的SSH凭据,用户名是admin,密码是cisco123
|
||||
```
|
||||
|
||||
AI将调用`add_credential`工具:
|
||||
- 用户名:admin
|
||||
- 密码:cisco123
|
||||
- 协议:ssh
|
||||
- 端口:22
|
||||
|
||||
#### 添加网络设备
|
||||
|
||||
```
|
||||
# 添加思科路由器
|
||||
请添加一台思科路由器,名称是Router-01,IP地址是192.168.1.1,使用刚才添加的凭据
|
||||
```
|
||||
|
||||
AI将调用`add_device`工具添加设备。
|
||||
|
||||
#### 查看设备列表
|
||||
|
||||
```
|
||||
显示所有网络设备的列表
|
||||
```
|
||||
|
||||
AI将调用`list_devices`工具显示所有已添加的设备。
|
||||
|
||||
### 5.2 设备连接和命令执行
|
||||
|
||||
#### 连接到设备
|
||||
|
||||
```
|
||||
请连接到Router-01设备
|
||||
```
|
||||
|
||||
AI将调用`connect_device`工具建立与设备的连接。
|
||||
|
||||
#### 执行命令
|
||||
|
||||
```
|
||||
# 查看设备版本信息
|
||||
在Router-01上执行 show version 命令
|
||||
|
||||
# 查看接口状态
|
||||
在Router-01上执行 show ip interface brief 命令
|
||||
|
||||
# 执行多个命令
|
||||
在Router-01上依次执行以下命令:
|
||||
1. show running-config
|
||||
2. show ip route
|
||||
3. show interface status
|
||||
```
|
||||
|
||||
AI将调用`send_command`或`send_commands`工具执行相应命令。
|
||||
|
||||
### 5.3 网络拓扑发现
|
||||
|
||||
#### 发现设备拓扑
|
||||
|
||||
```
|
||||
请发现Router-01的网络拓扑
|
||||
```
|
||||
|
||||
AI将调用`discover_topology`工具,通过CDP/LLDP协议发现网络拓扑。
|
||||
|
||||
#### 查看拓扑信息
|
||||
|
||||
```
|
||||
显示当前网络拓扑的统计信息
|
||||
```
|
||||
|
||||
AI将调用`get_topology_statistics`工具显示拓扑统计。
|
||||
|
||||
### 5.4 网络扫描
|
||||
|
||||
#### 扫描网络范围
|
||||
|
||||
```
|
||||
请扫描192.168.1.0/24网段,发现网络设备
|
||||
```
|
||||
|
||||
AI将调用`scan_network_range`工具进行网络扫描。
|
||||
|
||||
#### 查看扫描结果
|
||||
|
||||
```
|
||||
显示网络扫描的结果
|
||||
```
|
||||
|
||||
AI将调用`get_scan_results`工具显示扫描发现的设备。
|
||||
|
||||
## 6. 高级功能
|
||||
|
||||
### 6.1 使用提示模板
|
||||
|
||||
#### 设备诊断模板
|
||||
|
||||
```
|
||||
使用设备诊断模板分析Router-01的状态
|
||||
```
|
||||
|
||||
AI将使用`device_diagnosis`模板,结合设备信息和接口状态进行专业分析。
|
||||
|
||||
#### 配置审查模板
|
||||
|
||||
```
|
||||
使用配置审查模板检查Router-01的配置
|
||||
```
|
||||
|
||||
AI将使用`config_review`模板对设备配置进行安全和最佳实践审查。
|
||||
|
||||
#### 网络故障排除模板
|
||||
|
||||
```
|
||||
使用故障排除模板分析网络连接问题
|
||||
```
|
||||
|
||||
AI将使用`network_troubleshooting`模板进行系统化的故障排除。
|
||||
|
||||
### 6.2 使用MCP资源
|
||||
|
||||
#### 访问设备信息资源
|
||||
|
||||
```
|
||||
获取device://router-01的设备信息资源
|
||||
```
|
||||
|
||||
#### 访问配置资源
|
||||
|
||||
```
|
||||
获取device://router-01/config的配置资源
|
||||
```
|
||||
|
||||
#### 访问拓扑资源
|
||||
|
||||
```
|
||||
获取topology://的网络拓扑资源
|
||||
```
|
||||
|
||||
### 6.3 Web界面使用
|
||||
|
||||
#### 启动Web界面
|
||||
|
||||
```bash
|
||||
python server.py --web --port 8080
|
||||
```
|
||||
|
||||
然后在浏览器中访问:http://localhost:8080
|
||||
|
||||
#### Web界面功能
|
||||
|
||||
1. **设备管理页面**
|
||||
- 添加、编辑、删除设备
|
||||
- 管理设备凭据
|
||||
- 查看设备状态
|
||||
|
||||
2. **终端页面**
|
||||
- 多标签页终端
|
||||
- 实时命令执行
|
||||
- 命令历史和补全
|
||||
|
||||
3. **拓扑页面**
|
||||
- 交互式拓扑图
|
||||
- 拓扑发现控制
|
||||
- 设备详情查看
|
||||
|
||||
## 7. 配置管理
|
||||
|
||||
### 7.1 数据存储配置
|
||||
|
||||
系统数据存储在以下位置:
|
||||
|
||||
```
|
||||
NetBrainMCP/
|
||||
├── data/
|
||||
│ ├── devices.json # 设备信息
|
||||
│ └── credentials.json # 凭据信息(加密存储)
|
||||
├── resource_cache/ # 资源缓存
|
||||
└── templates/ # 模板缓存
|
||||
```
|
||||
|
||||
### 7.2 日志配置
|
||||
|
||||
日志文件位置:
|
||||
|
||||
```
|
||||
NetBrainMCP/
|
||||
└── logs/
|
||||
├── netbrain_mcp.log # 主日志
|
||||
├── device_connector.log # 连接日志
|
||||
└── audit.log # 审计日志
|
||||
```
|
||||
|
||||
### 7.3 缓存配置
|
||||
|
||||
- **资源缓存**:默认5分钟TTL
|
||||
- **设备配置缓存**:默认10分钟TTL
|
||||
- **拓扑缓存**:默认15分钟TTL
|
||||
|
||||
可在代码中调整缓存设置:
|
||||
|
||||
```python
|
||||
# 在mcp_resources.py中
|
||||
self.default_cache_ttl = 300 # 5分钟
|
||||
```
|
||||
|
||||
## 8. 故障排除
|
||||
|
||||
### 8.1 常见问题
|
||||
|
||||
#### 连接问题
|
||||
|
||||
**问题**:无法连接到设备
|
||||
```
|
||||
解决方案:
|
||||
1. 检查设备IP地址是否正确
|
||||
2. 验证网络连通性(ping测试)
|
||||
3. 确认SSH/Telnet服务已启用
|
||||
4. 检查凭据是否正确
|
||||
5. 查看防火墙设置
|
||||
```
|
||||
|
||||
**问题**:连接超时
|
||||
```
|
||||
解决方案:
|
||||
1. 增加连接超时时间
|
||||
2. 检查网络延迟
|
||||
3. 确认设备负载不高
|
||||
4. 检查并发连接限制
|
||||
```
|
||||
|
||||
#### MCP服务器问题
|
||||
|
||||
**问题**:Claude Desktop无法连接MCP服务器
|
||||
```
|
||||
解决方案:
|
||||
1. 检查配置文件路径是否正确
|
||||
2. 验证Python路径和脚本路径
|
||||
3. 检查权限设置
|
||||
4. 查看Claude Desktop日志
|
||||
5. 重启Claude Desktop
|
||||
```
|
||||
|
||||
**问题**:工具调用失败
|
||||
```
|
||||
解决方案:
|
||||
1. 检查Python环境和依赖
|
||||
2. 查看MCP服务器日志
|
||||
3. 验证工具参数格式
|
||||
4. 检查设备连接状态
|
||||
```
|
||||
|
||||
### 8.2 调试技巧
|
||||
|
||||
#### 启用详细日志
|
||||
|
||||
```bash
|
||||
# 设置日志级别为DEBUG
|
||||
export LOG_LEVEL=DEBUG
|
||||
python server.py
|
||||
```
|
||||
|
||||
#### 查看实时日志
|
||||
|
||||
```bash
|
||||
# Linux/macOS
|
||||
tail -f logs/netbrain_mcp.log
|
||||
|
||||
# Windows (PowerShell)
|
||||
Get-Content logs/netbrain_mcp.log -Wait
|
||||
```
|
||||
|
||||
#### 测试设备连接
|
||||
|
||||
```python
|
||||
# 使用test_scrapli_connection工具
|
||||
python -c "
|
||||
import asyncio
|
||||
from server import test_scrapli_connection
|
||||
result = asyncio.run(test_scrapli_connection(
|
||||
host='192.168.1.1',
|
||||
username='admin',
|
||||
password='cisco123',
|
||||
platform='cisco_iosxe'
|
||||
))
|
||||
print(result)
|
||||
"
|
||||
```
|
||||
|
||||
### 8.3 性能优化
|
||||
|
||||
#### 连接池配置
|
||||
|
||||
```python
|
||||
# 在device_connector.py中调整连接池大小
|
||||
MAX_CONNECTIONS = 10 # 最大并发连接数
|
||||
CONNECTION_TIMEOUT = 30 # 连接超时时间
|
||||
```
|
||||
|
||||
#### 缓存优化
|
||||
|
||||
```python
|
||||
# 调整缓存策略
|
||||
RESOURCE_CACHE_TTL = 300 # 资源缓存时间
|
||||
CONFIG_CACHE_TTL = 600 # 配置缓存时间
|
||||
TOPOLOGY_CACHE_TTL = 900 # 拓扑缓存时间
|
||||
```
|
||||
|
||||
## 9. 最佳实践
|
||||
|
||||
### 9.1 设备管理最佳实践
|
||||
|
||||
1. **统一命名规范**
|
||||
```
|
||||
设备命名:<位置>-<类型>-<编号>
|
||||
示例:DC1-RTR-01、DC1-SW-02
|
||||
```
|
||||
|
||||
2. **标签使用**
|
||||
```
|
||||
按功能分类:core, access, distribution
|
||||
按环境分类:production, staging, development
|
||||
按位置分类:datacenter1, branch-office, remote
|
||||
```
|
||||
|
||||
3. **凭据管理**
|
||||
```
|
||||
- 为不同设备类型创建专用凭据
|
||||
- 定期轮换密码
|
||||
- 使用SSH密钥认证(推荐)
|
||||
- 设置不同权限级别的凭据
|
||||
```
|
||||
|
||||
### 9.2 安全最佳实践
|
||||
|
||||
1. **网络安全**
|
||||
```
|
||||
- 限制MCP服务器的网络访问
|
||||
- 使用VPN或专用网络连接
|
||||
- 启用设备访问日志记录
|
||||
- 定期审查访问权限
|
||||
```
|
||||
|
||||
2. **数据保护**
|
||||
```
|
||||
- 定期备份设备和凭据数据
|
||||
- 使用强密码和加密
|
||||
- 限制文件系统访问权限
|
||||
- 监控异常访问活动
|
||||
```
|
||||
|
||||
### 9.3 运维最佳实践
|
||||
|
||||
1. **监控和告警**
|
||||
```
|
||||
- 监控MCP服务器状态
|
||||
- 设置设备连接告警
|
||||
- 记录重要操作日志
|
||||
- 定期检查系统资源使用
|
||||
```
|
||||
|
||||
2. **维护计划**
|
||||
```
|
||||
- 定期更新依赖包
|
||||
- 清理过期缓存文件
|
||||
- 归档旧日志文件
|
||||
- 验证备份数据完整性
|
||||
```
|
||||
|
||||
## 10. API参考
|
||||
|
||||
### 10.1 MCP工具列表
|
||||
|
||||
#### 设备管理工具
|
||||
- `list_devices` - 列出设备
|
||||
- `add_device` - 添加设备
|
||||
- `get_device` - 获取设备信息
|
||||
- `update_device` - 更新设备
|
||||
- `delete_device` - 删除设备
|
||||
|
||||
#### 连接管理工具
|
||||
- `connect_device` - 连接设备
|
||||
- `disconnect_device` - 断开连接
|
||||
- `send_command` - 发送命令
|
||||
- `send_commands` - 发送多个命令
|
||||
- `get_active_connections` - 获取活动连接
|
||||
|
||||
#### 拓扑发现工具
|
||||
- `discover_topology` - 发现拓扑
|
||||
- `get_topology` - 获取拓扑
|
||||
- `clear_topology` - 清除拓扑
|
||||
- `get_device_neighbors` - 获取邻居
|
||||
- `get_topology_statistics` - 拓扑统计
|
||||
|
||||
### 10.2 MCP资源列表
|
||||
|
||||
#### 设备资源
|
||||
- `device/{device_id}` - 设备基本信息
|
||||
- `device/{device_id}/config` - 设备配置
|
||||
- `device/{device_id}/interfaces` - 接口信息
|
||||
- `device/{device_id}/routes` - 路由信息
|
||||
- `device/{device_id}/neighbors` - 邻居信息
|
||||
|
||||
#### 系统资源
|
||||
- `credentials` - 凭据列表
|
||||
- `system/status` - 系统状态
|
||||
- `topology` - 网络拓扑
|
||||
- `scan/results` - 扫描结果
|
||||
|
||||
### 10.3 提示模板列表
|
||||
|
||||
#### 诊断模板
|
||||
- `device_diagnosis` - 设备诊断
|
||||
- `network_troubleshooting` - 网络故障排除
|
||||
- `performance_optimization` - 性能优化
|
||||
|
||||
#### 配置模板
|
||||
- `config_review` - 配置审查
|
||||
- `security_audit` - 安全审计
|
||||
- `vlan_config` - VLAN配置
|
||||
|
||||
## 11. 扩展开发
|
||||
|
||||
### 11.1 添加新的MCP工具
|
||||
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def custom_tool(param1: str, param2: int) -> Dict[str, Any]:
|
||||
"""自定义工具描述"""
|
||||
# 工具实现逻辑
|
||||
return {"result": "success"}
|
||||
```
|
||||
|
||||
### 11.2 添加新的MCP资源
|
||||
|
||||
```python
|
||||
@resource_manager.register_resource("custom/{id}", ResourceType.CUSTOM)
|
||||
async def get_custom_resource(id: str) -> Dict[str, Any]:
|
||||
"""自定义资源描述"""
|
||||
# 资源获取逻辑
|
||||
return {"data": "custom_data"}
|
||||
```
|
||||
|
||||
### 11.3 添加新的提示模板
|
||||
|
||||
```python
|
||||
@template_manager.register_template(
|
||||
name="custom_template",
|
||||
description="自定义模板描述"
|
||||
)
|
||||
def custom_template(param1: str, param2: str) -> str:
|
||||
"""自定义模板实现"""
|
||||
return f"自定义提示:{param1} - {param2}"
|
||||
```
|
||||
|
||||
## 12. 社区和支持
|
||||
|
||||
### 12.1 获取帮助
|
||||
|
||||
- **文档**:查看完整的技术文档
|
||||
- **示例**:参考examples目录中的使用示例
|
||||
- **FAQ**:查看常见问题解答
|
||||
|
||||
### 12.2 贡献代码
|
||||
|
||||
欢迎为NetBrain MCP项目贡献代码:
|
||||
|
||||
1. Fork项目仓库
|
||||
2. 创建功能分支
|
||||
3. 提交代码变更
|
||||
4. 创建Pull Request
|
||||
|
||||
### 12.3 报告问题
|
||||
|
||||
如发现bug或有功能建议,请:
|
||||
|
||||
1. 检查已知问题列表
|
||||
2. 提供详细的错误信息
|
||||
3. 包含复现步骤
|
||||
4. 提交Issue或联系维护团队
|
||||
|
||||
---
|
||||
|
||||
通过本指南,您应该能够熟练使用NetBrain MCP系统进行网络设备管理和AI驱动的网络运维工作。如有任何问题,请参考故障排除部分或联系技术支持团队。
|
||||
Reference in New Issue
Block a user