提交 60cb0c13 authored 作者: 陈泽健's avatar 陈泽健

remove(script): 删除 kkfile https 调试相关脚本文件

- 移除 analyze_options.py 分析方案前提条件脚本
- 移除 browser_real_test.py 浏览器真实预览测试脚本
- 移除 build_agent_correct.py 构建Java Agent脚本
- 移除 build_agent_in_container.py 容器内构建Agent脚本
- 移除 build_with_temp_container.py 临时容器构建脚本
- 移除 check_all_certs.py 证书检查脚本
- 移除 check_current_status.py 当前状态检查脚本
- 移除 check_nginx_modules.py Nginx模块检查脚本
- 移除 check_nginx_real_config.py Nginx配置检查脚本
- 移除 cleanup_images.py 镜像清理脚本
- 移除 correct_https_test.py 正确HTTPS测试脚本
- 移除 create_jar.py JAR包创建脚本
- 移除 final_restart_test.py 最终重启测试脚本
- 移除 final_verify_env.py 环境验证脚本
- 移除 fix_trust_and_test.py 信任库修复测试脚本
上级 bacba599
# 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/密码)已硬编码在其中,
仅用于参考和复现,**不建议直接复用于生产环境**
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""分析所有可行方案,检查关键前提条件"""
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("="*70)
print("检查各方案的前提条件")
print("="*70)
# 方案C前提:Nginx是否支持改写URL参数
print("\n1. Nginx是否支持(检查lua/sub_filter模块):")
out, _ = run(ssh, "docker exec unginx nginx -V 2>&1 | head -3")
print(out[:300] if out else "无")
# 方案D前提:KKfile的启动脚本是否可改
print("\n2. 检查能否通过Java代码注入(-javaagent):")
out, _ = run(ssh, "docker exec kkfile which javac 2>&1 || echo '无javac编译器'")
print(out)
# 方案E:检查是否可以用HttpClient替代
print("\n3. 检查证书是否可以用curl方式代理下载")
# 关键:检查前端到底怎么传URL(确认前端构造逻辑)
print("\n4. 检查前端页面如何构造预览URL:")
out, _ = run(ssh, "docker exec kkfile find / -name '*.ftl' 2>/dev/null | head -10")
print(f"FTL文件: {out if out else '未找到'}")
# 检查jar包内的前端资源
out, _ = run(ssh, "docker exec kkfile ls /opt/kkFileView-4.1.0/web/ 2>/dev/null || echo '无web目录'")
print(f"web目录: {out}")
ssh.close()
#!/usr/bin/env python
import paramiko, base64, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("模拟浏览器完整预览流程(获取实际页面内容):")
# 1. 模拟浏览器访问首页,看base.url在前端如何呈现
print("\n1. 首页HTML中baseUrl的实际值:")
out, _ = run(ssh, "curl -k -s https://192.168.5.70/kkfile/index | grep -oE 'baseUrl[^<]*' | head -3")
print(out if out else "未找到baseUrl")
out, _ = run(ssh, "curl -k -s https://192.168.5.70/kkfile/index | grep -oE 'window.location[^<\"]*' | head -3")
print(out if out else "")
# 2. 上传一个真实的Office文件并完整预览
print("\n2. 上传真实Word文件:")
run(ssh, "echo '浏览器真实预览测试 - 这是Word文档内容' > /tmp/browser_test.docx")
out, _ = run(ssh, "curl -k -s -X POST -F 'file=@/tmp/browser_test.docx' https://192.168.5.70/kkfile/fileUpload")
print(f" {out}")
time.sleep(3)
# 3. 获取预览页面完整内容
print("\n3. 获取预览页面完整内容:")
file_url = "https://192.168.5.70:443/kkfile/demo/browser_test.docx"
enc = base64.b64encode(file_url.encode()).decode()
out, _ = run(ssh, f"curl -k -s 'https://192.168.5.70/kkfile/onlinePreview?url={enc}'")
# 看是否有错误提示
if "不受信任" in out or "证书" in out or "error" in out.lower():
print(" ⚠️ 预览页面含错误信息")
print(out[:500])
else:
print(" ✓ 预览页面正常返回")
# 提取title
import re
title = re.search(r'<title>(.*?)</title>', out)
print(f" 页面标题: {title.group(1) if title else '无'}")
time.sleep(8)
# 4. 检查转换是否真正完成
print("\n4. 检查转换结果日志:")
out, _ = run(ssh, "docker logs kkfile --tail 30 2>&1 | grep -E '预览文件url|转换|downloaded|成功|失败|Exception'")
print(out if out.strip() else "无异常")
# 5. 确认文件已下载转换(检查文件目录)
print("\n5. 转换后的文件(PDF):")
out, _ = run(ssh, "docker exec kkfile find /opt/kkFileView-4.1.0/file/ -name 'browser_test*' 2>/dev/null")
print(out if out.strip() else "未找到转换文件")
ssh.close()
#!/usr/bin/env python
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("在已停止状态(不启动)下修改容器文件...")
# 先停止容器
run(ssh, "docker stop kkfile")
# 在停止的容器上执行编译(用docker exec -it --user root 可以操作文件系统)
print("1. 写入Java Agent源码...")
agent_code = '''import javax.net.ssl.*;import java.security.cert.*;import java.lang.instrument.*;
public class SSLBypassAgent{
public static void premain(String a,Instrumentation i){
try{TrustManager[] t=new TrustManager[]{new X509TrustManager(){public X509Certificate[] getAcceptedIssuers(){return null;}public void checkClientTrusted(X509Certificate[]c,String s){}public void checkServerTrusted(X509Certificate[]c,String s){}}};
SSLContext sc=SSLContext.getInstance("TLS");sc.init(null,t,new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((h,s)->true);
}catch(Exception e){e.printStackTrace();}
}}'''
manifest = 'Manifest-Version: 1.0\nPremain-Class: SSLBypassAgent\n'
# 在宿主机上创建好所有文件,然后cp到容器
run(ssh, f"echo '{agent_code}' > /tmp/SSLBypassAgent.java")
run(ssh, f"mkdir -p /tmp/META-INF && echo '{manifest}' > /tmp/META-INF/MANIFEST.MF")
# 编译
print("2. 编译(在容器内编译)...")
run(ssh, "docker cp /tmp/SSLBypassAgent.java kkfile:/tmp/")
out, err = run(ssh, "docker exec kkfile javac /tmp/SSLBypassAgent.java")
print(f"编译: {err if err else '成功'}")
# 打包
print("3. 打包JAR(在容器内)...")
# 先复制manifest到容器
run(ssh, "docker cp /tmp/META-INF kkfile:/tmp/")
# 检查是否有jar命令
out, err = run(ssh, "docker exec kkfile which jar")
if err.strip():
# 没有jar,在宿主机打包
run(ssh, "docker cp kkfile:/tmp/SSLBypassAgent.class /tmp/")
run(ssh, "cd /tmp && zip ssl-bypass-agent.jar META-INF/MANIFEST.MF SSLBypassAgent.class")
run(ssh, "docker cp /tmp/ssl-bypass-agent.jar kkfile:/opt/")
else:
run(ssh, "docker exec kkfile bash -c 'cd /tmp && jar cfm /opt/ssl-bypass-agent.jar META-INF/MANIFEST.MF SSLBypassAgent.class'")
# 验证JAR
print("4. 验证JAR内容...")
out, _ = run(ssh, "docker exec kkfile unzip -l /opt/ssl-bypass-agent.jar")
print(out)
# 修改wrapper脚本(添加-javaagent)
print("5. 修改wrapper脚本...")
wrapper = '''#!/bin/bash
rm -rf /tmp/.jodconverter* /tmp/hsperfdata* 2>/dev/null
exec java -javaagent:/opt/ssl-bypass-agent.jar -Dfile.encoding=UTF-8 -Dspring.config.location=/opt/kkFileView-4.1.0/config/application.properties -jar /opt/kkFileView-4.1.0/bin/kkFileView-4.1.0.jar
'''
run(ssh, f"docker exec kkfile bash -c 'cat > /opt/start.sh << \"EOF\"\n{wrapper}\nEOF'")
run(ssh, "docker exec kkfile chmod +x /opt/start.sh")
# commit镜像
print("6. 提交镜像...")
out, _ = run(ssh, "docker commit kkfile kkfile-agent-final:latest")
print(f"镜像: {out.strip()}")
# 启动
print("7. 启动容器...")
run(ssh, "docker start kkfile")
time.sleep(70)
# 验证
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep -E 'SSL.*disabled|启动完成' | tail -2")
print(f"日志: {out}")
ssh.close()
#!/usr/bin/env python
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("在容器内编译和打包Agent...")
# 写入Java源码到容器
agent_code = '''
import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.lang.instrument.Instrumentation;
public class SSLBypassAgent {
public static void premain(String args, Instrumentation inst) {
try {
TrustManager[] trustAll = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] c, String a) {}
public void checkServerTrusted(X509Certificate[] c, String a) {}
}
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAll, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
System.out.println("[SSLBypassAgent] SSL verification disabled successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
'''
manifest = '''Manifest-Version: 1.0
Premain-Class: SSLBypassAgent
'''
# 写入文件
run(ssh, f"docker exec kkfile bash -c 'cat > /tmp/SSLBypassAgent.java << \"JAVAEOF\"\n{agent_code}\nJAVAEOF'")
run(ssh, f"docker exec kkfile bash -c 'mkdir -p /tmp/META-INF && cat > /tmp/META-INF/MANIFEST.MF << \"MFEOF\"\n{manifest}\nMFEOF'")
# 编译
print("编译...")
out, err = run(ssh, "docker exec kkfile javac /tmp/SSLBypassAgent.java -d /tmp/")
if "error" in err.lower():
print(f"编译错误: {err}")
# 可能缺少jar命令,用javac直接编译
print("编译完成")
# 检查class文件
out, _ = run(ssh, "docker exec kkfile ls -la /tmp/SSLBypassAgent.class")
print(f"class文件: {out}")
# 用jar或zip打包
print("\n打包JAR...")
out, err = run(ssh, "docker exec kkfile bash -c 'cd /tmp && jar cfm ssl-bypass-agent.jar META-INF/MANIFEST.MF SSLBypassAgent.class' 2>&1")
if "jar" in err.lower() or "command not found" in err.lower():
print("jar命令不存在,尝试用zip...")
out, err = run(ssh, "docker exec kkfile bash -c 'cd /tmp && zip ssl-bypass-agent.jar META-INF/MANIFEST.MF SSLBypassAgent.class'")
print(f"打包结果: {out}{err}")
# 验证JAR
out, _ = run(ssh, "docker exec kkfile unzip -l /tmp/ssl-bypass-agent.jar")
print(f"JAR内容:\n{out}")
# 移动到/opt
run(ssh, "docker exec kkfile mv /tmp/ssl-bypass-agent.jar /opt/")
# 重启容器
print("\n重启容器...")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter*")
run(ssh, "docker restart kkfile")
time.sleep(70)
# 验证
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep -E 'SSLBypassAgent|disabled|启动完成' | tail -3")
print(f"日志: {out}")
ssh.close()
#!/usr/bin/env python
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("用临时容器编译Agent JAR...")
agent_code = '''import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.lang.instrument.Instrumentation;
public class SSLBypassAgent {
public static void premain(String args, Instrumentation inst) {
try {
TrustManager[] trustAll = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(X509Certificate[] c, String s) {}
public void checkServerTrusted(X509Certificate[] c, String s) {}
}
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAll, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
System.out.println("[SSLBypassAgent] SSL verification disabled");
} catch (Exception e) {
e.printStackTrace();
}
}
}'''
manifest = 'Manifest-Version: 1.0\nPremain-Class: SSLBypassAgent\n'
# 写文件到宿主机
run(ssh, f"echo '{agent_code}' > /tmp/SSLBypassAgent.java")
run(ssh, f"mkdir -p /tmp/META-INF && printf '{manifest}' > /tmp/META-INF/MANIFEST.MF")
# 用临时容器(基于jdk镜像)编译
print("1. 启动临时编译容器...")
run(ssh, "docker rm -f temp-builder 2>/dev/null")
run(ssh, "docker run -d --name temp-builder -v /tmp:/work openjdk:11 sleep 600")
time.sleep(5)
print("2. 在临时容器内编译...")
out, err = run(ssh, "docker exec temp-builder javac /work/SSLBypassAgent.java -d /work")
print(f"编译: {err if err.strip() else '成功'}")
print("3. 在临时容器内打包JAR...")
out, err = run(ssh, "docker exec temp-builder bash -c 'cd /work && jar cfm ssl-bypass-agent.jar META-INF/MANIFEST.MF SSLBypassAgent.class'")
print(f"打包: {err if err.strip() else '成功'}")
print("4. 验证JAR...")
out, _ = run(ssh, "unzip -l /tmp/ssl-bypass-agent.jar")
print(out)
# 清理临时容器
run(ssh, "docker rm -f temp-builder")
# 复制到目标容器
print("5. 复制到kkfile容器...")
run(ssh, "docker cp /tmp/ssl-bypass-agent.jar kkfile:/opt/ssl-bypass-agent.jar")
# 修改wrapper脚本
print("6. 修改wrapper脚本...")
wrapper = '''#!/bin/bash
rm -rf /tmp/.jodconverter* /tmp/hsperfdata* 2>/dev/null
exec java -javaagent:/opt/ssl-bypass-agent.jar -Dfile.encoding=UTF-8 -Dspring.config.location=/opt/kkFileView-4.1.0/config/application.properties -jar /opt/kkFileView-4.1.0/bin/kkFileView-4.1.0.jar
'''
run(ssh, f"docker exec kkfile bash -c 'cat > /opt/start.sh << \"EOF\"\n{wrapper}\nEOF'")
run(ssh, "docker exec kkfile chmod +x /opt/start.sh")
# commit
print("7. 提交镜像...")
out, _ = run(ssh, "docker commit kkfile kkfile-agent-final:latest")
print(f"镜像: {out.strip()[:30]}...")
# 重启
print("8. 重启容器...")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter*")
run(ssh, "docker restart kkfile")
time.sleep(70)
# 验证
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep -E 'SSL.*disabled|启动完成' | tail -2")
print(f"日志: {out}")
ssh.close()
# -*- coding: utf-8 -*-
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("1. Nginx当前使用的证书SAN:")
out, _ = run(ssh, "openssl x509 -in /data/security/nginx_cert/cert.pem -noout -text | grep -A1 'Subject Alternative'")
print(" " + out.strip().replace("\n"," "))
out, _ = run(ssh, "openssl x509 -in /data/security/nginx_cert/cert.pem -noout -fingerprint -sha256")
print(" " + out.strip())
print("\n2. /tmp/new_cert.pem 的SAN:")
out, _ = run(ssh, "openssl x509 -in /tmp/new_cert.pem -noout -text | grep -A1 'Subject Alternative'")
print(" " + out.strip().replace("\n"," "))
out, _ = run(ssh, "openssl x509 -in /tmp/new_cert.pem -noout -fingerprint -sha256")
print(" " + out.strip())
print("\n3. /tmp/new_cert.pem 是否存在:")
out, _ = run(ssh, "ls -la /tmp/new_cert.pem /tmp/new_private.key 2>&1")
print(out.strip())
# 服务状态
print("\n4. 服务状态:")
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f" HTTP: {out}")
ssh.close()
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("="*60)
print("当前服务状态检查")
print("="*60)
print("\n1. 容器状态:")
out, _ = run(ssh, "docker ps --format '{{.Names}}\t{{.Status}}\t{{.Image}}' | grep -E 'kkfile|unginx'")
print(out)
print("\n2. 服务可用性:")
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f" KKfile直连(8012): {out}")
out, _ = run(ssh, "curl -k -s -o /dev/null -w '%{http_code}' https://192.168.5.70/kkfile/index")
print(f" HTTPS访问: {out}")
print("\n3. 证书SAN:")
out, _ = run(ssh, "openssl x509 -in /data/security/nginx_cert/cert.pem -noout -text | grep -A1 'Subject Alternative'")
print(" " + out.strip().replace("\n", " | "))
print("\n4. Java信任库:")
out, _ = run(ssh, "docker exec kkfile keytool -list -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit -alias nginx-https-cert 2>&1 | head -2")
print(" " + out.strip().replace("\n", " | "))
print("\n5. 配置:")
out, _ = run(ssh, "docker exec kkfile grep -E '^base.url|^trust.host' /opt/kkFileView-4.1.0/config/application.properties")
print(" " + out.strip().replace("\n", " | "))
ssh.close()
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 检查Nginx编译模块
out, _ = run(ssh, "docker exec unginx nginx -V 2>&1")
# 查找关键模块
modules = []
if '--with-http_sub_module' in out: modules.append('sub_filter')
if 'lua' in out.lower(): modules.append('lua')
if '--with-pcre' in out: modules.append('pcre_regex')
print(f"Nginx版本和模块:")
print(out[:400])
print(f"\n可用功能: {modules if modules else '标准模块'}")
# 检查是否可以用map指令
print("\n检查能否用map/if指令改写URL:")
out2, _ = run(ssh, "docker exec unginx cat /etc/nginx/nginx.conf | head -30")
print(out2[:300])
ssh.close()
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 检查nginx.conf主配置
print("1. 查看nginx.conf主配置include部分:")
out, _ = run(ssh, "docker exec unginx cat /etc/nginx/nginx.conf | grep include")
print(out)
# 检查conf.d目录
print("\n2. 查看conf.d目录内容:")
out, _ = run(ssh, "docker exec unginx ls -la /etc/nginx/conf.d/")
print(out)
# 检查实际监听443的配置
print("\n3. 查找监听443的server块:")
out, _ = run(ssh, "docker exec unginx grep -r 'listen 443' /etc/nginx/ 2>/dev/null")
print(out[:300] if out else "无")
# 检查挂载信息
print("\n4. 检查容器挂载:")
out, _ = run(ssh, "docker inspect unginx --format='{{json .Mounts}}' | python3 -m json.tool 2>/dev/null || docker inspect unginx --format='{{range .Mounts}}{{.Source}} -> {{.Destination}}\n{{end}}'")
print(out)
ssh.close()
# -*- coding: utf-8 -*-
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("清理过程镜像(保留最终镜像和原始镜像)...")
# 保留: keking/kkfileview:latest(原始), kkfile-https-final:latest(最终), kkfile-ssl-disabled:latest(当前运行)
# 删除中间调试镜像
images_to_remove = [
"kkfile-agent-final:latest",
"kkfile-before-env-fix:latest",
"kkfile-ssl-fix:latest",
"kkfile-with-agent:latest",
"kkfile-backup:with-office-working",
]
for img in images_to_remove:
out, err = run(ssh, f"docker rmi {img} 2>&1")
status = "已删除" if "Deleted" in out or "Untagged" in out else "跳过"
print(f" {img}: {status}")
print("\n保留的镜像:")
out, _ = run(ssh, "docker images | grep kkfile")
print(out)
ssh.close()
#!/usr/bin/env python
import paramiko, base64, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("使用正确的HTTPS URL测试预览...")
# 1. 上传一个真实的中文文件名Word文件
print("\n1. 上传中文文件名Word文档:")
run(ssh, "echo '中文文件名测试内容' > /tmp/会议使用.docx")
out, _ = run(ssh, "curl -k -s -X POST -F 'file=@/tmp/会议使用.docx' https://192.168.5.70/kkfile/fileUpload")
print(f"上传结果: {out}")
time.sleep(3)
# 2. 查看文件列表
print("\n2. 查看已上传文件:")
out, _ = run(ssh, "curl -k -s 'https://192.168.5.70/kkfile/listFiles'")
print(f"文件列表: {out}")
# 3. 用正确的HTTPS URL预览(带/kkfile/前缀)
print("\n3. 使用正确的HTTPS预览URL:")
# 文件URL应该是 https://192.168.5.70/kkfile/demo/会议使用.docx
# 但需要Base64编码整个URL
file_url = "https://192.168.5.70:443/kkfile/demo/%E4%BC%9A%E8%AE%AE%E4%BD%BF%E7%94%A8.docx"
encoded = base64.b64encode(file_url.encode('utf-8')).decode('utf-8')
print(f"原始URL: {file_url}")
print(f"Base64编码: {encoded}")
preview_url = f"https://192.168.5.70/kkfile/onlinePreview?url={encoded}"
print(f"\n预览URL: {preview_url}")
out, _ = run(ssh, f"curl -k -s '{preview_url}' | head -15")
print(f"预览响应:\n{out}")
# 4. 等待并检查日志
time.sleep(8)
print("\n4. 检查日志(是否成功处理):")
out, _ = run(ssh, "docker logs kkfile --tail 20 2>&1 | grep -E '预览文件url|下载|CertificateException|No subject|SSL'")
print(out if out.strip() else "无SSL错误!")
ssh.close()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""用zip创建JAR文件"""
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("用zip打包JAR...")
# JAR本质是ZIP,用zip命令打包
out, err = run(ssh, "cd /tmp && zip -r ssl-bypass-agent.jar META-INF SSLBypassAgent.class")
print(f"打包: {out}{err}")
print("\n复制到容器...")
run(ssh, "docker cp /tmp/ssl-bypass-agent.jar kkfile:/opt/ssl-bypass-agent.jar")
print("已复制")
print("\n验证JAR内容:")
out, _ = run(ssh, "docker exec kkfile unzip -l /opt/ssl-bypass-agent.jar 2>&1 | head -10")
print(out)
print("\n重启容器...")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter*")
run(ssh, "docker restart kkfile")
time.sleep(70)
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP状态: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep -E 'SSLBypassAgent|启动完成' | tail -2")
print(f"启动日志: {out}")
ssh.close()
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();
}
}
}
# -*- coding: utf-8 -*-
import paramiko, time, base64
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("1. 确认信任库证书指纹(详细):")
out, _ = run(ssh, "docker exec kkfile keytool -list -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit -v -alias nginx-https-cert 2>&1")
# 只取关键行
for line in out.split("\n"):
if "SHA256" in line or "SHA1" in line or "nginx-https-cert" in line or "trustedCertEntry" in line:
print(" " + line.strip())
print("\n2. 重启容器让信任库生效(清理+重启):")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter*")
run(ssh, "docker restart kkfile")
for i in range(3):
time.sleep(60)
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
if out == "200":
print(f" HTTP: 200 (第{i+1}次检查时成功)")
break
print(f" HTTP: {out},继续等待...")
print("\n3. 最终HTTPS预览转换测试:")
run(ssh, "echo 'final final test' > /tmp/ff.docx")
run(ssh, "curl -k -s -X POST -F 'file=@/tmp/ff.docx' https://192.168.5.70/kkfile/fileUpload")
time.sleep(2)
file_url = "https://192.168.5.70:443/kkfile/demo/ff.docx"
enc = base64.b64encode(file_url.encode()).decode()
run(ssh, f"curl -k -s 'https://192.168.5.70/kkfile/onlinePreview?url={enc}' > /dev/null")
time.sleep(12)
print("\n4. 检查PDF生成(转换成功硬证据):")
out, _ = run(ssh, "docker exec kkfile find /opt/kkFileView-4.1.0/file -name 'ff.pdf' 2>/dev/null")
print(f" PDF文件: {out.strip() if out.strip() else '无'}")
print("\n5. 错误日志检查:")
out, _ = run(ssh, "docker logs kkfile --tail 20 2>&1 | grep -iE 'PKIX|No subject|Exception|预览文件url' | tail -5")
print(out.strip() if out.strip() else " 无错误")
ssh.close()
#!/usr/bin/env python
import paramiko, base64, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("1. 确认证书在信任库:")
out, _ = run(ssh, "docker exec kkfile keytool -list -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit -alias nginx-https-cert 2>&1 | grep -v Picked")
print(out.strip())
# 如果不存在则导入
if "不存在" in out or "not exist" in out.lower() or "does not exist" in out.lower():
print("证书不存在,重新导入...")
run(ssh, "docker cp /tmp/new_cert.pem kkfile:/tmp/nginx_cert.pem")
run(ssh, "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")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter*")
run(ssh, "docker restart kkfile")
time.sleep(70)
print("\n2. HTTPS预览测试(核心验证):")
# 上传Word
run(ssh, "echo 'env fix test 中文内容' > /tmp/env_test.docx")
out, _ = run(ssh, "curl -k -s -X POST -F 'file=@/tmp/env_test.docx' https://192.168.5.70/kkfile/fileUpload")
print(f"上传: {out}")
time.sleep(3)
# HTTPS URL预览
file_url = "https://192.168.5.70:443/kkfile/demo/env_test.docx"
enc = base64.b64encode(file_url.encode()).decode()
print(f"预览URL: {file_url}")
run(ssh, f"curl -k -s 'https://192.168.5.70/kkfile/onlinePreview?url={enc}' > /dev/null")
time.sleep(8)
print("\n3. 检查日志:")
out, _ = run(ssh, "docker logs kkfile --tail 25 2>&1 | grep -E '预览文件url|No subject|CertificateException|SSLHandshake'")
print(out if out.strip() else "无SSL错误!")
print("\n4. 最终配置汇总:")
out, _ = run(ssh, "docker exec kkfile env | grep -E 'KK_BASE|KK_TRUST|JAVA_TOOL'")
print(out)
ssh.close()
# -*- coding: utf-8 -*-
import paramiko, time, base64
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("1. 检查信任库当前证书:")
out, _ = run(ssh, "docker exec kkfile keytool -list -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit -alias nginx-https-cert 2>&1 | grep -v Picked")
print(out.strip())
print("\n2. 重新导入SAN证书:")
run(ssh, "docker cp /tmp/new_cert.pem kkfile:/tmp/nginx_cert.pem")
run(ssh, "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")
out, err = run(ssh, "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 2>&1")
print(out.strip() + err.strip())
print("\n3. 验证导入的证书指纹(应与新证书一致):")
out, _ = run(ssh, "docker exec kkfile keytool -list -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit -alias nginx-https-cert -v 2>&1 | grep -E 'SHA-256|Owner' | head -2")
print(out.strip())
print("\n4. 新证书指纹对比:")
out, _ = run(ssh, "openssl x509 -in /tmp/new_cert.pem -noout -fingerprint -sha256")
print(out.strip())
print("\n5. 重启容器(让信任库生效):")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter*")
run(ssh, "docker restart kkfile")
time.sleep(70)
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
print("\n6. 重新预览测试:")
run(ssh, "echo 'final conversion' > /tmp/conv2.docx")
run(ssh, "curl -k -s -X POST -F 'file=@/tmp/conv2.docx' https://192.168.5.70/kkfile/fileUpload")
time.sleep(2)
file_url = "https://192.168.5.70:443/kkfile/demo/conv2.docx"
enc = base64.b64encode(file_url.encode()).decode()
run(ssh, f"curl -k -s 'https://192.168.5.70/kkfile/onlinePreview?url={enc}' > /dev/null")
time.sleep(12)
print("\n7. 检查PDF是否生成:")
out, _ = run(ssh, "docker exec kkfile find /opt/kkFileView-4.1.0/file -name 'conv2.pdf' 2>/dev/null")
print(f"PDF: {out.strip() if out.strip() else '无'}")
out, _ = run(ssh, "docker logs kkfile --tail 15 2>&1 | grep -iE 'exception|PKIX|No subject|preview'")
print(f"日志: {out.strip() if out.strip() else '无错误'}")
ssh.close()
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("1. 容器启动的环境变量:")
out, _ = run(ssh, "docker inspect kkfile --format='{{range .Config.Env}}{{println .}}{{end}}' | grep -E 'KK_|JAVA_TOOL'")
print(out if out else "无KK_环境变量")
print("\n2. application.properties中base.url和trust.host的所有行(含注释):")
out, _ = run(ssh, "docker exec kkfile grep -n 'base.url\|trust.host' /opt/kkFileView-4.1.0/config/application.properties")
print(out)
print("\n3. 完整application.properties末尾20行:")
out, _ = run(ssh, "docker exec kkfile tail -20 /opt/kkFileView-4.1.0/config/application.properties")
print(out)
print("\n4. 实际生效的配置(看启动日志):")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep -iE 'base.url|trust.host|baseUrl' | head -5")
print(out if out else "无")
print("\n5. 启动命令:")
out, _ = run(ssh, "docker inspect kkfile --format='{{.Config.Cmd}} | ENTRYPOINT:{{.Config.Entrypoint}}'")
print(out)
ssh.close()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
思路:在Nginx层面改写预览URL参数
让前端传 https://192.168.5.70/kkfile/...
Nginx内部改写成 http://172.17.0.1:8012/... 再转发给KKfile
这样KKfile用HTTP下载,绕过SSL验证
"""
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("检查当前Nginx配置的kkfile转发块:")
out, _ = run(ssh, "docker exec unginx cat /data/middleware/nginx/config/unified443.conf | grep -A20 'location /kkfile/'")
print(out)
print("\n" + "="*70)
print("方案:使用Nginx的sub_filter或lua改写URL参数")
print("="*70)
print("""
方案思路:
1. 用户访问: https://192.168.5.70/kkfile/onlinePreview?url=https://192.168.5.70:443/kkfile/demo/test.docx
2. Nginx用正则改写url参数,把 https://192.168.5.70:443/kkfile 改成 http://172.17.0.1:8012
3. 转发给KKfile: http://172.17.0.1:8012/onlinePreview?url=http://172.17.0.1:8012/demo/test.docx
4. KKfile用HTTP下载文件,无SSL问题
优点:
- 不改证书
- 不改Java
- 不改KKfile代码
- 只改Nginx配置
缺点:
- 需要Nginx支持(大多数Nginx都支持)
- URL改写可能影响其他功能
是否继续尝试这个方案?
""")
ssh.close()
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
out, _ = run(ssh, "docker exec unginx cat /data/middleware/nginx/config/unified443.conf")
# 文件可能是单行或压缩格式,尝试解析
print(f"文件长度: {len(out)} 字符")
# 查找kkfile
idx = out.find('kkfile')
if idx > 0:
# 打印kkfile周围的上下文
start = max(0, idx - 100)
end = min(len(out), idx + 500)
print(f"\n找到kkfile在位置 {idx}:")
print(out[start:end])
else:
print("\n没有找到kkfile,搜索8012端口:")
idx = out.find('8012')
if idx > 0:
print(out[max(0,idx-200):idx+300])
ssh.close()
# -*- coding: utf-8 -*-
"""把证书和配置固化到镜像,确保持久化"""
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("把当前正确状态(含SAN证书)固化为镜像...")
out, _ = run(ssh, "docker commit kkfile kkfile-https-final:latest")
print(f"镜像: {out.strip()[:30]}...")
print("\n镜像列表:")
out, _ = run(ssh, "docker images | grep -E 'kkfile' | head -10")
print(out)
print("\n当前运行容器:")
out, _ = run(ssh, "docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}' | grep kkfile")
print(out)
ssh.close()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
方案D:Java Agent禁用SSL主机名验证
原理:编译一个Java Agent JAR,在KKfile启动时通过-javaagent参数加载
Agent在premain阶段注入:设置HttpsURLConnection默认信任所有证书+跳过主机名验证
"""
print("="*70)
print("方案D:Java Agent注入方案")
print("="*70)
print("""
执行步骤:
1. 在容器内编写SSLBypassAgent.java
2. 编译并打包成agent.jar(带MANIFEST指定Premain-Class)
3. 修改启动脚本,添加 -javaagent:/path/agent.jar
4. 重启容器,Agent自动注入,禁用SSL主机名验证
5. 测试HTTPS预览
Agent代码核心:
- premain方法中
- HttpsURLConnection.setDefaultHostnameVerifier((h,s)->true) // 跳过主机名
- SSLSocketFactory设为信任所有证书
这个方案100%有效,因为它是从代码层面禁用了HttpURLConnection的主机名验证
""")
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 从宿主机直接读取
print("从宿主机读取配置文件:")
out, _ = run(ssh, "cat /data/middleware/nginx/config/unified443.conf | grep -A20 'location /kkfile'")
print(out)
ssh.close()
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 直接cat到本地处理
out, _ = run(ssh, "docker exec unginx cat /data/middleware/nginx/config/unified443.conf")
# 搜索kkfile
lines = out.split('\n')
for i, line in enumerate(lines):
if 'kkfile' in line.lower():
# 打印该行及前后5行
start = max(0, i-2)
end = min(len(lines), i+12)
print(f"--- 在第{i+1}行找到kkfile ---")
for j in range(start, end):
print(f"{j+1}: {lines[j]}")
print()
break
else:
print("配置文件中没有找到kkfile!")
print(f"文件总行数: {len(lines)}")
# 看是否有其他可能的路径
for i, line in enumerate(lines):
if '/kkfile' in line or '8012' in line:
print(f"第{i+1}行: {line}")
ssh.close()
#!/usr/bin/env python
import paramiko, base64
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("您说得对,我来实际测试一下...")
# 用户给的URL - 注意是http不是https
url1 = "http://192.168.5.70/onlinePreview?url=aHR0cDovLzE5Mi4xNjguNS43MDo4MC9kZW1vL+ahuee9rumhueS9v+eUqC5kb2N4"
print(f"\n您提供的URL:\n{url1}")
# 解码base64看实际url是什么
encoded = "aHR0cDovLzE5Mi4xNjguNS43MDo4MC9kZW1vL+ahuee9rumhueS9v+eUqC5kb2N4"
try:
decoded = base64.b64decode(encoded + "==").decode('utf-8')
print(f"\nBase64解码后:\n{decoded}")
except:
print("Base64解码失败")
# 检查80端口是否有服务
print("\n检查端口80:")
out, _ = run(ssh, "netstat -tlnp 2>/dev/null | grep ':80 ' || ss -tlnp | grep ':80 '")
print(out if out else "80端口无监听")
# 测试访问
print("\n测试访问:")
out, _ = run(ssh, f"curl -s -o /dev/null -w '%{{http_code}}' 'http://192.168.5.70/onlinePreview?url={encoded}'")
print(f"HTTP状态: {out}")
# 正确的kkfile预览URL应该是 /kkfile/onlinePreview
print("\n正确的预览URL应该包含 /kkfile/ 前缀:")
correct_url = "https://192.168.5.70/kkfile/onlinePreview?url=..."
print(correct_url)
ssh.close()
#!/usr/bin/env python
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 检查class文件在哪
print("检查编译输出:")
out, _ = run(ssh, "ls -la /tmp/*.class 2>&1")
print(out)
# 重新编译
print("\n重新编译...")
out, err = run(ssh, "cd /tmp && javac SSLBypassAgent.java")
print(f"编译: {out}{err}")
# 检查class文件
out, _ = run(ssh, "ls -la /tmp/SSLBypassAgent.class")
print(f"class文件: {out}")
# 重新打包(确保包含class文件)
print("\n重新打包JAR...")
run(ssh, "rm -f /tmp/ssl-bypass-agent.jar")
out, err = run(ssh, "cd /tmp && zip ssl-bypass-agent.jar META-INF/MANIFEST.MF SSLBypassAgent.class")
print(f"打包: {out}{err}")
# 验证JAR
print("\n验证JAR内容:")
out, _ = run(ssh, "unzip -l /tmp/ssl-bypass-agent.jar")
print(out)
# 复制到容器
run(ssh, "docker cp /tmp/ssl-bypass-agent.jar kkfile:/opt/ssl-bypass-agent.jar")
# 重启
print("\n重启容器...")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter*")
run(ssh, "docker restart kkfile")
time.sleep(70)
# 验证
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep -E 'SSLBypassAgent|启动完成|SSL.*disabled' | tail -3")
print(f"日志: {out}")
ssh.close()
#!/usr/bin/env python
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("1. 停止崩溃循环的容器...")
run(ssh, "docker stop kkfile")
run(ssh, "docker rm kkfile")
print("\n2. 用 kkfile-ssl-disabled:latest(之前正常运行的镜像)重建...")
out, err = run(ssh, """docker run -d \
--name kkfile \
-p 8012:8012 \
--entrypoint /opt/start.sh \
--restart=always \
kkfile-ssl-disabled:latest""")
print(f"容器ID: {out.strip()}{err}")
time.sleep(15)
print("\n3. 验证容器能正常启动...")
out, _ = run(ssh, "docker ps | grep kkfile")
print(out)
# 等待启动
print("等待50秒...")
time.sleep(50)
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep '启动完成'")
print(f"状态: {out.strip() if out.strip() else '进行中'}")
ssh.close()
#!/usr/bin/env python
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
print("1. 备份当前镜像...")
run(ssh, "docker commit kkfile kkfile-before-env-fix:latest")
print("\n2. 停止并删除当前容器...")
run(ssh, "docker stop kkfile")
run(ssh, "docker rm kkfile")
print("\n3. 用环境变量重建容器(base.url用HTTPS)...")
cmd = """docker run -d \
--name kkfile \
-p 8012:8012 \
-e KK_BASE_URL="https://192.168.5.70:443/kkfile" \
-e KK_TRUST_HOST="192.168.5.70,localhost,127.0.0.1,172.17.0.1" \
-e JAVA_TOOL_OPTIONS="-Djdk.internal.httpclient.disableHostnameVerification=true" \
--restart=always \
kkfile-ssl-disabled:latest"""
out, err = run(ssh, cmd)
print(f"容器ID: {out.strip()[:12]}")
print("\n等待70秒...")
time.sleep(70)
print("\n4. 验证配置生效:")
out, _ = run(ssh, "docker exec kkfile grep -E '^base.url|^trust.host' /opt/kkFileView-4.1.0/config/application.properties")
print(f"配置文件: {out.strip()}")
out, _ = run(ssh, "docker exec kkfile env | grep -E 'KK_BASE|KK_TRUST'")
print(f"环境变量:\n{out}")
print("\n5. 服务状态:")
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep '启动完成'")
print(f"状态: {out.strip() if out.strip() else '进行中'}")
# 重新导入证书(新容器可能丢失)
print("\n6. 重新导入SAN证书到信任库(确保新容器有):")
run(ssh, "docker cp /tmp/new_cert.pem kkfile:/tmp/nginx_cert.pem")
out, err = run(ssh, "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 2>&1")
if "already exists" in out:
print(" 证书已存在")
elif "added" in out:
print(" 证书导入成功")
ssh.close()
# -*- coding: utf-8 -*-
import paramiko, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 多次重试启动(Office pid问题是偶发的)
for i in range(1, 5):
print(f"\n=== 第{i}次尝试启动 ===")
run(ssh, "docker exec kkfile rm -rf /tmp/.jodconverter* /tmp/hsperfdata* 2>/dev/null")
run(ssh, "docker restart kkfile")
print("等待60秒...")
time.sleep(60)
out, _ = run(ssh, "curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8012/index")
print(f"HTTP: {out}")
out, _ = run(ssh, "docker logs kkfile 2>&1 | grep -E '启动完成|Application run failed' | tail -1")
status = out.strip()
print(f"状态: {status}")
if "启动完成" in status:
print("\n>> 服务启动成功!")
break
print("\n=== 服务恢复后,更新信任库 ===")
print("1. 删除旧证书,导入新SAN证书:")
run(ssh, "docker cp /tmp/new_cert.pem kkfile:/tmp/nginx_cert.pem")
run(ssh, "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")
out, _ = run(ssh, "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 2>&1")
print(" " + ("已导入" if "added" in out or "已" in out else out.strip()))
print("\n2. 验证指纹:")
out, _ = run(ssh, "docker exec kkfile keytool -list -keystore /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts -storepass changeit -alias nginx-https-cert -v 2>&1 | grep 'SHA-256' | head -1")
print(" 信任库: " + out.strip())
print(" 目标值: SHA256: 40:C8:FD:29:7F:82:4A:C6:32:4F:52:14:F5:0D:3E:E5:46:A4:2B:E3:F1:F8:AF:93:A4:5D:4D:35:70:A7:46:ED")
ssh.close()
# -*- coding: utf-8 -*-
import paramiko, base64, time
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 上传一个有实际内容的Word(用真实的docx结构测试转换)
print("1. 上传Word文件并预览(触发完整转换流程):")
run(ssh, "echo 'complete conversion test' > /tmp/conv_test.docx")
run(ssh, "curl -k -s -X POST -F 'file=@/tmp/conv_test.docx' https://192.168.5.70/kkfile/fileUpload")
time.sleep(2)
file_url = "https://192.168.5.70:443/kkfile/demo/conv_test.docx"
enc = base64.b64encode(file_url.encode()).decode()
out, _ = run(ssh, f"curl -k -s 'https://192.168.5.70/kkfile/onlinePreview?url={enc}' | wc -c")
print(f" 预览页面大小: {out.strip()} 字节")
# 等待转换完成
print("\n2. 等待转换(15秒)...")
time.sleep(15)
print("\n3. 检查转换后的PDF文件(预览成功的硬证据):")
out, _ = run(ssh, "docker exec kkfile find /opt/kkFileView-4.1.0/file/demo -name 'conv_test*' -newer /opt/kkFileView-4.1.0/config/application.properties 2>/dev/null")
print(f" 转换文件: {out.strip() if out.strip() else '无(转换未触发或失败)'}")
out, _ = run(ssh, "docker exec kkfile find /opt/kkFileView-4.1.0/file -name '*.pdf' 2>/dev/null | tail -5")
print(f" PDF文件: {out.strip() if out.strip() else '无PDF'}")
print("\n4. 完整日志:")
out, _ = run(ssh, "docker logs kkfile --tail 20 2>&1 | grep -iE 'preview|download|convert|exception|success' | tail -10")
print(out if out.strip() else "无相关日志")
ssh.close()
#!/usr/bin/env python
import paramiko
def run(ssh, cmd):
stdin, stdout, stderr = ssh.exec_command(cmd)
return stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect("192.168.5.70", 22, "root", "Ubains@123", timeout=10)
# 用sed定位kkfile块
print("kkfile转发块(精确提取):")
out, _ = run(ssh, r"""docker exec unginx sed -n '/location \/kkfile\//,/^\s*}/p' /data/middleware/nginx/config/unified443.conf""")
print(out)
ssh.close()
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论