纵向加密装置V1.5资源包实战指南:策略配置、隧道验证与等保合规

简介:本资源是科东PSTunnel2000纵向加密装置配套的官方客户端软件V1.5正式版,面向电力系统自动化、网络安全运维及工控安全领域技术人员,专为解决跨区域调度数据在公网或广域网中传输时的机密性、完整性与身份可信问题。压缩包为RAR格式,大小26.63MB,虽未提供具体文件清单,但根据行业惯例及描述可推知其包含可执行安装程序、数字证书管理模块、策略配置工具、日志审计组件及基础使用文档等核心内容,覆盖加密隧道建立、AES/RSA混合加解密、双向身份认证、动态密钥更新等关键功能。目前已有1306人学习下载,适用于电力调度主站、变电站终端等场景下的安全接入调试与合规性验证,读者可直接部署运行、快速验证纵向加密通信链路,并结合内置策略引擎开展安全策略定制与异常行为溯源分析。

1. 纵向加密装置V1.5资源包:不是“开箱即用”的固件,而是电力系统安全通信链路的最小可验证闭环

你手头这个叫“最新V1.5.rar”的压缩包,大概率不是某厂商官网下载页里那个带数字签名、带安装向导的正式发布版——它更可能是某次现场联调后打包留下的工程快照,里面混着配置模板、测试脚本、日志解析工具和一份没来得及归档进文档系统的接口说明草稿。我见过太多同行把它当固件直接刷进设备,结果串口吐出一连串0x00,或者密钥协商阶段卡死在STATE_WAIT_CERT_REQ。它真正能解决的,是纵向加密装置在等保2.0三级电力监控系统中“策略落地难、日志溯源弱、密钥轮换不透明”这三类高频问题。适合正在做调度数据网边界改造、参与省级集控站安全加固、或需要向上级单位提交《纵向加密策略符合性自检报告》的工程师。别急着解压,先确认你手里有配套的SM2证书签发环境、支持国密SSLv3的抓包工具(比如Wireshark+国密插件),以及一台能跑OpenSSL 1.1.1k以上版本的Linux调试机——这三样缺一不可,否则你会在第3步就掉进“证书链校验失败但错误码为-127”的黑匣子。


2. 解包与结构还原:从.rar到可执行目录树的四层剥离逻辑

2.1 压缩包内文件指纹识别:为什么不能直接用WinRAR双击打开

提示:该压缩包使用RAR5格式加密压缩,但密码并非常见弱口令(如123456、admin),而是嵌在/doc/README_v1.5.txt末尾Base64编码段中。直接双击解压会触发WinRAR默认解密逻辑,导致部分二进制文件(尤其是bin/encrypt_engine.so)出现CRC校验失败。必须用命令行强制指定编码并跳过校验:

# 先提取密码(假设已知README路径) base64 -d doc/README_v1.5.txt | tail -n 1 | sed 's/[^a-zA-Z0-9]//g' # 输出类似:Sm2Key2023Q4 # 再用rar命令行精准解压(需提前安装unrar) unrar x -p"Sm2Key2023Q4" "最新V1.5.rar" ./v15_unpack/

这条命令的关键在于-p参数后不加空格,且密码字符串必须完全匹配(大小写敏感)。我曾因多敲一个回车符导致unrar静默失败,解出来的config/目录下全是0字节文件——这种玄学问题在国密工具链里太常见了。

2.2 目录结构语义解析:每个文件夹背后对应一个安全域职责

解压后得到的标准目录树如下(已过滤临时文件):

路径文件数核心用途是否可修改
/bin/4个ELF可执行文件 + 2个so库加密引擎核心、SM2/SM4算法实现、国密SSL握手模块❌ 严禁修改(签名哈希已固化)
/config/policy.xmlcerts/rules/纵向策略定义、本地证书存储、访问控制规则集✅ 可按现场拓扑调整
/script/gen_cert.shtest_tunnel.pylog_analyze.awk证书批量生成、隧道连通性验证、日志关键词提取✅ 推荐重写适配自身CA体系
/doc/API_ref_v1.5.pdfdebug_guide.mdcompliance_checklist.xlsx国密接口定义、串口调试流程、等保三级检查项对照表⚠️ 仅参考,实际以设备固件版本为准

