openplc runtime v4 安全

安全

概述

OpenPLC 运行时 v4 实施了多层安全防护,以抵御常见漏洞,并确保在工业环境中的安全运行。

TLS/HTTPS

自签名证书

运行时在首次启动时会自动生成自签名的 TLS 证书:

证书文件:

  • webserver/certOPENPLC.pem -- 证书
  • webserver/keyOPENPLC.pem -- 私钥

证书详情:

  • 密钥长度:2048 位 RSA
  • 有效期:365 天
  • 主题:CN=localhost
  • 主题备用名称:localhost、127.0.0.1 以及检测到的 IP 地址

实现代码: webserver/credentials.py

证书生成

证书生成过程包含多项安全校验:

  1. 主机名校验:防止在主机名字段中进行命令注入
  2. IP 地址校验:确保 IP 格式有效
  3. 路径校验:防止证书文件路径中的目录遍历攻击
  4. 自动续期:检查证书有效性,过期后自动重新生成

关键函数:

python 复制代码
CertGen.generate_self_signed_cert(cert_file, key_file)
CertGen.is_certificate_valid(cert_file)

使用自定义证书

如需使用自定义证书(例如来自 Let's Encrypt 的证书):

  1. 用您的证书替换 webserver/certOPENPLC.pem
  2. 用您的私钥替换 webserver/keyOPENPLC.pem
  3. 确保证书包含所有必要的主机名/IP
  4. 重启运行时

证书链:

若使用证书链,请将证书串联在一起:

bash 复制代码
cat your_cert.pem intermediate.pem root.pem > certOPENPLC.pem

身份认证

JWT 令牌

运行时使用 JSON Web 令牌(JWT)进行身份认证:

令牌存储:

  • 密钥保存在 /var/run/runtime/.env
  • 256 位十六进制密钥(64 字符)
  • 首次启动时自动生成

令牌用途:

  • WebSocket 调试接口需要 JWT 认证
  • 令牌通过 REST API 登录端点获取
  • 可通过重新生成密钥来吊销所有令牌

环境变量:

复制代码
JWT_SECRET_KEY=<64-character-hex-string>

密码安全

用户密码经过多层保护:

  1. 哈希:使用安全算法对密码进行哈希
  2. 盐值:每个用户拥有唯一的盐
  3. 胡椒 :全局 256 位胡椒,保存在 .env 文件中
  4. 数据库 :存储于 /var/run/runtime/restapi.db

环境变量:

复制代码
PEPPER=<64-character-hex-string>

配置管理

.env 文件在首次启动时自动生成,采用安全默认值:

路径: /var/run/runtime/.env

内容:

复制代码
SQLALCHEMY_DATABASE_URI=sqlite:////var/run/runtime/restapi.db
JWT_SECRET_KEY=<自动生成>
PEPPER=<自动生成>

权限:

  • 文件创建时带有受限权限
  • 仅运行时用户可访问
  • 不应提交至版本控制系统

实现代码: webserver/config.py

文件上传安全

ZIP 文件校验

上传的 ZIP 文件在解压前会经过全面的安全检查:

路径遍历防护

检查项:

  • 无绝对路径(以 / 开头)
  • 无父目录引用(..
  • 无盘符(: 字符)
  • 解压路径经验证始终位于目标目录内

示例拦截路径:

复制代码
/etc/passwd
../../../etc/passwd
C:\Windows\System32
大小限制

限制:

  • 单个文件最大:10 MB
  • 解压后总大小最大:50 MB
  • 在解压前即强制执行

目的: 防止资源耗尽和磁盘空间攻击

ZIP 炸弹检测

检查项: 压缩比必须 ≤ 1000:1

示例:

  • 压缩后:1 KB
  • 解压后:1 MB(比率 1000:1)-- 允许
  • 解压后:2 MB(比率 2000:1)-- 拦截

目的: 防止解压炸弹耗尽磁盘空间或内存

扩展名白名单

拦截的扩展名:

  • .exe -- Windows 可执行文件
  • .dll -- 动态链接库
  • .sh -- Shell 脚本
  • .bat -- 批处理文件
  • .js -- JavaScript 文件
  • .vbs -- VBScript 文件
  • .scr -- 屏幕保护程序(常被用作恶意软件)

目的: 防止执行恶意代码

macOS 元数据移除

移除项:

  • __MACOSX/ 目录
  • .DS_Store 文件

目的: 清除可能包含敏感信息的多余元数据

实现代码: webserver/plcapp_management.py

安全解压

解压过程还包含额外安全措施:

  1. 根目录剥离:自动移除单个顶层根文件夹
  2. 路径规范化:将所有路径转换为绝对路径并验证合法性
  3. 目录创建:安全地创建必要的子目录
  4. 原子操作:解压过程要么全部成功,要么全部回滚

进程安全

特权要求

运行时的某些操作需要提升权限:

  1. 实时调度:设置 SCHED_FIFO 优先级
  2. 套接字创建 :在 /run/runtime/ 中创建 Unix 域套接字
  3. 端口绑定:绑定至 8443 端口(特权端口)

建议: 使用 sudo 运行,或授予特定能力(capabilities):

bash 复制代码
sudo setcap cap_sys_nice,cap_net_bind_service=+ep build/plc_main

进程隔离

独立进程:

  • Web 服务器作为 Python 进程运行
  • PLC 运行时作为独立的 C/C++ 进程运行
  • 仅通过 Unix 域套接字通信

优势:

  • 一个进程崩溃不会影响另一个进程
  • 可实现不同级别的权限
  • 内存隔离

信号处理

运行时能够优雅地处理信号:

  • SIGINT:优雅关闭,清理资源
  • SIGTERM:优雅关闭
  • SIGSEGV:捕获并记录日志(如可能)

实现代码: core/src/plc_app/plc_main.c

网络安全

端口暴露

默认端口:

  • 8443 (HTTPS) -- OpenPLC 编辑器通信的 REST API

建议:

  • 使用防火墙限制访问
  • 仅暴露给可信网络
  • 远程访问可考虑使用 VPN

Docker 端口映射:

bash 复制代码
docker run -p 127.0.0.1:8443:8443 ...  # 仅本地回环
docker run -p 8443:8443 ...            # 所有接口

Unix 域套接字

套接字位置:

  • /run/runtime/plc_runtime.socket -- 命令套接字
  • /run/runtime/log_runtime.socket -- 日志套接字

安全性:

  • 仅本地系统可访问
  • 文件系统权限控制访问
  • 不暴露至网络

权限:

  • 创建时带有受限权限
  • 仅运行时用户可连接

数据安全

数据库

路径: /var/run/runtime/restapi.db

内容:

  • 用户账户
  • 哈希密码
  • 会话数据

保护措施:

  • 文件系统权限
  • SQLite 加密(如配置)
  • 建议定期备份

日志

敏感信息:

  • 日志可能包含变量值
  • IP 地址及连接信息
  • 带有文件路径的错误信息

建议:

  • 定期轮转日志
  • 限制日志文件访问权限
  • 共享前对日志进行脱敏处理

编译后程序

路径: build/libplc_*.so

内容:

  • 编译后的 PLC 逻辑
  • 变量定义
  • 自定义功能块

保护措施:

  • 文件系统权限
  • 不通过网络传输
  • 带时间戳以进行版本控制

Docker 安全

容器隔离

优势:

  • 与宿主机进程隔离
  • 网络隔离(除非显式暴露)
  • 文件系统隔离

注意事项:

  • 实时调度可能需要特权模式
  • 挂载卷会暴露宿主机目录
  • 端口暴露会创建网络访问入口

卷安全

持久化卷:

bash 复制代码
docker run -v openplc-runtime-data:/var/run/runtime ...

内容:

  • 含机密的 .env 文件
  • 含用户账户的数据库
  • 编译后的程序

建议:

  • 使用命名卷(而非绑定挂载)
  • 定期备份卷
  • 限制卷的访问权限

镜像安全

官方镜像: ghcr.io/autonomy-logic/openplc-runtime:latest

安全特性:

  • 基于 Debian bookworm-slim(最小攻击面)
  • 通过 CI/CD 定期更新
  • 多架构支持
  • 签名镜像(GitHub 容器仓库)

验证方法:

bash 复制代码
docker pull ghcr.io/autonomy-logic/openplc-runtime:latest
docker inspect ghcr.io/autonomy-logic/openplc-runtime:latest

安全最佳实践

部署

  1. 仅使用 HTTPS:切勿禁用 TLS
  2. 强密码:强制密码复杂度
  3. 定期更新:保持运行时及依赖项为最新
  4. 防火墙规则:限制网络访问
  5. 监控:监控日志以发现可疑活动

开发

  1. 代码审查:合并前审查所有变更
  2. 静态分析:使用 linter 和安全扫描工具
  3. 依赖项扫描:检查是否存在漏洞依赖
  4. 输入校验:验证所有用户输入
  5. 错误处理:错误信息中不暴露敏感信息

运维

  1. 定期备份 :备份 /var/run/runtime/ 目录
  2. 轮换密钥:定期重新生成 JWT 密钥和胡椒
  3. 审计日志:检查日志中的安全事件
  4. 更新证书:在证书过期前续期
  5. 最小权限原则:以所需的最低权限运行

漏洞报告

若发现安全漏洞:

  1. 请勿 公开提交 issue
  2. 私下联系维护者
  3. 提供详细的重现步骤
  4. 留出补丁开发时间
  5. 协调披露时间

安全局限性

已知限制

  1. 自签名证书:默认证书为自签名(OpenPLC 编辑器可自动处理)
  2. 无速率限制:API 端点未限制请求频率
  3. 无账户锁定:未提供暴力破解防护
  4. 无审计追踪:安全事件日志记录有限
  5. 无静态加密:数据库和文件未加密

未来改进

计划中的安全增强功能:

  • API 端点速率限制
  • 失败尝试后的账户锁定
  • 全面的审计日志
  • 数据库静态加密
  • 证书管理界面
  • 双因素认证
  • 基于角色的访问控制

合规性考虑

工业标准

运行时专为工业自动化设计,但未声称符合特定标准(如 IEC 62443)。各组织应:

  1. 进行安全评估
  2. 根据需要实施额外控制措施
  3. 遵循行业特定指南
  4. 记录安全配置

数据保护

对于有数据保护要求的环境(GDPR 等):

  1. 最小化数据收集
  2. 实施数据保留策略
  3. 提供数据导出功能
  4. 记录数据流
  5. 实施访问控制

相关文档

相关推荐
瘾大侠1 小时前
HTB 赛季10 - Pterodactyl - user
网络·安全·web安全·网络安全
加农炮手Jinx1 小时前
Flutter for OpenHarmony 实战:network_info_plus 网络扫描与隐私合规深度适配
网络·flutter·华为·harmonyos·鸿蒙
maplewen.2 小时前
C++ 内存对齐
开发语言·c++
柒儿吖2 小时前
三方库 Boost.Regex 在 OpenHarmony 的 lycium完整实践
c++·c#·openharmony
IT古董2 小时前
Next.js 本地 HTTPS + 自定义域名无法访问问题排查(Windows / mkcert / HSTS 完整指南)
windows·https·next.js
一只小小的芙厨2 小时前
寒假集训·子集枚举2
c++·笔记·算法·动态规划
Geoking.2 小时前
SPI 与 API 的区别详解
网络
kyle~2 小时前
ROS2----组件(Components)
开发语言·c++·机器人·ros2
阿猿收手吧!2 小时前
【C++】Ranges 工厂视图与投影机制
开发语言·c++