工业控制安全编程:实现设备的操作权限分级与非法操作拦截机制
工业现场权限做烂,常见不是“没登录”,而是只把按钮灰掉:界面层禁用了“修改参数”,懂点Modbus的人直接写保持寄存器就把工艺值改了;HMI显示正常,PLC已经跑偏。 正解是RBAC分层+后端指令校验+PLC侧硬边界+审计留痕,四层一起上。
一、RBAC:用户不直接绑权限
工控标准模型是“用户→角色→权限”:
操作员:监视、启停、确认报警
工程师:改工艺参数、切配方、标校
管理员:用户管理、系统配置
运维:通信配置、故障复位,但不碰审计日志
权限别只分到“菜单级”,要分到操作原子:View/Start/Stop/SetParam/EditRecipe/UserManage。同一角色不同产线还能再分数据域,A线人员改不到B线。
二、嵌入式侧用位掩码做判定
MCU/HMI侧角色权限存成bitmask,校验开销极小:
typedef enum {
PERM_VIEW = 1<<0,
PERM_START = 1<<1,
PERM_STOP = 1<<2,
PERM_SETPARAM = 1<<3,
PERM_RECIPE = 1<<4,
PERM_USERMGR = 1<<5,
} perm_bit_t;
typedef struct {
uint32_t uid;
uint8_t role; // 0操作 1工程 2管理
uint32_t mask;
uint64_t login_ts;
} session_t;
session_t cur_user;
static int check_permit(perm_bit_t p){
return (cur_user.mask & p) ? 0 : -EPERM;
}
会话登录后下发音掩码,后续每次关键操作先check_permit,不在掩码里直接拒。
三、操作请求统一走拦截点
别在按钮回调里顺手写PLC,封装成操作请求:
typedef struct {
uint32_t op; // 操作码
uint32_t reg;
int32_t val;
uint64_t req_id;
uint32_t uid;
} ctrl_req_t;
int dispatch_ctrl(ctrl_req_t*r){
/* 1. 会话校验 */
if(session_expired(&cur_user)) return -EEXPIRED;
/* 2. 权限校验 */
if(op_need_perm(r->op) && check_permit(op_perm(r->op)))
return reject_log(r, "permission deny");
/* 3. 风险操作二次确认 */
if(op_high_risk(r->op) && !r->confirmed)
return ask_confirm(r);
/* 4. PLC侧范围硬校验 */
if(param_out_of_range(r->reg, r->val))
return reject_log(r, "value over safe bound");
/* 5. 下发+审计 */
plc_write(r->reg, r->val);
audit_record(r);
return 0;
}
界面禁用按钮只是“防误操作”,上面这层才是“防越权”。前端被绕过后后端照样拦。
四、PLC侧别信上位机
只靠HMI权限是纸老虎,懂点技术直接连PLC改值就绕过。 控制器侧必须补:
关键参数写范围硬限幅(如温度上限、力矩上限)
模式切换要条件使能:自动/手动切换需设备静止或安全条件满足
写来源标记:记录本次修改来自HMI/本地/工程软件
安全相关动作走硬件互锁,不单靠软件位
// 伪梯形:参数写前限幅
IF HMI_SET_TEMP > TEMP_MAX THEN
ACT_TEMP := TEMP_MAX;
REJECT_FLAG := 1;
ELSE
ACT_TEMP := HMI_SET_TEMP;
END_IF
Modbus这类明文协议本身无认证,网络层还得做VLAN隔离、防火墙白名单,别把写线圈端口暴露给业务网。
五、审计日志不能省
每次拒绝和关键写都落盘:
[ts][uid=3][op=SETPARAM][reg=40100][val=185]
-> DENY reason=over_bound
日志要素:谁、什么时候、哪台设备、改了哪个点、改前改后、结果。密码别明文存,加盐哈希;默认账号不给管理员权限。
高风险操作(清报警、下配方、切自动)建议原因必填;涉及安全停机/整线参数可走双人确认,不是所有操作都这么重,按风险分级就行。
六、落坑清单
只禁按钮不校验业务方法→直接写寄存器绕过
管理员账号共享给全班→出事查不到人
默认密码admin/12345→被扫一遍就进
PLC不限位→HMI拦了也被直写
审计日志放HMI内存→掉电没了
会话不过期→工程师走人工位一直有权
参数修改不记旧值→复盘对不上
Modbus端口对全厂开放→任意节点可写
工程师也能增删用户→权责不分
关键操作无二次确认→袖口蹭一下触发
七、落地顺序
角色三层:操作/工程/管理,权限原子化
登录下发bitmask,界面按权限显隐
所有写操作统一进dispatch_ctrl
check_permit+会话过期+高风险确认
PLC侧参数硬限幅+条件使能
每次关键操作写审计(谁/点/前后值)
密码哈希、默认账号降权
工控网络分段,Modbus端口不裸奔
工业权限分级的本质是“前端防误操作,后端防越权,PLC防绕过,日志防甩锅”。界面灰掉按钮只是第一道;真正拦非法操作的是业务方法里的权限位判断和下发前的范围校验;再往下PLC不认超界值,才算闭环。只做HMI登录的系统,在工控现场基本等于没做——懂协议的人根本不走界面。审计日志反而是最容易被省的一环,但真出工艺事故时,没有它连“谁动的”都说不清。