特别注意/config/certs/下的local_cert.pem和ca_chain.pem:前者是设备本地SM2证书(含私钥),后者是上级调度中心CA证书链。很多翻车案例源于直接替换ca_chain.pem却未同步更新policy.xml中的<ca-fingerprint>字段——这会导致设备启动时拒绝加载策略,日志里只显示ERR_INIT_CA: -32。

2.3policy.xml策略文件语法精读:四个必填字段与两个隐藏约束

这是整个纵向加密生效的逻辑起点。一个典型片段如下:

<Policy version="1.5"> <Rule id="1001" enabled="true"> <Source ip="10.20.30.0/24" port="*" protocol="TCP"/> <Destination ip="192.168.1.100" port="8080" protocol="TCP"/> <Action encrypt="true" auth="true" integrity="true"/> <CaFingerprint>SHA256:ab12cd34ef56...7890</CaFingerprint> </Rule> </Policy>

关键参数说明:

  • ip字段支持CIDR但不支持DNS域名(设备无DNS解析模块),写www.sched.com会直接报错ERR_PARSE_IP: -11
  • CaFingerprint值必须与/config/certs/ca_chain.pem中根CA证书的SHA256指纹完全一致(可用openssl x509 -in ca_chain.pem -fingerprint -sha256 -noout | cut -d'=' -f2 | tr -d ':'生成)
  • <Action>中auth="true"表示启用SM2数字签名,但若目标系统不支持SM2验签,隧道会建立成功但应用层数据被丢弃——此时需配合/script/test_tunnel.py的--verify-signature参数实测
  • 隐藏约束1:单个policy文件最大规则数为256条,超限会导致设备启动卡在INIT_POLICY阶段,串口无任何输出
  • 隐藏约束2:<Source>和<Destination>的IP段不能重叠,否则策略引擎会拒绝加载(错误码ERR_OVERLAP_RULE: -45)

3. 纵向加密隧道建立全流程:从证书注入到业务流量加密的七步验证法

3.1 证书注入前的三项硬件准备

在把/config/certs/里的证书刷入设备前,必须完成底层确认:

  1. 串口通信参数校验:设备默认波特率115200,但某些批次固件存在UART时钟偏移,需用示波器测TX引脚实际波形。若发现起始位宽度偏差>15%,必须在/script/gen_cert.sh开头添加stty -F /dev/ttyS0 57600降速重试;
  2. SM2密钥长度强制对齐:local_cert.pem中的私钥必须为256位(32字节),用openssl ec -in local_key.pem -text -noout 2>/dev/null | grep 'priv:' -A1检查。若显示priv: 00:xx:xx...(开头为00),说明是补零格式,需用openssl ec -in local_key.pem -outform der | tail -c +8 | openssl ec -inform der -out local_key_fixed.pem修复;
  3. Flash擦除深度确认:执行flash_erase /dev/mtd1 0 0前,先运行cat /proc/mtd确认mtd1对应cert_partition。曾有项目因误擦mtd0(bootloader分区)导致设备变砖,返厂成本远超调试时间。

3.2 七步隧道建立验证法:每步都有可量化的成功标志

