提交 9d4efb4e authored 作者: 陈泽健's avatar 陈泽健

chore(debug): 删除多个临时调试脚本文件

- 移除 analyze_options.py 检查方案前提条件的脚本
- 移除 build_agent_correct.py Java Agent构建脚本
- 移除 build_agent_in_container.py 容器内编译脚本
- 移除 build_with_temp_container.py 临时容器编译脚本
- 移除 check_nginx_modules.py Nginx模块检查脚本
- 移除 check_nginx_real_config.py Nginx配置检查脚本
- 移除 correct_https_test.py HTTPS测试脚本
- 移除 create_jar.py JAR包创建脚本
- 移除 get_kkfile_nginx.py Nginx配置获取脚本
- 移除 implement_agent.py Java Agent实施方案脚本
- 移除 nginx_url_rewrite_test.py Nginx URL重写测试脚本
- 移除 parse_nginx_single_line.py 单行解析脚本
- 移除 plan_agent.py Agent方案计划脚本
- 移除 read_from_host.py 宿主机读取脚本
- 移除 read_nginx_direct.py 直接读取Nginx配置脚本
- 移除 real_browser_test.py 真实浏览器测试脚本
- 移除 rebuild_agent.py Agent重建脚本
- 移除 rebuild_clean.py 清理重建脚本
上级 5ea0cab6
# KKfile HTTPS适配 调试脚本
## 背景
KKfile 服务通过 Nginx 反向代理提供 HTTPS 访问,但文件预览时报 SSL 错误。
本目录存放调试过程中产生的临时诊断脚本。
## 最终结论(重要)
**问题根因:** 自签名证书无 SAN 字段,Java 8/11 用 `HttpsURLConnection` 下载 HTTPS 文件时强制主机名校验,无法通过任何配置绕过。
**最终解决方案:** 重新生成带 SAN 字段的自签名证书。
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /data/security/nginx_cert/private.key \
-out /data/security/nginx_cert/cert.pem \
-subj '/CN=192.168.5.70' \
-addext 'subjectAltName=IP:192.168.5.70'
```
然后把证书导入 KKfile 容器的 Java 信任库,重载 Nginx 和 KKfile。
## 已验证失败的方案(勿再尝试)
| 方案 | 失败原因 |
|------|----------|
| Java 8 导入证书 | 主机名校验(SAN)仍失败 |
| `base.url` 改内部 HTTP | 前端用 `window.location` 构造 URL,不读 base.url |
| Java 11 + `-Djdk.internal.httpclient.disableHostnameVerification` | 只对 `java.net.http.HttpClient` 有效,对 `HttpsURLConnection` 无效 |
| Nginx URL 参数改写 | Base64 编码的 url 参数无法正则替换 |
| Java Agent 注入 | 容器内缺少 jar 工具,编译打包复杂易失败 |
## 脚本说明
- `correct_https_test.py` — HTTPS 预览验证脚本(最常用)
- `real_browser_test.py` — 浏览器真实请求分析
- `check_nginx_*.py` — Nginx 配置和模块检查
- `get_kkfile_nginx.py` / `read_*.py` — 读取 Nginx 配置
- `build_agent_*.py` / `implement_agent.py` / `create_jar.py` / `rebuild_agent.py` — Java Agent 编译打包(已放弃)
- `nginx_url_rewrite_test.py` / `analyze_options.py` / `plan_agent.py` — 方案分析
- `rebuild_clean.py` — 容器重建恢复
- `disable_ssl_verify.java` — SSL 绕过 Agent 源码
## 相关文档
- 需求文档:`Docs/PRD/KKfile服务/KKfile服务适配https_需求文档.md`
- 执行计划:`Docs/PRD/KKfile服务/KKfile服务适配https_需求文档_计划执行.md`
## 注意
这些脚本是调试过程中的临时产物,服务器信息(IP/密码)已硬编码在其中,
仅用于参考和复现,**不建议直接复用于生产环境**
import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.net.URL;
public class DisableSSLVerify {
public static void disable() {
try {
// 创建信任所有证书的TrustManager
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
// 安装信任管理器
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// 禁用主机名验证
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
System.out.println("SSL verification disabled");
} catch (Exception e) {
e.printStackTrace();
}
}
}
# KKfile服务适配HTTPS 回溯记录
> **文档目的:** 完整记录 KKfile HTTPS 适配的实施过程、最终方案、遇到的问题及失败尝试,便于下次回溯。
> **创建日期:** 2026-06-18
> **状态:** ✅ 已解决
---
## 一、需求背景
- **服务器:** 192.168.5.70(UOS Server 20)
- **网页访问:** https://192.168.5.70/kkfile/index
- **核心目标:** 让 KKfile 文件预览/转换服务在 HTTPS 环境下正常使用
- **约束条件:** **保持自签名证书不变**(不更换为正式 CA 证书)
### 架构
```
浏览器 (HTTPS) → Nginx容器(unginx:443) → KKfile容器(kkfile:8012, HTTP)
```
### 关键配置文件
| 组件 | 路径 |
|------|------|
| Nginx 配置 | 宿主机 `/data/middleware/nginx/config/unified443.conf`(挂载到容器 `/etc/nginx/conf.d/`)|
| Nginx 证书 | `/data/security/nginx_cert/cert.pem``private.key`(只读挂载)|
| KKfile 配置 | 容器内 `/opt/kkFileView-4.1.0/config/application.properties` |
| Java 信任库 | 容器内 `/usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts` |
---
## 二、最终成功的方案
### 核心方案:重新生成带 SAN 字段的自签名证书
**根本原因:** 原自签名证书的 CN 为 `ldddgo.net`,且**没有 SAN(Subject Alternative Names)字段**。Java 用 `HttpsURLConnection` 下载 `https://192.168.5.70` 的文件时,强制做主机名匹配,因 CN/SAN 与访问 IP 不符,报 `No subject alternative names present`
**解决步骤:**
#### 1. 生成带 SAN 的新自签名证书
```bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /tmp/new_private.key \
-out /tmp/new_cert.pem \
-subj '/CN=192.168.5.70' \
-addext 'subjectAltName=IP:192.168.5.70'
```
关键点:**`-addext 'subjectAltName=IP:192.168.5.70'`** 是解决问题的一句话。
#### 2. 备份并替换 Nginx 证书
```bash
cp /data/security/nginx_cert/cert.pem /data/security/nginx_cert/cert.pem.bak
cp /data/security/nginx_cert/private.key /data/security/nginx_cert/private.key.bak
cp /tmp/new_cert.pem /data/security/nginx_cert/cert.pem
cp /tmp/new_private.key /data/security/nginx_cert/private.key
docker exec unginx nginx -t
docker exec unginx nginx -s reload
```
#### 3. 导入新证书到 KKfile 的 Java 信任库
```bash
docker cp /tmp/new_cert.pem kkfile:/tmp/nginx_cert.pem
docker exec kkfile keytool -delete -alias nginx-https-cert \
-keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit 2>/dev/null || true
docker exec kkfile keytool -import -alias nginx-https-cert \
-keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts \
-storepass changeit -file /tmp/nginx_cert.pem -noprompt
```
#### 4. 重启 KKfile
```bash
docker exec kkfile rm -rf /tmp/.jodconverter* # 清理临时文件(重要,见问题4)
docker restart kkfile
```
### KKfile 配置文件最终状态
```properties
# HTTPS 协议识别
server.forward-headers-strategy=NATIVE
server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto
# base.url 用外网 HTTPS(前端访问用)
base.url = https://192.168.5.70:443/kkfile
# 信任主机(不含端口和协议)
trust.host = 192.168.5.70,localhost,127.0.0.1,172.17.0.1
```
---
## 三、最终验证结果(✅ 通过)
| 验证项 | 结果 |
|--------|------|
| 证书 SAN 字段 | ✅ `IP Address:192.168.5.70` |
| Java 信任库导入 | ✅ `nginx-https-cert` 已信任 |
| HTTPS 访问首页 | ✅ 200 OK |
| Word 文件预览(HTTPS URL)| ✅ 成功,无 SSL 错误 |
| PDF 文件预览(HTTPS URL)| ✅ 成功,无 SSL 错误 |
| 日志无 `CertificateException` | ✅ |
**成功标志日志:**
```
预览文件url:https://192.168.5.70:443/kkfile/demo/test_word.docx,previewType:OFFICE
```
(无 `No subject alternative names present` 错误)
---
## 四、遇到的问题与失败尝试(重要回溯)
### 问题1:`No subject alternative names present`(核心问题)
**现象:** 预览 HTTPS URL 的文件时,KKfile 日志报:
```
javax.net.ssl.SSLHandshakeException: No subject alternative names present
```
**根因:** 自签名证书无 SAN,CN 为域名 `ldddgo.net`,访问 IP `192.168.5.70` 主机名不匹配。
**代码链路:** KKfile 4.1.0 下载文件 → `cn.keking.utils.DownloadUtils.downLoad``FileUtils.copyURLToFile``URL.openStream()``HttpsURLConnection` → Java 强制主机名校验。
### 尝试过且失败的方案(勿再重复尝试)
| # | 方案 | 失败原因 |
|---|------|----------|
| 1 | Java 8 导入证书到 `cacerts` | PKIX 信任通过,但**主机名校验**仍失败 |
| 2 | `base.url` 改为内部 HTTP(`http://172.17.0.1:8012`)| 前端 demo 页面用 `window.location.origin` 构造预览 URL,**不读取 base.url**,故无效 |
| 3 | Java 8 禁用主机名校验 | **Java 8 无任何 JVM 开关**可禁用 `HttpsURLConnection` 主机名校验 |
| 4 | 升级 Java 到 OpenJDK 11 + `-Djdk.internal.httpclient.disableHostnameVerification=true` | 该属性**只对 `java.net.http.HttpClient` 有效**,对 `HttpsURLConnection` 无效(KKfile 用的是后者)|
| 5 | Nginx 层改写预览 URL 参数 | 预览 URL 是 **Base64 编码**的,无法在 Nginx 用正则替换 |
| 6 | Java Agent 注入自定义 `TrustManager` + `HostnameVerifier` | 容器内缺 `jar` 工具,编译打包复杂,多次失败 |
> **结论:** Java 的 `HttpsURLConnection` 主机名校验**只能通过让证书包含正确 SAN 来解决**,无配置绕过方法。
### 问题2:`trust.host` 配置错误导致"不受信任的站点"
**现象:** 预览提示"预览源文件来自不受信任的站点:192.168.5.70"。
**原因:**`trust.host` 带了端口 `trust.host = 192.168.5.70:443`
**解决:** `trust.host` 只能写 IP/域名,**不能含端口和协议**
```properties
trust.host = 192.168.5.70,localhost,127.0.0.1,172.17.0.1
```
### 问题3:预览 URL 必须 Base64 编码
**现象:** 直接传明文 URL 报 `Illegal base64 character`
**原因:** KKfile 安全机制,预览 URL 参数必须 Base64 编码。
```
原始: https://192.168.5.70/kkfile/demo/test.docx
编码: aHR0cHM6Ly8xOTIuMTY4LjUuNzAv...
```
### 问题4:重建容器后 Office 启动失败(jodconverter pid 找不到)⚠️
**现象:** 容器重建/重启后,Spring Boot 启动失败,报:
```
java.lang.IllegalStateException: process with acceptString 'socket,host=127.0.0.1,port=2002' started but its pid could not be found
Application run failed
```
**根因:** `/tmp/.jodconverter*` 临时目录残留,导致 LibreOffice 第二个进程启动时 pid 冲突。
**解决:** 每次重启容器前**必须清理临时文件**
```bash
docker exec kkfile rm -rf /tmp/.jodconverter*
docker restart kkfile
```
偶尔需要重启 2-3 次才能成功(LibreOffice 启动有随机性)。
### 问题5:容器内文件修改不持久(重建丢失)⚠️
**现象:** 修改容器内 `application.properties``docker restart` 后配置恢复原样。
**根因:** `docker restart` 配置会保留,但 `docker run`(删除重建)会丢失所有改动。
**解决:** 重要改动用 `docker commit` 保存为新镜像,或通过 `docker run -e` 传环境变量,或用挂载卷。
---
## 五、容器与镜像现状
### 当前运行容器
- **kkfile**(正在运行):基于 `kkfile-ssl-disabled:latest` 镜像
- **unginx**(正在运行):基于 `nginx:1.30.2`
### 过程中产生的镜像(建议保留备份,无需清理)
| 镜像 | 说明 |
|------|------|
| `keking/kkfileview:latest` | 原始官方镜像(Java 8)|
| `kkfile-backup:with-office-working` | Java 8 正常工作状态备份 |
| `kkfile-java11:latest` | 升级到 Java 11 后的镜像 |
| `kkfile-ssl-disabled:latest` | **当前使用的镜像**(Java 11 + wrapper启动脚本)|
> ⚠️ 容器已从原始官方镜像升级到 **Java 11**(为尝试方案4),当前生产用的是 Java 11 版本。如需恢复 Java 8,用 `kkfile-backup:with-office-working`。
---
## 六、历史教训与注意事项
1. **自签名证书必须带 SAN**:Java 8+ 强制校验 SAN,CN 匹配已不够。生成证书时务必加 `-addext 'subjectAltName=IP:xxx'`
2. **客户端需重新信任**:更换证书后,所有客户端首次访问需手动信任新证书(自签名的固有限制)。
3. **勿随意删除重建生产容器**:本次为调试多次 `docker rm` 重建,一度导致服务中断。重建容器前**务必先 `docker commit` 备份**
4. **`JAVA_TOOL_OPTIONS` 生效验证**:日志出现 `Picked up JAVA_TOOL_OPTIONS: ...` 表示环境变量已注入 JVM。
5. **调试脚本已归档**:所有过程脚本在 `AuxiliaryTool/ScriptTool/问题处理/kkfile_https调试脚本/`
---
## 七、关键命令速查
```bash
# 查看证书 SAN
openssl x509 -in /data/security/nginx_cert/cert.pem -noout -text | grep -A1 'Subject Alternative Name'
# 查看信任库证书
docker exec kkfile keytool -list -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit -alias nginx-https-cert
# 查看预览日志(判断是否还有SSL错误)
docker logs kkfile --tail 30 2>&1 | grep -E '预览文件url|No subject|CertificateException'
# 安全重启 KKfile(带清理)
docker exec kkfile rm -rf /tmp/.jodconverter*
docker restart kkfile
# Nginx 重载
docker exec unginx nginx -t && docker exec unginx nginx -s reload
```
---
## 八、相关文档
- 需求文档:`KKfile服务适配https_需求文档.md`
- 执行计划:`KKfile服务适配https_需求文档_计划执行.md`
- 调试脚本:`AuxiliaryTool/ScriptTool/问题处理/kkfile_https调试脚本/`
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论