15 KiB
15 KiB
苏州教育E卡通数据安全运维操作手册
前言
本手册基于苏州教育E卡通平台的实际运维需求,旨在建立一套实用、可操作的数据安全管控体系。聚焦于解决实际工作中真正存在的风险问题。
本手册适用于所有参与平台运维、管理的人员,包括但不限于系统管理员、客服人员、学校管理人员等。
一、风险分级体系
1.1 三级操作分类
等保三级依据:根据GB/T 22239-2019要求,对不同风险的操作采取相应控制措施。
🔴 关键操作 (CRITICAL)
识别标准:
- 系统核心配置修改
- 用户权限分配
- 审计规则修改
- 批量数据处理(≥50条)
- 系统运维重大调整 管控要求:
- 主管审批:事前纸质(电子档)审批流程
- 双人确认:一人操作,一人监督
- 双因素认证:密码+动态码,堡垒机或摄像记录
- 操作记录:详细日志记录
- 自动备份:执行前自动备份
🟡 重要操作 (IMPORTANT)
识别标准:
- 特殊敏感数据修改(身份证、家庭住址、监护人联系方式)
- 新生录入、注册报到等
- 账号创建和权限分配(非管理员,如班主任等)
管控要求:
- 主管审批:事后审核
- 双因素认证:重要操作时启用
- 操作确认:关键步骤二次确认
- 操作日志:完整记录操作链路
🟢 一般操作 (NORMAL)
识别标准:
- 学生信息查询
- 系统状态查看
- 非敏感信息修改
- 补换卡订单处理
- 报表生成和统计
管控要求:
- 基本认证:用户名密码认证
- 操作记录:基础日志记录
- 访问控制:基于角色的权限控制
- 会话管理:超时自动退出
二、简化的角色体系
2.1 核心角色定义
| 角色 | 主要职责 | 可操作范围 | 禁止操作 |
|---|---|---|---|
| 家长用户 | 查看自己孩子信息 | ✓ 查看基本信息 ✓ 修改联系方式 ✓ 查看卡状态 |
✗ 查看其他学生 ✗ 修改关键信息 ✗ 批量操作 |
| 学校教师 | 管理本校学生 | ✓ 新生录入 ✓ 修改非关键信息 ✓ 本校数据查询 |
✗ 跨校查询 ✗ 删除记录 ✗ 批量导出 |
| 客服人员 | 处理补卡业务 | ✓ 学生信息查询(补卡用) ✓ 处理补换卡订单 ✓ 查询卡状态 |
✗ 查看敏感信息 ✗ 修改数据 ✗ 批量导出 |
| 系统(区域)管理员 | 处理学校业务 | ✓ 信息修改 ✓ 敏感信息 ✓ 执行任务 ✓ 用户账号管理 |
✗ 参与业务审批 ✗ 单独操作 |
| 审核管理员 | 业务审核 | ✓ 业务审批 ✓ 信息查询 |
✗ 修改数据 ✗ 用户账号管理 ✗ 单独操作 |
| 安全审计管理员 | 安全审计 | ✓ 查看所有日志 ✓ 生成安全报告 ✓ 设置监控规则 ✓ 调查安全事件 |
✗ 修改业务数据 ✗ 执行业务操作 ✗ 查看敏感信息 |
| 系统运维人员 | 系统运维 | ✓ 服务器维护 ✓ 数据库备份 ✓ 执行审批脚本 |
✗ 查看业务数据 ✗ 参与业务审批 ✗ 单独操作 |
2.2 权限分离原则
核心原则:
- 操作与审核分离:操作人不能同时是审核人
- 技术与业务分离:系统管理员不接触业务数据
- 监督与执行分离:安全管理员只监督不执行
简化的权限矩阵:
| 操作类型 | 学校教师 | 客服人员 | 系统管理员 | 安全管理员 |
|---|---|---|---|---|
| 数据查询 | ✅(本校) | ✅(授权) | ❌ | ✅(审计) |
| 数据修改 | ✅(非关键) | ❌ | ✅(脚本) | ❌ |
| 关键操作 | ❌ | ❌ | ✅(双人) | ❌ |
| 系统运维 | ❌ | ❌ | ✅ | ❌ |
| 安全审计 | ❌ | ❌ | ❌ | ✅ |
三、统一的操作流程
3.1 标准三阶段流程
所有操作统一采用三阶段流程:
申请阶段 → 审批阶段 → 执行阶段
第一阶段:申请
- 操作人提交申请
- 系统自动检查权限
- 生成操作编号
第二阶段:审批
- 关键操作:需要双人确认
- 重要操作:需要主管审批
- 一般操作:自动审批
第三阶段:执行
- 验证审批状态
- 执行操作
- 记录结果
3.2 操作流程简化图
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 申请 │───→│ 审批 │───→│ 执行 │
└─────────┘ └─────────┘ └─────────┘
│ │ │
│ │ │
自动检查 分级审批 结果记录
权限验证 双人确认 日志保存
四、权限控制
4.1 访问控制
角色权限控制:
-- 角色表
create table SYS_ROLE
(
role_id NUMBER not null,--角色主键
role_name VARCHAR2(30) not null,--角色名称
role_key VARCHAR2(100) not null,
role_sort NUMBER not null,
data_scope CHAR(1) default '1',
status CHAR(1) not null, --角色状态
del_flag CHAR(1) default '0',
create_by VARCHAR2(64) default '',
create_time DATE,
update_by VARCHAR2(64) default '',
update_time DATE,
remark VARCHAR2(500)
)
--角色菜单表
create table SYS_ROLE_MENU
(
role_id NUMBER not null,
menu_id NUMBER not null
)
4.2 身份鉴别
登录认证流程:
-
收集身份凭证:用户名和密码
-
创建认证令牌:UsernamePasswordToken
-
提交认证:subject.login(token)
-
Realm 验证:自定义 Realm 中验证用户信息
-
处理结果:成功跳转首页,失败返回错误信息
会话管理:
- 超时时间:30分钟超时
会话控制:
- 并发控制:限制同一用户最大会话数
- 踢出策略:新登录踢出旧会话或阻止新登录
4.3 审计日志
审计日志结构:
-- 审计日志
create table SYS_OPER_LOG
(
oper_id NUMBER not null,
title VARCHAR2(50) , -- 业务标题
business_type NUMBER default 0,
method VARCHAR2(100), -- 方法名称
operator_type NUMBER default 0, --操作类别(0其它 1后台用户 2手机端用户)
oper_name VARCHAR2(50), --操作人员
dept_name VARCHAR2(50),--部门名称
oper_url VARCHAR2(255),
oper_ip VARCHAR2(50),--主机地址
oper_location VARCHAR2(255),
oper_param VARCHAR2(4000),
status NUMBER default 0,
error_msg VARCHAR2(4000),
oper_time DATE--操作时间
);
五、监控和告警
5.1 告警规则
告警规则:
- 连续5次登录失败
- 未审批就执行的操作
告警处理:
- 系统自动发送告警
- 安全管理员15分钟内响应
- 记录处理结果
5.2 监控指标
核心监控指标:
- 登录成功率
- 操作执行成功率
- 异常操作数量
- 系统响应时间
六、数据备份
6.1 备份策略
简单的备份方案:
- 实时备份:关键数据实时同步 使用oracle ram 回闪备份技术进行实时备份
- 每日备份:全量数据备份 每日凌晨 导出 一份 dmp 文件
- 异地备份:备份到异地存储 备份文件同步到异地存储保存
- 保留期限:在线30天,离线1年
磁盘监控脚本: 每5分钟 检查一遍磁盘空间 当发现磁盘可用空间小于阈值后 发送企微告警
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os/exec"
"strconv"
"strings"
"time"
)
// Config 配置结构体
type Config struct {
WebhookURL string `json:"webhook_url"`
UsageThreshold float64 `json:"usage_threshold"`
Interval int `json:"interval"` // 新增:监控间隔时间(分钟)
}
// 获取主机的 IP 地址
func getHostIP() (string, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return "", err
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok &&!ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String(), nil
}
}
}
return "", fmt.Errorf("未找到有效的 IP 地址")
}
// 发送消息到企业微信机器人
func sendMessage(webhookURL, message string) error {
payload := map[string]interface{}{
"msgtype": "text",
"text": map[string]string{
"content": message,
},
}
payloadBytes, err := json.Marshal(payload)
if err != nil {
return err
}
resp, err := http.Post(webhookURL, "application/json", bytes.NewBuffer(payloadBytes))
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("发送消息失败,状态码: %d", resp.StatusCode)
}
return nil
}
// 获取所有挂载点的磁盘使用率
func getAllDiskUsage() (map[string]float64, error) {
cmd := exec.Command("df")
output, err := cmd.Output()
if err != nil {
return nil, err
}
lines := strings.Split(string(output), "\n")
if len(lines) < 2 {
return nil, fmt.Errorf("未找到磁盘使用信息")
}
usageMap := make(map[string]float64)
for _, line := range lines[1:] {
if line == "" {
continue
}
fields := strings.Fields(line)
if len(fields) < 6 {
continue
}
mountPoint := fields[5]
usageStr := strings.TrimRight(fields[4], "%")
usage, err := strconv.ParseFloat(usageStr, 64)
if err != nil {
continue
}
usageMap[mountPoint] = usage
}
return usageMap, nil
}
func monitorDiskUsage(config Config) {
ip, err := getHostIP()
if err != nil {
log.Printf("获取 IP 地址失败: %v", err)
ip = "未知 IP"
}
usageMap, err := getAllDiskUsage()
if err != nil {
log.Fatalf("获取磁盘使用率失败: %v", err)
}
var alertMessages []string
for mountPoint, usage := range usageMap {
if usage > config.UsageThreshold {
message := fmt.Sprintf("警告:IP 地址为 %s 的主机,挂载点 %s 的磁盘使用率已达到 %.2f%%,超过阈值 %.2f%%!", ip, mountPoint, usage, config.UsageThreshold)
alertMessages = append(alertMessages, message)
}
}
if len(alertMessages) > 0 {
combinedMessage := strings.Join(alertMessages, "\n")
err := sendMessage(config.WebhookURL, combinedMessage)
if err != nil {
log.Printf("发送告警消息失败: %v", err)
} else {
log.Printf("已发送告警消息: %s", combinedMessage)
}
} else {
log.Println("所有挂载点的磁盘使用率正常")
}
}
func main() {
// 读取配置文件
configData, err := ioutil.ReadFile("config.json")
if err != nil {
log.Fatalf("读取配置文件失败: %v", err)
}
var config Config
err = json.Unmarshal(configData, &config)
if err != nil {
log.Fatalf("解析配置文件失败: %v", err)
}
// 首次执行监控
monitorDiskUsage(config)
// 创建定时器
ticker := time.NewTicker(time.Duration(config.Interval) * time.Minute)
defer ticker.Stop()
for range ticker.C {
monitorDiskUsage(config)
}
}
七、应急响应
7.1 简化的应急流程
三级响应:
| 事件级别 | 响应时间 | 处理方式 |
|---|---|---|
| 一般事件 | 2小时内 | 在线处理 |
| 重要事件 | 30分钟内 | 紧急处理 |
| 重大事件 | 15分钟内 | 立即处理 |
7.2 应急联系人
| 角色 | 联系人 | 电话 |
|---|---|---|
| 应急总指挥 | [姓名] | [电话] |
| 技术负责人 | [姓名] | [电话] |
| 安全负责人 | [姓名] | [电话] |
八、培训和考核
8.1 培训内容
新员工培训(4小时):
- 手册内容和操作规范(2小时)
- 系统操作演示(1小时)
- 应急流程说明(1小时)
年度复训(2小时):
- 安全事件案例分析(1小时)
- 操作规范更新(1小时)
8.2 考核要求
- 每年1次操作规范考试
- 每半年1次应急演练
- 不合格人员重新培训
九、操作检查表
9.1 关键操作检查表
申请阶段:
- 操作目的明确
- 影响范围确认
- 申请人权限验证
审批阶段:
- 必要性评估
- 风险评估
- 备份方案确认
执行阶段:
- 双人确认(关键操作)
- 操作步骤按计划执行
- 结果验证
完成阶段:
- 操作记录保存
- 相关人员通知
- 异常情况处理
9.2 系统管理员操作检查表
操作前:
- 维护时间窗口确认
- 影响范围评估
- 备份完成确认
- 回滚方案准备
操作中:
- 按计划执行
- 每步确认结果
- 异常情况记录
操作后:
- 系统功能验证
- 性能检查
- 操作记录归档
十、附录
附录A:角色申请表
申请编号: [自动生成]
申请人: [姓名]
所属部门: [部门]
申请角色: [角色名称]
申请原因: [详细说明]
申请权限:
□ 查询权限
□ 修改权限
□ 删除权限
□ 系统管理权限
申请人签字: _________ 日期: _________
部门主管审批: _________ 日期: _________
安全管理员审核: _________ 日期: _________
附录B:操作申请单
申请单编号: [自动生成]
申请时间: YYYY-MM-DD HH:MM
申请人: [姓名]
操作类型: [关键/重要/一般]
操作描述: [详细说明]
影响范围: [影响的人数/系统范围]
操作步骤: [简要步骤]
申请人签字: _________ 日期: _________
审批人签字: _________ 日期: _________
执行确认: _________ 日期: _________
附录C:应急响应记录表
事件编号: [自动生成]
发生时间: YYYY-MM-DD HH:MM
事件类型: [一般/重要/重大]
事件描述: [简要描述]
响应时间: ____分钟
处理过程: [简要记录]
处理结果: [成功/失败]
处理人签字: _________ 日期: _________
确认人签字: _________ 日期: _________
结语
简单就是美
本手册采用简化的设计,在满足等保三级要求的同时,最大限度地降低系统复杂度和操作难度。
核心原则:
- 消除特殊情况
- 统一操作流程
- 减少概念数量
- 保持实用主义
通过这种方式,我们既能满足合规要求,又能确保系统的可维护性和操作的便利性。
本手册自发布之日起执行,由数据安全管理领导小组负责解释和修订。