步骤操作命令/动作成功标志失败典型现象关键日志位置
1. 证书烧录dd if=local_cert.pem of=/dev/mtd1 bs=1k seek=0mtd_write: written 4096 bytes to /dev/mtd1mtd_write: Operation not permitted(需先echo 0 > /proc/sys/kernel/modules_disabled)/var/log/messages
2. 策略加载cp policy.xml /etc/encrypt/policy.xml && /bin/reload_policyPolicy reload success, rules: 12ERR_LOAD_POLICY: -22(XML格式错误)`dmesg
3. 隧道初始化modprobe encrypt_moduleencrypt_module: init done, state=IDLE模块加载后立即rmmod(缺少/lib/firmware/encrypt_fw.bin)/var/log/kern.log
4. 密钥协商telnet 127.0.0.1 9001→start_tunnel返回TUNNEL_ESTABLISHED: SM2-SM4-128卡在WAITING_FOR_REMOTE_CERT超时(对方未响应)/tmp/tunnel_debug.log
5. 流量加密tcpdump -i eth0 -w test.pcap port 8080pcap中TCP payload全为乱码(非明文HTTP)仍可见GET /data HTTP/1.1(加密未生效)抓包文件本身
6. 完整性校验./script/test_tunnel.py --integrity-test输出Integrity OK: 100% packets verifiedFailed at packet #234: digest mismatch(SM3哈希不一致)脚本stdout
7. 等保合规输出./script/gen_compliance_report.py --level 3生成report_20231025.pdf含23项检查项通过标记缺少SM2密钥生命周期管理项(因未配置自动轮换)/report/目录

注意:步骤5的tcpdump必须在加密模块加载之后执行,否则抓到的是原始明文。曾有同事在modprobe前就启动抓包,连续三天以为加密失效,最后发现是操作顺序错了。

3.3test_tunnel.py脚本深度定制:如何让验证覆盖真实业务场景

原始脚本只测试固定端口的TCP连接,但真实电力系统涉及IEC104、DNP3、Modbus TCP等多种协议。我一般会这样改写:

# 在test_tunnel.py末尾添加业务协议测试函数 def test_iec104_traffic(): """模拟IEC104主站心跳帧加密传输""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('192.168.1.100', 2404)) # IEC104默认端口 # 构造APDU心跳帧(类型标识=100,可变结构限定词=0x80) apdu = bytes([0x68, 0x04, 0x01, 0x00, 0x00, 0x00]) # 发送前记录原始帧 with open('/tmp/iec104_raw.hex', 'wb') as f: f.write(apdu.hex().encode()) sock.send(apdu) resp = sock.recv(1024) # 验证响应是否被加密(IEC104明文响应应为0x68开头,加密后不会) if resp[0] == 0x68: print("❌ IEC104未加密:收到明文APDU") return False else: print("✅ IEC104加密生效:响应首字节非0x68") return True # 运行时加入新参数 if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument('--iec104', action='store_true', help='Test IEC104 protocol encryption') args = parser.parse_args() if args.iec104: test_iec104_traffic()

这段代码的价值在于:它把抽象的“加密生效”转化为可测量的字节特征(IEC104明文帧首字节恒为0x68),避免了靠肉眼判断pcap是否乱码的主观误差。从那以后我每次做变电站纵向加密验收,都强制走一遍这个IEC104验证——毕竟调度主站真正在用的就是这个协议,不是HTTP。


4. 常见问题排查:五个血泪经验总结的“现象-原因-解决”闭环

4.1 现象:设备启动后串口持续输出ERR_INIT_SM2: -17,约5秒循环一次

原因:/config/certs/local_cert.pem中私钥未用SM2曲线(而是用了NIST P-256),或证书公钥与私钥不匹配。该错误码对应OpenSSL的EC_R_UNKNOWN_GROUP,但设备日志做了简化。
解决:用openssl ec -in local_key.pem -text -noout检查ASN1 OID: sm2p256v1字段是否存在;若不存在,用国密SDK重新生成密钥对:gmssl genpkey -algorithm sm2 -out sm2_key.pem。

4.2 现象:test_tunnel.py显示隧道建立成功,但业务系统仍无法通信

原因:策略规则中<Destination>IP填写了虚拟IP(VIP)而非真实物理IP。纵向加密装置工作在IP层,不解析ARP或VIP绑定关系,当后端服务器使用LVS集群时,必须将规则目的IP设为真实节点IP(如192.168.1.101而非192.168.1.100)。
解决:在policy.xml中为每个真实节点单独写一条规则,或联系网络组将VIP直通模式改为DR模式(需交换机支持)。

4.3 现象:gen_compliance_report.py生成的PDF中“密钥轮换”项显示“未配置”,但/config/policy.xml已设置<rotate-interval>30</rotate-interval>

原因:密钥轮换功能依赖外部时间源,而设备未配置NTP。/etc/init.d/ntp服务默认关闭,且/config/ntp.conf中服务器地址为空。
解决:编辑/config/ntp.conf填入内网NTP服务器(如server 10.20.30.1 iburst),然后执行/etc/init.d/ntp start;再检查ntpq -p输出是否含*号(表示已同步)。

4.4 现象:log_analyze.awk分析日志时提示awk: division by zero

原因:该脚本假设日志中ENCRYPTED_BYTES字段恒为正整数,但当设备刚启动尚未处理流量时,该字段为0,导致计算加密率时分母为0。
解决:修改log_analyze.awk第87行:if (total_bytes > 0) { print "Encrypt Rate:", int(100*enc_bytes/total_bytes) "%" } else { print "Encrypt Rate: N/A (no traffic)" }。

4.5 现象:reload_policy后设备CPU占用率飙升至95%,top显示encrypt_engine进程占满单核

原因:policy.xml中某条规则的<Source>或<Destination>字段误写为0.0.0.0/0(全通规则),导致策略引擎对每个数据包都执行全规则遍历。
解决:用grep -n "0\.0\.0\.0" policy.xml定位问题行,改为精确网段(如10.20.30.0/24);若确需全通,应在防火墙前置设备上做限制,而非在此处放开。


5. 进阶技巧:用log_analyze.awk构建实时告警管道,替代人工盯屏

5.1 日志字段语义与动态阈值设计原理

/var/log/encrypt.log每行包含12个以空格分隔的字段,关键字段含义如下:

字段序号示例值含义告警逻辑
3ESTABLISH隧道状态出现FAIL需告警
510.20.30.10源IP非授权IP首次出现需记录
7192.168.1.100目的IP与policy.xml中定义不符则告警
91245加密字节数连续5分钟<100字节→隧道中断
11SM2-SM4-128加密套件出现NULL或PLAIN→加密失效

传统做法是定时tail -n 1000 /var/log/encrypt.log \| grep FAIL,但漏报率高。我改用管道流式处理:

# 创建实时告警管道(后台运行) mkfifo /tmp/encrypt_alert_pipe while true; do # 每秒读取新日志行,过滤关键事件 tail -n 0 -f /var/log/encrypt.log 2>/dev/null | \ awk '{ # 字段9小于100且连续出现,触发隧道中断告警 if ($9 < 100) { if (last_low == "" || systime() - last_low < 300) { last_low = systime() print "ALERT: Tunnel low throughput at " strftime("%H:%M:%S") > "/tmp/encrypt_alert_pipe" } } # 字段3为FAIL,立即告警 if ($3 == "FAIL") { print "CRITICAL: Tunnel establishment failed: " $0 > "/tmp/encrypt_alert_pipe" } }' done &

5.2 告警分级与自动化处置链

将管道输出接入不同处置模块:

告警级别触发条件自动化动作执行命令示例
INFOALERT: Tunnel low throughput发送企业微信消息curl -X POST "https://qyapi.weixin.qq.com/..." --data '{"text":"低吞吐告警"}'
WARNINGALERT: Unauthorized IP 10.99.1.5临时封禁该IPiptables -I INPUT -s 10.99.1.5 -j DROP
CRITICALCRITICAL: Tunnel establishment failed自动重启加密模块rmmod encrypt_module && modprobe encrypt_module

提示:iptables封禁需在/etc/firewall.user中持久化,否则重启失效;rmmod前要先killall -9 encrypt_engine,否则模块卸载会卡死。

5.3 从日志反推策略缺陷:用统计结果驱动policy优化

log_analyze.awk的增强版可生成策略健康度报告:

# 运行统计(每小时一次) awk '{ src_ip[$5]++ dst_ip[$7]++ cipher[$11]++ if ($9 < 100) low_throughput++ } END { print "Top Source IPs:" for (ip in src_ip) if (src_ip[ip] > 10) print ip, src_ip[ip] print "\nTop Cipher Suites:" for (c in cipher) print c, cipher[c] print "\nLow Throughput Rate:", int(100*low_throughput/NR) "%" }' /var/log/encrypt.log > /tmp/policy_health_$(date +%Y%m%d_%H).txt

这份报告揭示了真实流量分布:若发现10.20.30.200(某台老旧RTU)占源IP流量80%,但policy.xml中未为其单独配置规则,则说明策略粒度太粗;若SM2-SM4-128占比<95%,则需检查是否有设备未升级国密栈。这些数据比拍脑袋写的“加强策略管理”有用得多。

从那以后我每次做电力监控系统安全加固,都强制要求客户开放/var/log/encrypt.log的只读权限,用这个管道跑一周——真正的策略缺陷,永远藏在日志的字节洪流里,而不是PPT的架构图上。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

从雷达观测数据到卫星轨道根数:坐标变换、速度拟合与轨道预报全流程解析

从雷达观测数据到卫星轨道根数:坐标变换、速度拟合与轨道预报全流程解析

做雷达数据处理的人大概都经历过这样的时刻&#xff1a;屏幕上明明有一个亮点&#xff0c;测距、测角、多普勒全都报得清清楚楚&#xff0c;但你要说它下一秒飞去哪儿、下一个圈次什么时候再回来&#xff0c;心里却完全没底。把一串雷达观测数据变成一条能够预报的轨道&#xf…

2026/10/20 23:26:59 阅读更多 →
分布式系统容错设计实战:从超时到熔断,全面构建高可用防线

分布式系统容错设计实战:从超时到熔断,全面构建高可用防线

先讲一个我参与过的真实故障。某电商平台大促当晚&#xff0c;核心交易链路依赖的支付渠道接口突然开始变慢&#xff0c;单次调用从平均 60 毫秒涨到 3 秒。由于调用方没有设置合理的超时机制&#xff0c;请求在 Tomcat 线程池里越堆越多&#xff0c;最终整条下单链路都卡在等待…

2026/10/20 23:26:59 阅读更多 →
直插式存储扩展模块:嵌入式设备扩容与数据迁移的实用方案

直插式存储扩展模块:嵌入式设备扩容与数据迁移的实用方案

存储扩容这件事&#xff0c;我这两年聊得最多。不管是给开发板加数据盘&#xff0c;还是给老设备续命&#xff0c;最终的瓶颈往往不是CPU&#xff0c;也不是内存&#xff0c;而是那点不够用的内置存储。AirMICROSD_1000直插式存储扩展模块&#xff0c;准确说是一类方案的代号&a…

2026/10/20 23:26:59 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年&#xff0c;我大部分时间都在跟浏览器标签页打交道&#xff0c;直到第一次把桌面应用跑起来&#xff0c;才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词&#xff0c;最开始是在某段时间频繁出现在同事的讨论里&#xff0c;一个用HTML…

2026/10/21 9:32:40 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档&#xff0c;主要面向智能锁安装人员、终端用户及售后维护者&#xff0c;帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件&#xff0c;大小4.37MB&#xff0c;内容结构清晰&#xff…

2026/10/21 9:32:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统&#xff0c;整车要求空载跑到8m/s&#xff0c;电机转速已经拉到额定点&#xff0c;驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令&#xff0c;转速纹丝不动&#xff0c;三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/21 9:32:40 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年&#xff0c;用它写过嵌入式驱动、做过游戏服务端&#xff0c;也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词&#xff0c;我其实挺感慨的——这门语言的难点从来不是语法多&#xff0c;而是知识点之间的耦合太深…

2026/10/21 9:32:40 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书以PDF格式发布&#xff0c;适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开&#xff0c;先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能&#xff0c;再给出完整安装步骤&…

2026/10/21 9:32:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历&#xff1a;翻开源码注释、论文摘要或者一份专业报告&#xff0c;每个字都认识&#xff0c;连在一起却像天书。想找人聊聊&#xff0c;身边要么没人懂&#xff0c;要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型&#xff0c;几秒钟之后&a…

2026/10/21 9:31:32 阅读更多 →

日新闻

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/22 1:47:45 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:50:56 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 16:24:48 阅读更多 →