diff --git "a/Doc/\350\277\234\347\250\213\345\221\275\344\273\244\346\211\247\350\241\214\345\256\211\345\205\250\346\226\271\346\241\210.md" "b/Doc/\350\277\234\347\250\213\345\221\275\344\273\244\346\211\247\350\241\214\345\256\211\345\205\250\346\226\271\346\241\210.md"
new file mode 100644
index 0000000..d473b0d
--- /dev/null
+++ "b/Doc/\350\277\234\347\250\213\345\221\275\344\273\244\346\211\247\350\241\214\345\256\211\345\205\250\346\226\271\346\241\210.md"
@@ -0,0 +1,450 @@
+# Զ������ִ�а�ȫ����
+
+## ����
+
+StarAgent ֧��ͨ���dz�ƽ̨Զ��ִ�� bash/cmd ������������������Ⱥ�������� Agent �ǿ�Դ�ģ��ͻ��˷�����Ч�����**��ȫ�����ص���ƽ̨��**��
+
+## ����ԭ��
+
+1. **�ͻ��˿ɱ��ƹ�**�������߿����� Agent Դ��ȥ������
+2. **ƽ̨�����α߽�**�����з���������ƽ̨��ʵʩ
+3. **��������ڷ���**������ֹʱ��ȷ������
+
+---
+
+## ��ʵʩ������A - ��ǿ�����־
+
+### Agent ��Ľ�
+
+#### 1. ʹ�� WriteEvent �ϱ���־
+```csharp
+// ִ��ǰ����¼�����ʱ��ʱ���
+WriteEvent("warn", "RunBash", $"ִ�����{cmd}����ʱ��{timeout}ms��ʱ�䣺{now:yyyy-MM-dd HH:mm:ss}");
+
+// ִ�гɹ�����¼��ʱ���������
+WriteEvent("info", "RunBash", $"ִ�гɹ������{cmd}����ʱ��{sw.ElapsedMilliseconds}ms��������ȣ�{rs?.Length ?? 0}");
+
+// ִ��ʧ�ܣ���¼������Ϣ
+WriteEvent("error", "RunBash", $"ִ��ʧ�ܣ����{cmd}����ʱ��{sw.ElapsedMilliseconds}ms������{ex.Message}");
+```
+
+#### 2. �ؼ�����
+- ? **����ɾ��**��`WriteEvent` ֱ���ϱ����dz�ƽ̨���ݿ�
+- ? **������¼**�����ʱ�䡢��ʱ�������������Ϣ
+- ? **���ܼ���**��ʹ�� `Stopwatch` ��¼��ȷ��ʱ
+- ? **����ض�**��������־������1000�ַ��ضϣ�
+
+#### 3. �����־�ֶ�
+| �ֶ� | ˵�� | ʾ�� |
+|------|------|------|
+| ���� | warn/info/error | warn��ִ��ǰ����info���ɹ�����error��ʧ�ܣ� |
+| ���� | RunBash/RunCmd | RunBash |
+| ���� | ������������ | `systemctl restart nginx` |
+| ��ʱ | ��ʱʱ�䣨���룩 | 30000 |
+| ��ʱ | ʵ��ִ��ʱ�䣨���룩 | 1523 |
+| ������� | ���ؽ������ | 256 |
+| ʱ��� | ִ��ʱ�� | 2025-01-01 14:30:00 |
+| ������Ϣ | ʧ��ԭ�� | Command execution timeout |
+
+---
+
+## ��ʵʩ������B - ƽ̨�����
+
+### 1. ���ݿ�����
+
+#### NodeCommand���ڵ������¼����
+```sql
+CREATE TABLE NodeCommand (
+ Id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ NodeId INT NOT NULL COMMENT '�ڵ�ID',
+ NodeName VARCHAR(100) COMMENT '�ڵ�����',
+ Command TEXT NOT NULL COMMENT 'ִ�е�����',
+ Type VARCHAR(20) COMMENT 'bash/cmd',
+
+ -- ��������Ϣ
+ OperatorId INT COMMENT '������ID',
+ OperatorName VARCHAR(50) COMMENT '����������',
+ OperatorRole VARCHAR(50) COMMENT '�����˽�ɫ',
+ ClientIP VARCHAR(50) COMMENT '������IP',
+ ClientLocation VARCHAR(100) COMMENT 'IP�����',
+
+ -- ִ�н��
+ Success BOOLEAN COMMENT '�Ƿ�ɹ�',
+ Duration INT COMMENT '��ʱ(ms)',
+ OutputLength INT COMMENT '�������',
+ ErrorMessage TEXT COMMENT '������Ϣ',
+
+ -- ʱ���
+ ExecuteTime DATETIME COMMENT 'ִ��ʱ��',
+ CreateTime DATETIME NOT NULL,
+
+ INDEX idx_node (NodeId, ExecuteTime),
+ INDEX idx_operator (OperatorId, ExecuteTime),
+ INDEX idx_time (ExecuteTime)
+) COMMENT='�ڵ�����ִ�м�¼������ɾ����';
+```
+
+#### NodeCommandAlert�����в����澯����
+```sql
+CREATE TABLE NodeCommandAlert (
+ Id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ CommandId BIGINT COMMENT '����NodeCommand.Id',
+ AlertType VARCHAR(50) COMMENT '�澯���ͣ�dangerous_command/batch_operation/abnormal_time/abnormal_ip',
+ AlertLevel VARCHAR(20) COMMENT '�澯����info/warn/error/critical',
+ AlertMessage TEXT COMMENT '�澯����',
+
+ -- �澯����
+ Status VARCHAR(20) DEFAULT 'pending' COMMENT '״̬��pending/confirmed/ignored',
+ Handler INT COMMENT '������ID',
+ HandleTime DATETIME COMMENT '����ʱ��',
+ HandleRemark TEXT COMMENT '������ע',
+
+ -- ֪ͨ״̬
+ NotifyDingTalk BOOLEAN DEFAULT FALSE COMMENT '�Ƿ��Ѷ���֪ͨ',
+ NotifyWechat BOOLEAN DEFAULT FALSE COMMENT '�Ƿ�����֪ͨ',
+ NotifySMS BOOLEAN DEFAULT FALSE COMMENT '�Ƿ��Ѷ���֪ͨ',
+
+ CreateTime DATETIME NOT NULL,
+
+ INDEX idx_status (Status, CreateTime),
+ INDEX idx_command (CommandId)
+) COMMENT='�ڵ�����澯��¼';
+```
+
+### 2. �������������
+
+#### Σ�չؼ����б�
+```csharp
+public static class DangerousPatterns
+{
+ // ϵͳ�ƻ�
+ public static readonly String[] SystemDestruction =
+ [
+ "rm -rf /", // ɾ����Ŀ¼
+ "mkfs", // ��ʽ������
+ "dd if=/dev/zero", // д�����ֽ�
+ ":(){:|:&};:", // Forkը��
+ ];
+
+ // Ȩ����
+ public static readonly String[] PermissionChange =
+ [
+ "chmod 777", // Σ��Ȩ��
+ "chown root", // �ı�������
+ "passwd", // ������
+ "useradd", // �����û�
+ "userdel", // ɾ���û�
+ ];
+
+ // Զ��ִ��
+ public static readonly String[] RemoteExecution =
+ [
+ "curl.*|.*bash", // ���ز�ִ��
+ "wget.*|.*sh", // ���ز�ִ��
+ "nc -l", // ����shell
+ "/dev/tcp", // �������
+ ];
+
+ // ���簲ȫ
+ public static readonly String[] NetworkSecurity =
+ [
+ "iptables -F", // ��շ���ǽ
+ "systemctl stop firewalld", // ֹͣ����ǽ
+ "ufw disable", // ���÷���ǽ
+ ];
+
+ // ϵͳ����
+ public static readonly String[] SystemControl =
+ [
+ "shutdown", // �ػ�
+ "reboot", // ������ע�⣺����node/rebootָ�
+ "init 0", // �ػ�
+ "init 6", // ����
+ ];
+}
+```
+
+#### �����
+```csharp
+public class CommandSecurityChecker
+{
+ /// <summary>��������Ƿ����Σ�ղ���</summary>
+ public static (Boolean isDangerous, String category, String pattern) CheckDangerous(String command)
+ {
+ foreach (var pattern in DangerousPatterns.SystemDestruction)
+ {
+ if (Regex.IsMatch(command, pattern, RegexOptions.IgnoreCase))
+ return (true, "ϵͳ�ƻ�", pattern);
+ }
+
+ foreach (var pattern in DangerousPatterns.PermissionChange)
+ {
+ if (Regex.IsMatch(command, pattern, RegexOptions.IgnoreCase))
+ return (true, "Ȩ����", pattern);
+ }
+
+ foreach (var pattern in DangerousPatterns.RemoteExecution)
+ {
+ if (Regex.IsMatch(command, pattern, RegexOptions.IgnoreCase))
+ return (true, "Զ��ִ��", pattern);
+ }
+
+ foreach (var pattern in DangerousPatterns.NetworkSecurity)
+ {
+ if (Regex.IsMatch(command, pattern, RegexOptions.IgnoreCase))
+ return (true, "���簲ȫ", pattern);
+ }
+
+ foreach (var pattern in DangerousPatterns.SystemControl)
+ {
+ if (Regex.IsMatch(command, pattern, RegexOptions.IgnoreCase))
+ return (true, "ϵͳ����", pattern);
+ }
+
+ return (false, null, null);
+ }
+}
+```
+
+### 3. �쳣��Ϊ���
+
+#### �����������
+```csharp
+// ��⣺5������ͬһ�û�ִ�������100��
+var count = NodeCommand.FindCount(
+ _.OperatorId == userId &&
+ _.ExecuteTime >= DateTime.Now.AddMinutes(-5)
+);
+
+if (count > 100)
+{
+ // �����澯
+ CreateAlert(commandId, "batch_operation", "error",
+ $"�û� {operatorName} ��5������ִ���� {count} �����������������");
+
+ // ��ʱ�����˺�
+ FreezeUser(userId, "���������澯����ʱ����30����");
+
+ // ����֪ͨ
+ SendAlert("����", $"�û� {operatorName} �˺����Ʊ���������ʱ����");
+}
+```
+
+#### �쳣ʱ����
+```csharp
+// ��⣺�賿2-5��ִ������ && ���û���δ�ڴ�ʱ�β���
+var hour = DateTime.Now.Hour;
+if (hour >= 2 && hour < 5)
+{
+ var historyCount = NodeCommand.FindCount(
+ _.OperatorId == userId &&
+ _.ExecuteTime.Hour >= 2 &&
+ _.ExecuteTime.Hour < 5 &&
+ _.ExecuteTime < DateTime.Now.AddDays(-7) // ��7��ǰ����ʷ
+ );
+
+ if (historyCount == 0)
+ {
+ CreateAlert(commandId, "abnormal_time", "warn",
+ $"�û� {operatorName} �״����賿 {hour} ��ִ�����{command}");
+
+ SendAlert("����", $"�û� {operatorName} ���쳣ʱ��β���");
+ }
+}
+```
+
+#### �쳣IP���
+```csharp
+// ��⣺����IP����û���ʷIP����λ�����>1000km
+var lastLogin = UserLoginLog.FindLast(_.UserId == userId);
+if (lastLogin != null && lastLogin.ClientIP != currentIP)
+{
+ var lastLocation = GetIPLocation(lastLogin.ClientIP);
+ var currentLocation = GetIPLocation(currentIP);
+ var distance = CalculateDistance(lastLocation, currentLocation);
+
+ if (distance > 1000)
+ {
+ CreateAlert(commandId, "abnormal_ip", "error",
+ $"�û� {operatorName} ���쳣�ص��¼��{currentLocation}�������ϴε�¼ {distance}km��");
+
+ // Ҫ�������֤
+ RequireTwoFactorAuth(userId);
+
+ SendAlert("����", $"�û� {operatorName} �쳣�ص��¼��������ȷ��");
+ }
+}
+```
+
+### 4. �澯֪ͨʵ��
+
+#### ����������֪ͨ
+```csharp
+public async Task SendDingTalkAlert(String title, String message, String level)
+{
+ var webhook = "https://oapi.dingtalk.com/robot/send?access_token=xxx";
+
+ var color = level switch
+ {
+ "info" => "#00FF00",
+ "warn" => "#FFA500",
+ "error" => "#FF0000",
+ "critical" => "#8B0000",
+ _ => "#808080"
+ };
+
+ var content = new
+ {
+ msgtype = "markdown",
+ markdown = new
+ {
+ title = title,
+ text = $"## {title}\n\n" +
+ $"**����**��{level}\n\n" +
+ $"**����**��{message}\n\n" +
+ $"**ʱ��**��{DateTime.Now:yyyy-MM-dd HH:mm:ss}\n\n" +
+ $"[�鿴����](https://stardust.newlifex.com/deployment/nodecommand)"
+ }
+ };
+
+ await HttpClient.PostJsonAsync(webhook, content);
+}
+```
+
+#### ��ҵ��֪ͨ
+```csharp
+public async Task SendWechatAlert(String title, String message, String level)
+{
+ var webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx";
+
+ var content = new
+ {
+ msgtype = "markdown",
+ markdown = new
+ {
+ content = $"## {title}\n" +
+ $">����<font color=\"warning\">{level}</font>\n" +
+ $">���ݣ�{message}\n" +
+ $">ʱ�䣺{DateTime.Now:yyyy-MM-dd HH:mm:ss}\n" +
+ $"[�鿴����](https://stardust.newlifex.com/deployment/nodecommand)"
+ }
+ };
+
+ await HttpClient.PostJsonAsync(webhook, content);
+}
+```
+
+### 5. Ȩ���ƣ�RBAC��
+
+#### ��ɫ����
+```csharp
+public enum NodeCommandPermission
+{
+ None = 0, // ��Ȩ��
+ View = 1, // �鿴�ڵ�
+ ReadOnly = 2, // ִ��ֻ�����ps/df/top�ȣ�
+ Manage = 3, // ִ�й��������������ȣ�
+ Dangerous = 4, // ִ��Σ�����ɾ���ļ�/������ȣ�
+ Admin = 5, // ��������Ա
+}
+```
+
+#### Ȩ���
+```csharp
+public Boolean CheckPermission(Int32 userId, String command)
+{
+ var user = User.FindById(userId);
+ var permission = GetCommandPermission(command);
+
+ // ����û���ɫ�Ƿ�����Ҫ��
+ if (user.NodeCommandPermission < permission)
+ {
+ XTrace.WriteLine($"Ȩ���㣺�û� {user.Name} Ȩ��Ϊ {user.NodeCommandPermission}��������Ҫ {permission}");
+ return false;
+ }
+
+ return true;
+}
+
+private NodeCommandPermission GetCommandPermission(String command)
+{
+ // ֻ������
+ if (Regex.IsMatch(command, "^(ps|top|df|free|ls|cat|tail|head|uptime|hostname)"))
+ return NodeCommandPermission.ReadOnly;
+
+ // ��������
+ if (Regex.IsMatch(command, "^(systemctl restart|systemctl stop|systemctl start)"))
+ return NodeCommandPermission.Manage;
+
+ // ������
+ if (Regex.IsMatch(command, "^(rm|passwd|userdel|useradd|chmod|chown)"))
+ return NodeCommandPermission.Dangerous;
+
+ // Ĭ����Ҫ����ԱȨ��
+ return NodeCommandPermission.Admin;
+}
+```
+
+### 6. ʵʩ����
+
+#### ��һ�Σ�������ƣ�����ɣ�
+- [x] Agent ��ʹ�� WriteEvent ��¼��־
+- [x] ��¼����ִ��ǰ���������Ϣ
+- [x] ��¼��ʱ���������
+
+#### �ڶ��Σ�ƽ̨���¼����ʵʩ��
+- [ ] ���� NodeCommand ��
+- [ ] ���� NodeCommandAlert ��
+- [ ] ʵ�������¼�ӿ�
+- [ ] ������̨չʾ������ʷ
+
+#### �����Σ����澯����ʵʩ��
+- [ ] ʵ��Σ��������
+- [ ] ʵ���쳣��Ϊ���
+- [ ] ���ɶ���/��ҵ�Ÿ澯
+- [ ] ʵ�ָ澯��������
+
+#### ���ĽΣ�Ȩ���ƣ���ʵʩ��
+- [ ] ʵ�� RBAC Ȩ����ϵ
+- [ ] Ȩ���������
+- [ ] �������̣���ѡ��
+
+---
+
+## ��¼����ȫ���ʵ��
+
+### 1. ��СȨ��ԭ��
+- ��ͨ�û���ֻ�ܲ鿴�ڵ�״̬
+- ��ά��Ա����ִ��ֻ����������
+- ����ά����ִ��Σ�������������
+- ��������Ա���������ƣ�������ƣ�
+
+### 2. ˫������֤
+����Σ�ղ�����Ҫ��
+1. ������֤
+2. ����/������֤��
+3. ��̬���ƣ���ѡ��
+
+### 3. ��������
+- ������������
+- ������ɾ�������־
+- ���ڹ鵵��ʷ����
+- �ؼ�����ʵʱ�澯
+
+### 4. �������
+- ÿ�����ɲ�������
+- �쳣��Ϊ�˹�����
+- Ȩ���ڸ���
+- ��ȫ���Գ����Ż�
+
+---
+
+## �ܽ�
+
+Զ������ִ�й��ܵİ�ȫ������**������ƽ̨��**��
+
+1. **Agent ��**����ϸ�������־������ɣ�
+2. **ƽ̨��**��Ȩ���� + �쳣��� + ʵʱ�澯����ʵʩ��
+3. **��Ӫ��**��������� + Ӧ����Ӧ
+
+**��ס**����ʹ�����߹���ƽ̨�������������־Ҳ�ܰ��������в������������һ�����ߡ