From fea5e0fac54e8515fcd80938321c61feac3b8d2f Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 2 Jan 2026 20:46:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E7=89=87=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9=E6=8A=80=E6=9C=AF=EF=BC=9A=E9=81=BF=E5=85=8D=E5=8F=8C?= =?UTF-8?q?=E9=87=8D=E5=8E=8B=E7=BC=A9=EF=BC=8C=E4=BF=9D=E6=8C=81JPG/PNG?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 客户端压缩:保持原格式(JPG保持JPG,PNG保持PNG),不再强制转换为WebP - 提高压缩质量:最低质量从0.6提高到0.90,避免画质损失 - 启用高质量图像平滑:减少锯齿,提升画质 - 服务器端智能优化:使用MozJPEG和PNG优化算法 - 避免双重压缩:小文件(<3MB)跳过服务器端优化,只有优化效果明显(>5%)才使用 - 优化策略:优先缩小尺寸而不是降低质量,留余量给服务器端优化 技术改进: - JPEG: MozJPEG编码器,质量92%,渐进式,优化扫描 - PNG: 压缩级别6,自适应过滤,调色板优化 - 智能判断:避免不必要的双重压缩,保护画质 --- app/(chat)/api/files/upload/route.ts | 98 ++++++- components/multimodal-input.tsx | 80 ++++-- scripts/fix-high-cpu.sh | 2 + 图片压缩优化方案说明.md | 132 +++++++++ 图片压缩冲突分析.md | 155 +++++++++++ 图片变清晰api.md | 157 +++++++++++ 恶意程序来源调查报告.md | 382 +++++++++++++++++++++++++++ 服务器挖矿程序检查报告.md | 240 +++++++++++++++++ 系统性能诊断与解决方案.md | 2 + 9 files changed, 1230 insertions(+), 18 deletions(-) create mode 100644 图片压缩优化方案说明.md create mode 100644 图片压缩冲突分析.md create mode 100644 恶意程序来源调查报告.md create mode 100644 服务器挖矿程序检查报告.md diff --git a/app/(chat)/api/files/upload/route.ts b/app/(chat)/api/files/upload/route.ts index f8b0470..87dc422 100644 --- a/app/(chat)/api/files/upload/route.ts +++ b/app/(chat)/api/files/upload/route.ts @@ -4,6 +4,83 @@ import { z } from "zod"; import { auth } from "@/app/(auth)/auth"; import { uploadFile } from "@/lib/storage/service"; +/** + * 使用Sharp智能优化图片(保持原格式) + * 策略:避免双重压缩,只在需要时优化 + * - 如果文件已经很小(<3MB),跳过优化(客户端已处理) + * - 如果文件较大,使用MozJPEG/PNG优化算法进一步优化 + */ +async function optimizeImage(buffer: Buffer, mimeType: string): Promise { + try { + const fileSizeMB = buffer.length / 1024 / 1024; + const OPTIMIZE_THRESHOLD_MB = 3; // 3MB阈值:小于此值不优化(避免双重压缩) + + // ✅ 智能判断:如果文件已经很小,跳过优化(避免双重压缩) + if (fileSizeMB < OPTIMIZE_THRESHOLD_MB) { + console.log(`[Upload] 文件已较小(${fileSizeMB.toFixed(2)}MB < ${OPTIMIZE_THRESHOLD_MB}MB),跳过优化,避免双重压缩`); + return buffer; + } + + const sharp = await import("sharp"); + const image = sharp.default(buffer); + + if (mimeType === 'image/jpeg' || mimeType === 'image/jpg') { + // ✅ 使用MozJPEG编码器,高质量压缩 + // 注意:这里使用MozJPEG重新编码,使用更好的算法,而不是降低质量 + const optimized = await image + .jpeg({ + quality: 92, // 高质量(92%质量,画质优秀) + mozjpeg: true, // 使用MozJPEG编码器(比标准JPEG压缩率高15-25%,但质量更好) + progressive: true, // 渐进式JPEG,加载体验更好 + optimizeScans: true, // 优化扫描 + trellisQuantisation: true, // 网格量化,更好的压缩 + overshootDeringing: true, // 过冲去振铃,减少伪影 + optimizeCoding: true, // 优化编码 + }) + .toBuffer(); + + // 只有优化后文件明显更小才使用(避免不必要的处理) + const reductionPercent = ((1 - optimized.length / buffer.length) * 100); + if (reductionPercent > 5) { // 只有减少超过5%才使用 + console.log(`[Upload] JPEG优化: ${buffer.length} → ${optimized.length} bytes (减少${reductionPercent.toFixed(1)}%)`); + return optimized; + } else { + console.log(`[Upload] JPEG优化效果不明显(${reductionPercent.toFixed(1)}%),使用原图`); + return buffer; + } + } else if (mimeType === 'image/png') { + // ✅ PNG优化压缩(无损优化) + const metadata = await image.metadata(); + const optimized = await image + .png({ + compressionLevel: 6, // 压缩级别(0-9,6是平衡点) + adaptiveFiltering: true, // 自适应过滤,减少文件大小 + palette: !metadata.hasAlpha, // 无透明通道时使用调色板模式 + quality: 100, // PNG质量(100=无损) + effort: 6, // 压缩努力程度(0-10,6是平衡点) + }) + .toBuffer(); + + // 只有优化后文件明显更小才使用 + const reductionPercent = ((1 - optimized.length / buffer.length) * 100); + if (reductionPercent > 5) { // 只有减少超过5%才使用 + console.log(`[Upload] PNG优化: ${buffer.length} → ${optimized.length} bytes (减少${reductionPercent.toFixed(1)}%)`); + return optimized; + } else { + console.log(`[Upload] PNG优化效果不明显(${reductionPercent.toFixed(1)}%),使用原图`); + return buffer; + } + } + + // 其他格式返回原图 + return buffer; + } catch (error) { + console.error("[Upload] 图片优化失败,使用原图:", error); + // 优化失败时返回原图,不影响上传流程 + return buffer; + } +} + // Use Blob instead of File since File is not available in Node.js environment const FileSchema = z.object({ file: z @@ -68,8 +145,27 @@ export async function POST(request: Request) { console.log("[Upload API] File buffer size:", fileBuffer.byteLength); try { + // ✅ 使用Sharp优化图片(保持原格式) + let optimizedBuffer: Buffer = Buffer.from(fileBuffer); + + // ✅ 优化原图(保持JPG/PNG格式) + // WebP格式不优化(用于预览图,保持原样) + if (file.type === 'image/jpeg' || file.type === 'image/jpg' || file.type === 'image/png') { + optimizedBuffer = await optimizeImage(optimizedBuffer, file.type); + } else if (file.type === 'image/webp') { + // WebP格式不优化(用于预览图),直接使用 + console.log(`[Upload] WebP格式(预览图),跳过优化,直接上传`); + } + + // 将Buffer转换为ArrayBuffer用于上传 + const optimizedArrayBuffer = optimizedBuffer.buffer.slice( + optimizedBuffer.byteOffset, + optimizedBuffer.byteOffset + optimizedBuffer.byteLength + ) as ArrayBuffer; + // 使用统一的存储服务(支持数据库配置的 S3、环境变量 S3 或 Vercel Blob) - const data = await uploadFile(filename, fileBuffer); + // 使用优化后的buffer上传 + const data = await uploadFile(filename, optimizedArrayBuffer); console.log("[Upload API] Upload successful:", data.url); return NextResponse.json(data); diff --git a/components/multimodal-input.tsx b/components/multimodal-input.tsx index d47557d..a398c76 100644 --- a/components/multimodal-input.tsx +++ b/components/multimodal-input.tsx @@ -238,16 +238,25 @@ function PureMultimodalInput({ resetHeight, ]); - // 压缩图片函数 + // 压缩图片函数(保持原格式:JPG保持JPG,PNG保持PNG) const compressImage = useCallback(async (file: File, maxSizeMB = 8): Promise => { // 如果不是图片,直接返回 if (!file.type.startsWith('image/')) { return file; } - // 如果已经是 WebP 且小于限制,直接返回 - if (file.type === 'image/webp' && file.size <= maxSizeMB * 1024 * 1024) { + // ✅ 保持原格式:只处理JPG和PNG,其他格式(如WebP)直接返回 + const isJPEG = file.type === 'image/jpeg' || file.type === 'image/jpg'; + const isPNG = file.type === 'image/png'; + + // 如果不是JPG/PNG,直接返回(WebP等格式不压缩) + if (!isJPEG && !isPNG) { + if (file.size <= maxSizeMB * 1024 * 1024) { return file; + } + // 如果WebP等格式太大,也返回(让服务器端处理或提示用户) + console.log(`[压缩] 非JPG/PNG格式,跳过压缩: ${file.type}`); + return file; } return new Promise((resolve, reject) => { @@ -286,16 +295,33 @@ function PureMultimodalInput({ canvas.width = newWidth; canvas.height = newHeight; - const ctx = canvas.getContext('2d'); + const ctx = canvas.getContext('2d', { + alpha: isPNG, // PNG需要透明通道 + desynchronized: false, // 同步渲染,保证质量 + willReadFrequently: false, + }); + if (!ctx) { reject(new Error('无法创建 Canvas 上下文')); return; } + // ✅ 启用高质量图像平滑,减少锯齿 + ctx.imageSmoothingEnabled = true; + ctx.imageSmoothingQuality = 'high'; + ctx.drawImage(img, 0, 0, newWidth, newHeight); - // 尝试不同的质量等级,直到文件大小小于限制 - let quality = 0.9; + // ✅ 保持原格式压缩 + // 策略:优先缩小尺寸,尽量保持高质量,让服务器端做最终优化 + const outputFormat = isPNG ? 'image/png' : 'image/jpeg'; + const TARGET_SIZE_MB = maxSizeMB * 0.9; // 目标大小(留10%余量给服务器端优化) + + // 如果尺寸已经调整过,使用高质量直接输出(让服务器端优化) + const wasResized = newWidth !== width || newHeight !== height; + let quality = wasResized ? 0.95 : 0.92; // 如果已缩小尺寸,使用更高质量 + const minQuality = 0.90; // 最低质量(提高,避免画质损失) + const tryCompress = () => { canvas.toBlob( (blob) => { @@ -304,26 +330,46 @@ function PureMultimodalInput({ return; } - console.log(`[压缩] 格式: image/webp, 质量: ${quality}, 大小: ${(blob.size / 1024 / 1024).toFixed(2)}MB`); + console.log(`[压缩] 格式: ${outputFormat}, 质量: ${quality}, 大小: ${(blob.size / 1024 / 1024).toFixed(2)}MB`); - // 目标 maxSizeMB (默认8MB) + // 目标 TARGET_SIZE_MB(留余量给服务器端优化) // 如果还是太大且质量可以降低,继续压缩 - if (blob.size > maxSizeMB * 1024 * 1024 && quality > 0.6) { // 最低质量 0.6 - quality -= 0.1; + if (blob.size > TARGET_SIZE_MB * 1024 * 1024 && quality > minQuality) { + quality -= 0.02; // 每次减少0.02(更精细的调整) tryCompress(); + } else if (blob.size > TARGET_SIZE_MB * 1024 * 1024 && quality <= minQuality) { + // 如果质量已到最低还是太大,缩小尺寸而不是继续降低质量 + if (newWidth > 1000 || newHeight > 1000) { + newWidth = Math.floor(newWidth * 0.95); + newHeight = Math.floor(newHeight * 0.95); + canvas.width = newWidth; + canvas.height = newHeight; + ctx.imageSmoothingEnabled = true; + ctx.imageSmoothingQuality = 'high'; + ctx.drawImage(img, 0, 0, newWidth, newHeight); + quality = 0.95; // 重置质量(缩小尺寸后使用高质量) + tryCompress(); + } else { + // 已经很小了,使用当前结果 + const compressedFile = new File([blob], file.name, { + type: outputFormat, // 保持原格式 + lastModified: Date.now(), + }); + console.log(`[压缩] 原始: ${(file.size / 1024 / 1024).toFixed(2)}MB → 压缩后: ${(compressedFile.size / 1024 / 1024).toFixed(2)}MB`); + resolve(compressedFile); + } } else { - // 创建新文件,强制使用 .webp 扩展名 - const newName = file.name.replace(/\.[^/.]+$/, "") + ".webp"; - const compressedFile = new File([blob], newName, { - type: "image/webp", + // 大小合适,使用当前结果(让服务器端做最终优化) + const compressedFile = new File([blob], file.name, { + type: outputFormat, // 保持原格式 lastModified: Date.now(), }); - console.log(`[压缩] 原始: ${(file.size / 1024 / 1024).toFixed(2)}MB → 压缩后: ${(compressedFile.size / 1024 / 1024).toFixed(2)}MB`); + console.log(`[压缩] 原始: ${(file.size / 1024 / 1024).toFixed(2)}MB → 压缩后: ${(compressedFile.size / 1024 / 1024).toFixed(2)}MB (将交由服务器端进一步优化)`); resolve(compressedFile); } }, - "image/webp", - quality + outputFormat, // 保持原格式 + isPNG ? undefined : quality // PNG不需要quality参数 ); }; diff --git a/scripts/fix-high-cpu.sh b/scripts/fix-high-cpu.sh index 867cb0e..42cd9fe 100755 --- a/scripts/fix-high-cpu.sh +++ b/scripts/fix-high-cpu.sh @@ -82,3 +82,5 @@ echo "" + + diff --git a/图片压缩优化方案说明.md b/图片压缩优化方案说明.md new file mode 100644 index 0000000..d8c4d75 --- /dev/null +++ b/图片压缩优化方案说明.md @@ -0,0 +1,132 @@ +# 图片压缩优化方案说明 + +## 问题分析 + +### 双重压缩问题 +- **客户端压缩**:使用Canvas API,质量0.88-0.92 +- **服务器端优化**:使用Sharp MozJPEG,质量92% +- **风险**:如果客户端已经压缩,服务器端再压缩,可能造成双重压缩,导致画质损失 + +--- + +## 优化方案 + +### 策略:避免双重压缩,智能优化 + +#### 1. 客户端压缩策略(`components/multimodal-input.tsx`) + +**优化点**: +- ✅ **优先缩小尺寸**:如果图片太大,先缩小尺寸而不是降低质量 +- ✅ **提高质量下限**:最低质量从0.6提高到0.90,避免画质损失 +- ✅ **留余量给服务器**:目标大小设为`maxSizeMB * 0.9`,留10%余量给服务器端优化 +- ✅ **尺寸调整后使用高质量**:如果已缩小尺寸,使用0.95质量,让服务器端做最终优化 + +**逻辑**: +``` +如果图片 > 5MB 或 > 4K分辨率 + ↓ +优先缩小尺寸(保持高质量) + ↓ +如果还是太大,才降低质量(最低0.90) + ↓ +输出文件(留余量给服务器端优化) +``` + +#### 2. 服务器端优化策略(`app/(chat)/api/files/upload/route.ts`) + +**优化点**: +- ✅ **智能判断**:如果文件 < 3MB,跳过优化(避免双重压缩) +- ✅ **效果检查**:只有优化后文件减少 > 5% 才使用,否则返回原图 +- ✅ **使用更好的编码器**:MozJPEG(更好的算法,而不是降低质量) + +**逻辑**: +``` +接收文件 + ↓ +检查文件大小 + ├─ < 3MB → 跳过优化(客户端已处理) + └─ ≥ 3MB → 使用MozJPEG/PNG优化 + ↓ + 检查优化效果 + ├─ 减少 > 5% → 使用优化结果 + └─ 减少 ≤ 5% → 使用原图 +``` + +--- + +## 工作流程 + +### 场景1:小文件(< 5MB,< 4K) +``` +客户端:直接返回原图(免检通道) +服务器:< 3MB,跳过优化 +结果:原图直接存储,无压缩 +``` + +### 场景2:中等文件(5-8MB,< 4K) +``` +客户端:可能轻微压缩(质量0.90-0.95) +服务器:< 3MB,跳过优化 +结果:客户端压缩后存储,无双重压缩 +``` + +### 场景3:大文件(> 8MB 或 > 4K) +``` +客户端:缩小尺寸 + 高质量压缩(质量0.90-0.95) + ↓ +服务器:≥ 3MB,使用MozJPEG优化 + ↓ +检查优化效果 + ├─ 减少 > 5% → 使用优化结果 + └─ 减少 ≤ 5% → 使用原图(避免双重压缩) +``` + +--- + +## 优化效果 + +### 避免双重压缩 +- ✅ 小文件(< 3MB):服务器端跳过优化 +- ✅ 优化效果检查:只有明显优化才使用 +- ✅ 客户端提高质量下限:0.6 → 0.90 + +### 画质保护 +- ✅ 客户端优先缩小尺寸,而不是降低质量 +- ✅ 服务器端使用更好的编码器(MozJPEG),而不是降低质量 +- ✅ 智能判断,避免不必要的处理 + +### 文件大小 +- ✅ 客户端留10%余量给服务器端优化 +- ✅ 服务器端使用MozJPEG(压缩率高15-25%) +- ✅ 双重优化效果更好(但避免双重压缩) + +--- + +## 技术细节 + +### 客户端压缩参数 +- **起始质量**:0.92(尺寸未调整)或 0.95(尺寸已调整) +- **最低质量**:0.90(避免画质损失) +- **目标大小**:`maxSizeMB * 0.9`(留余量) +- **图像平滑**:`high`(减少锯齿) + +### 服务器端优化参数 +- **优化阈值**:3MB(小于此值跳过优化) +- **效果阈值**:5%(只有减少超过5%才使用) +- **JPEG质量**:92%(高质量) +- **PNG质量**:100%(无损) + +--- + +## 预期效果 + +| 文件大小 | 客户端处理 | 服务器端处理 | 最终结果 | +|---------|-----------|-------------|---------| +| < 3MB | 原图或轻微压缩 | 跳过优化 | 高质量,无双重压缩 | +| 3-8MB | 高质量压缩 | 智能优化 | 高质量,单次优化 | +| > 8MB | 缩小尺寸+高质量 | MozJPEG优化 | 高质量,双重优化(但避免双重压缩) | + +--- + +**总结**:通过智能判断和效果检查,避免不必要的双重压缩,同时保证画质和文件大小优化。 + diff --git a/图片压缩冲突分析.md b/图片压缩冲突分析.md new file mode 100644 index 0000000..5e62018 --- /dev/null +++ b/图片压缩冲突分析.md @@ -0,0 +1,155 @@ +# 图片压缩功能冲突分析 + +## 当前压缩流程 + +### 1. 客户端压缩 (`components/multimodal-input.tsx`) +- **函数**: `compressImage` +- **作用**: 在浏览器端压缩图片 +- **输出格式**: **强制转换为WebP** (第316-320行) +- **质量范围**: 0.6 - 0.9 (最低质量0.6,可能导致画质损失) +- **处理逻辑**: + - 如果图片 < 5MB 且 < 4K分辨率,直接返回原图 + - 否则压缩并转换为WebP格式 + +### 2. 服务器端优化 (`app/(chat)/api/files/upload/route.ts`) +- **函数**: `optimizeImage` +- **作用**: 在服务器端优化图片 +- **支持格式**: **仅JPEG和PNG** (第126行) +- **处理逻辑**: + - JPEG: 使用MozJPEG编码器,质量92% + - PNG: 自适应过滤,压缩级别6 + - **WebP: 不处理,直接返回原图** + +--- + +## ⚠️ 发现的冲突问题 + +### 问题1: 格式不匹配 +- **客户端**: JPG/PNG → **WebP** (强制转换) +- **服务器端**: 只优化 **JPEG/PNG**,不优化WebP +- **结果**: 客户端转换的WebP图片在服务器端不会被优化 + +### 问题2: 双重处理但效果不佳 +- 客户端已经压缩(可能损失画质) +- 服务器端无法进一步优化WebP +- 最终结果:画质可能已经受损,且文件大小未进一步优化 + +### 问题3: 格式要求冲突 +- 用户要求:**保持JPG和PNG格式不变** +- 当前实现:客户端强制转换为WebP +- **冲突**: 不符合用户需求 + +--- + +## ✅ 解决方案 + +### 方案A: 修改客户端压缩逻辑(推荐) + +**修改客户端代码,保持原格式**: +```typescript +// 修改 compressImage 函数 +const compressImage = useCallback(async (file: File, maxSizeMB = 8): Promise => { + // ... 现有代码 ... + + // ✅ 保持原格式,不转换为WebP + const outputFormat = file.type === 'image/png' ? 'image/png' : 'image/jpeg'; + const outputQuality = file.type === 'image/png' ? undefined : 0.92; // PNG不需要quality + + canvas.toBlob( + (blob) => { /* ... */ }, + outputFormat, // 保持原格式 + outputQuality + ); +}); +``` + +**优点**: +- 符合用户需求(保持JPG/PNG格式) +- 服务器端可以进一步优化 +- 双重优化效果更好 + +### 方案B: 服务器端也支持WebP优化 + +**扩展服务器端优化函数**: +```typescript +async function optimizeImage(buffer: Buffer, mimeType: string): Promise { + // ... 现有JPEG/PNG代码 ... + + // ✅ 新增WebP优化 + else if (mimeType === 'image/webp') { + const optimized = await image + .webp({ + quality: 90, + effort: 6, + smartSubsample: true, + nearLossless: true, + }) + .toBuffer(); + return optimized; + } +} +``` + +**优点**: +- 可以优化客户端转换的WebP +- 不需要修改客户端代码 + +**缺点**: +- 不符合用户"保持JPG/PNG格式"的要求 + +### 方案C: 跳过客户端压缩,仅使用服务器端优化 + +**修改客户端代码**: +```typescript +const compressImage = useCallback(async (file: File, maxSizeMB = 8): Promise => { + // 如果图片较小,直接返回原图 + if (file.size <= maxSizeMB * 1024 * 1024) { + return file; // 不压缩,让服务器端优化 + } + + // 只处理超大图片(缩小尺寸,保持格式) + // ... 只缩小尺寸,不改变格式和质量 +}); +``` + +**优点**: +- 画质最好(服务器端Sharp优化更专业) +- 保持原格式 +- 避免双重压缩 + +--- + +## 📊 推荐方案 + +**推荐使用方案A + 方案C的组合**: + +1. **修改客户端压缩逻辑**: + - 保持原格式(JPG保持JPG,PNG保持PNG) + - 提高最低质量(0.6 → 0.88) + - 只处理超大图片(>8MB或>4K) + +2. **服务器端优化**: + - 继续优化JPEG和PNG + - 使用MozJPEG和PNG优化算法 + +3. **工作流程**: + ``` + 用户上传 → 客户端检查大小 → + 如果太大:客户端压缩(保持格式) → + 服务器端进一步优化(MozJPEG/PNG优化) → + 存储 + ``` + +--- + +## 🔍 当前状态总结 + +| 项目 | 客户端 | 服务器端 | 冲突 | +|------|--------|----------|------| +| 输出格式 | WebP | JPEG/PNG | ✅ 是 | +| 质量范围 | 0.6-0.9 | 92% (JPEG) | ⚠️ 客户端质量低 | +| 格式保持 | ❌ 强制转换 | ✅ 保持原格式 | ✅ 是 | +| 优化效果 | 基础压缩 | 专业优化 | ⚠️ WebP无法优化 | + +**结论**: 存在冲突,需要修改客户端代码以保持原格式。 + diff --git a/图片变清晰api.md b/图片变清晰api.md index e69de29..456be13 100644 --- a/图片变清晰api.md +++ b/图片变清晰api.md @@ -0,0 +1,157 @@ +注意事项 + +接口返回的链接有效期为 1 小时,请及时下载存储。 +图片格式要求 + +格式 分辨率 大小 +jpg, jpeg, bmp, png, webp, tiff, tif, bitmap, raw, rgb, jfif, lzw 最大 4096x4096 最大20MB +快速开始 + +异步 +不同调用方式的区别&优缺点? +Image URL +Image File +cURL +PHP +Java +NodeJs +Python +C# +Swift +Go +#Create a task. +curl -k 'https://techsz.aoscdn.com/api/tasks/visual/scale' \ +-H 'X-API-KEY: YOUR_API_KEY' \ +-F 'sync=0' \ +-F 'image_url=YOU_IMG_URL' + +#Get the cutout result +#Polling requests using the following methods 1. The polling interval is set to 1 second, 2. The polling time does not exceed 30 seconds +curl -k 'https://techsz.aoscdn.com/api/tasks/visual/scale/{task_id}' \ +-H 'X-API-KEY: YOUR_API_KEY' \ +在线调试 + + +POST +/api/tasks/visual/scale +创建图片变清晰任务 +创建图片变清晰任务 + +图片大小: 不超过 20 MB +图片来源:文件上传(二进制)或从 URL 下载 +消耗:每次成功调用,最长边≤2048px则消耗2算粒,2048px<最长边≤4096px则消耗3算粒。 + +Parameters +Name Description +X-API-KEY * +string +(header) +API Key + +Request body + +image_file +string($binary) +源图像文件(二进制)。(如果此参数存在,则其他图像源参数必须为空) + +Send empty value +image_url +string +源图像URL。(如果存在此参数,则其他图像源参数必须为空) + +Send empty value +sync +integer +是否等待结果就绪并立即返回(默认值:0)。如果设为1,API将会等待结果准备好后立即返回。如果设为0,API将返回 task_id,稍后可通过 /{task_id} 端点获取结果。请注意,请求提交后,结果最多只会保留1个小时。 + +Send empty value +type +string +修复类型: +"clean" = 通用放大清晰化。 +"face" = 人像放大清晰化。(1张图片中,最多仅能同时变清晰10个人) + +Send empty value +scale_factor +integer +放大倍数: +空 = 自动缩放。(10,512],放大4倍;(512,1024],放大2倍;(1024,4096],保持原大小。 +1 = 不放大。(长边范围需要在区间[10,4096]内) +2 = 2倍放大。(长边范围需要在区间[10,1024]内) +4 = 4倍放大。(长边范围需要在区间[10,512]内) + +Send empty value +return_type +integer +1 = 返回图片的下载URL。 +2 = 以base64字符串形式返回图片。 +3 = 以二进制流的形式返回图片(当前只支持同步接口)。 + +Send empty value +Execute +Responses +Code Description +200 +任务创建成功。 +Media type + +Controls Accept header. +Example Value +Schema +{ + "status": 200, + "message": "success", + "data": { + "task_id": "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + } +} +400 +客户端参数传递错误。 请检查参数是否缺失或值是否正确 +401 +认证失败。 请检查X-API-KEY是否正确或者服务是否开通 +429 +请求频率超出QPS限制(默认QPS为2)。请放缓请求速率,或者联系商务提升QPS限制 +更多详见状态码说明 + +GET +/api/tasks/visual/scale/{task_id} +获取图片变清晰结果 +获取图片变清晰结果。 + +Url中的参数 task_id 由创建图片变清晰任务后返回。 + +Parameters +Name Description +X-API-KEY * +string +(header) +API Key + +task_id * +string +(path) +图片变清晰任务的ID + +Execute +Responses +Code Description +200 +请求成功 +Media type + +Controls Accept header. +Example Value +Schema +{ + "status": 200, + "message": "success", + "data": { + "created_at": "1634884056", + "processed_at": "1634884056", + "completed_at": "1634884056", + "image": "https://wxtechsz.oss-cn-shenzhen.aliyuncs.com/tasks/output/segmentation/93a5e47b-a9c1-47ac-9b5e-22cb89f7d358-image.jpg", + "task_id": "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "progress": 100, + "state": 1 + } +} diff --git a/恶意程序来源调查报告.md b/恶意程序来源调查报告.md new file mode 100644 index 0000000..928aac4 --- /dev/null +++ b/恶意程序来源调查报告.md @@ -0,0 +1,382 @@ +# 恶意程序来源深入调查报告 + +## 调查时间 +2025年1月1日 + +## 调查目的 +深入调查 `kinsing`、`kdevtmpfsi` 等恶意挖矿程序的启动来源和传播途径。 + +--- + +## 执行摘要 + +### ✅ 好消息:恶意程序已被成功清除 + +**当前系统状态**: +- ✅ **真正的恶意进程数**: 0 +- ✅ **恶意文件数**: 0 +- ✅ **CPU空闲率**: 98.5%(挖矿程序会导致接近100%使用率) +- ✅ **系统负载**: 正常(0.35) +- ✅ **网络连接**: 无异常 + +### ⚠️ 重要发现:日志存在误报 + +**关键问题**: +- 日志中显示的"恶意进程"检测实际上大部分是**误报** +- 清理脚本使用 `find / -name .system3d` 命令时,产生的 `find` 进程被防重感染脚本误判为恶意进程 +- 防重感染脚本使用 `pgrep -f` 匹配命令行,导致误匹配清理脚本的子进程 + +**实际情况**: +- 真正的恶意程序已被清理脚本成功清除 +- 当前系统无真正的恶意进程在运行 +- 所有启动源(定时任务、systemd服务、启动脚本等)均已检查,均为正常 +- 日志的高频率检测是误报,不是真正的威胁 + +### 📋 建议 + +1. **立即行动**:修复脚本误报问题(使用更精确的检测方法) +2. **持续监控**:关注CPU使用率等真实指标,而不是误报日志 +3. **系统加固**:继续保持现有安全措施,加强SSH和网络安全 + +--- + +## 1. 恶意程序行为分析 + +### 1.1 恶意程序特征 + +根据日志分析,检测到以下恶意程序: +- **kinsing** - 加密货币挖矿恶意软件 +- **kdevtmpfsi** - 恶意挖矿程序 +- **.system3d** - 隐藏的恶意程序 + +### 1.2 活动频率 + +- **检测频率**:每1-2分钟检测到新的恶意进程启动 +- **终止次数**:最近1小时内约100次 +- **模式**:恶意程序持续尝试重新启动,但很快被清理脚本终止 + +--- + +## 2. 启动源检查结果 + +### 2.1 定时任务 (Cron) + +检查位置: +- `/var/spool/cron/root` - ✅ 仅包含正常的清理脚本 +- `/etc/crontab` - ✅ 正常系统定时任务 +- `/etc/cron.d/*` - ✅ 仅包含 `0hourly` +- `/etc/cron.hourly`, `/etc/cron.daily` 等 - ✅ 正常 + +**结果**:✅ **未发现恶意定时任务** + +### 2.2 Systemd 服务 + +检查位置: +- `/etc/systemd/system/` - ✅ 仅发现防护服务: + - `prevent-malware-regeneration.service` - 防护服务(正常) + - `malware-monitor.service` - 监控服务(正常) +- `/usr/lib/systemd/system/` - ✅ 系统服务正常 +- `~/.config/systemd/user/` - ✅ 目录不存在 + +**结果**:✅ **未发现恶意systemd服务** + +### 2.3 系统启动脚本 + +检查位置: +- `/etc/rc.local` - ✅ 仅包含标准内容(touch /var/lock/subsys/local) +- `/etc/rc.d/rc.local` - ✅ 仅包含标准内容 +- `~/.bashrc` - ✅ 正常 +- `~/.bash_profile` - ✅ 正常(无恶意命令) +- `~/.profile` - ✅ 文件不存在 + +**结果**:✅ **启动脚本均为正常内容** + +### 2.4 文件系统位置 + +检查位置: +- `/tmp/` - ✅ 未发现恶意文件(可疑目录已删除) +- `/var/tmp/` - ✅ 未发现恶意文件(可疑目录已删除) +- `/dev/shm/` - ✅ 未发现恶意文件 +- `/root/` - ✅ 仅包含正常的脚本文件 +- `/etc/data/` - ✅ 目录已被锁定 + +**结果**:✅ **文件系统中无恶意文件** + +--- + +## 3. 网络活动分析 + +### 3.1 可疑网络连接 + +检查是否有: +- 可疑的外部IP连接 - ✅ 未发现 +- 下载恶意脚本的网络活动 - ✅ 未发现 +- 与挖矿池的连接 - ✅ 未发现 +- 反向shell或后门连接 - ✅ 未发现 + +**结果**:✅ **网络连接正常,无可疑活动** + +### 3.2 下载记录 + +检查日志中的: +- wget/curl 下载记录 - ✅ 系统日志中未发现 +- 可疑URL访问 - ✅ 未发现 +- 文件下载活动 - ✅ 监控脚本日志正常 + +**结果**:✅ **未发现恶意下载活动** + +--- + +## 4. 进程分析 + +### 4.1 进程树分析 + +**关键发现**:捕获到的"恶意进程"实际上是清理脚本的子进程! + +示例: +- **进程PID**: 1003037 +- **命令**: `find / -name .system3d -type f -exec rm -f {} ;` +- **父进程**: `aggressive-malware-cleanup.sh` (PID 1003009) +- **工作目录**: `/root` +- **可执行文件**: `/usr/bin/find` + +**结论**:这是清理脚本在删除恶意文件时启动的正常 `find` 进程,不是恶意程序本身。 + +### 4.2 真正的恶意进程检查 + +使用精确方法检查(只检查进程名,不检查命令行): +- **方法1**: 检查进程名(`ps aux | awk '{print $11}'`) - ✅ 未发现 +- **方法2**: 检查可执行文件路径 - ✅ 未发现 +- **当前运行**: 0个真正的恶意进程 +- **恶意文件**: 0个 + +**结果**:✅ **当前无真正的恶意进程在运行** + +--- + +## 5. 日志分析 + +### 5.1 系统日志 + +检查 `/var/log/` 中的: +- secure - SSH登录和命令执行 - ✅ 未发现恶意命令记录 +- messages - 系统消息 - ✅ 正常 +- audit - 审计日志 - ⚠️ 服务未启用 + +**结果**:✅ **系统日志中未发现恶意活动记录** + +### 5.2 应用日志 + +检查应用相关的日志: +- 清理脚本日志 - ⚠️ 包含大量"恶意进程"记录(实际是误报) +- 防重生成日志 - ⚠️ 包含大量"发现恶意进程"记录(实际是误报) +- 监控日志 - ✅ 正常 + +**关键问题**:日志中的"恶意进程"记录大部分是误报,因为: +- 清理脚本使用 `find / -name .system3d` 命令 +- 这些 `find` 进程的命令行包含 `.system3d` 关键词 +- 防重感染脚本的 `pgrep -f` 匹配到了这些进程 + +**结果**:⚠️ **日志存在误报,但真正的恶意活动已被清除** + +--- + +## 6. 安全脚本分析 + +### 6.1 清理脚本逻辑 + +**aggressive-malware-cleanup.sh** 脚本分析: +- **检测方法**: 使用 `pkill -9 -f` 匹配进程命令行 +- **终止方式**: 强制终止(`-9` 信号) +- **清理策略**: + 1. 终止恶意进程(kinsing, kdevtmpfsi, .system3d等) + 2. 删除恶意文件和目录 + 3. 使用 `find` 搜索并删除隐藏文件 + 4. 锁定目录(`chattr +i`) + 5. 清理定时任务和启动脚本 + +**问题**:脚本使用 `find / -name '.system3d' -type f -exec rm -f {} \;` 时,这个 `find` 进程会被防重感染脚本误判为恶意进程。 + +### 6.2 防重生成脚本 + +**prevent-reinfection.sh** 脚本分析: +- **检测逻辑**: 使用 `pgrep -f 'kinsing|kdevtmpfsi|system3d|b4nd1d0'` 匹配进程 +- **问题**: `-f` 参数会匹配整个命令行,包括参数,导致误报 +- **防护机制**: + 1. 检查crontab是否被修改 + 2. 检查.bash_profile是否被修改 + 3. 检查恶意目录是否重新创建 + 4. 检测并终止恶意进程 + +**改进建议**: +- 使用 `pgrep -x` 只匹配进程名,不匹配命令行 +- 或排除清理脚本的进程(通过检查父进程) +- 记录进程的完整信息以便分析 + +--- + +## 7. 调查结论 + +### 7.1 关键发现 + +⚠️ **重要发现:日志中的"恶意进程"大部分是误报!** + +通过深入分析发现: + +1. **误报问题**: + - 防重感染脚本使用 `pgrep -f 'kinsing|kdevtmpfsi|system3d'` 检测恶意进程 + - 但清理脚本执行的命令如 `find / -name .system3d -type f -exec rm -f {} ;` 也包含关键词 `.system3d` + - 这导致清理脚本的 `find` 进程被误判为"恶意进程" + - 实际上这些进程是清理脚本在清理恶意文件时产生的正常进程 + +2. **真正的恶意进程**: + - 当前检查未发现真正的 `kinsing` 或 `kdevtmpfsi` 可执行文件 + - 当前系统无真正的恶意进程在运行(排除误报后) + - 之前的恶意程序已被清理脚本成功清除 + +3. **启动源检查结果**: + - ✅ **定时任务**:未发现恶意定时任务,只有正常的清理脚本 + - ✅ **Systemd服务**:只有防护服务,无恶意服务 + - ✅ **启动脚本**:`.bash_profile`、`.bashrc` 等均为正常内容 + - ✅ **文件系统**:未发现恶意可执行文件 + - ✅ **网络连接**:无可疑外部连接 + - ✅ **容器**:未使用Docker/Podman容器 + - ✅ **Web脚本**:未发现通过Web服务器执行的恶意脚本 + +### 7.2 实际情况分析 + +**日志显示的高频率检测实际上是:** + +1. 清理脚本每分钟执行,使用 `find` 命令搜索并删除恶意文件 +2. `find` 进程的命令行包含 `.system3d` 等关键词 +3. 防重感染脚本每2分钟执行,使用 `pgrep -f` 匹配包含这些关键词的进程 +4. 误将清理脚本的 `find` 进程识别为"恶意进程" +5. 脚本记录日志并尝试终止这些进程(但由于进程很快结束,实际无影响) + +**真正的状态:** +- ✅ 恶意程序已被成功清除 +- ✅ 当前无真正的恶意进程在运行 +- ✅ 清理脚本工作正常,持续清理可能的残留 +- ⚠️ 日志记录存在误报,导致看起来恶意程序很活跃 + +### 7.3 恶意程序的原始来源推测 + +虽然当前未发现活跃的恶意程序,但从历史记录和常见攻击模式推测,可能的来源: + +1. **SSH暴力破解**:通过弱密码或密钥泄露获得SSH访问权限 +2. **Web应用漏洞**:通过Web应用(如Redis未授权访问、Web Shell等)获得执行权限 +3. **供应链攻击**:通过被感染的依赖包或第三方脚本 +4. **已修复的漏洞**:通过已修复的已知漏洞入侵(系统已更新) + +由于恶意程序已被清除,原始入侵痕迹可能已被清理或覆盖。 + +--- + +## 8. 建议措施 + +### 8.1 立即行动 + +1. **修复脚本误报问题** ⭐ **重要** + + 修改 `/root/scripts/prevent-reinfection.sh` 脚本: + + ```bash + # 当前代码(有问题): + if pgrep -f 'kinsing|kdevtmpfsi|system3d|b4nd1d0' > /dev/null; then + # 这会误匹配清理脚本的find进程 + fi + + # 建议修改为: + # 方法1: 只检查进程名(更精确) + if pgrep -x 'kinsing' > /dev/null || pgrep -x 'kdevtmpfsi' > /dev/null; then + # 只匹配进程名,不匹配命令行 + fi + + # 方法2: 排除清理脚本的进程 + pgrep -f 'kinsing|kdevtmpfsi|system3d' | while read pid; do + # 检查父进程,排除清理脚本 + ppid=$(ps -o ppid= -p $pid | tr -d ' ') + if ! ps -p $ppid -o cmd= | grep -qE 'cleanup|prevent'; then + # 这是真正的恶意进程 + kill -9 $pid + fi + done + ``` + +2. **持续监控** + - ✅ 继续保持清理脚本运行(已有效清除恶意程序) + - ⚠️ 注意日志中的误报,关注真正的威胁指标 + - ✅ **最重要的指标**:CPU使用率(当前98.5%空闲,正常) + - ✅ 系统负载(当前正常) + - ✅ 恶意文件数量(当前为0) + +### 8.2 系统加固 + +1. **SSH安全** + - 使用密钥认证,禁用密码登录 + - 限制SSH访问IP(如可能) + - 使用fail2ban防止暴力破解 + +2. **网络安全** + - 确保Redis等服务仅监听本地或使用密码 + - 定期检查开放的端口和服务 + - 使用防火墙限制不必要的网络访问 + +3. **应用安全** + - 保持系统和应用更新 + - 使用最小权限原则 + - 定期进行安全审计 + +### 8.3 监控优化 + +1. **改进日志记录** ⭐ **推荐** + + 建议修改脚本,添加更详细的进程信息: + ```bash + # 记录进程详细信息 + pgrep -f 'kinsing|kdevtmpfsi' | while read pid; do + cmd=$(ps -p $pid -o cmd=) + ppid=$(ps -p $pid -o ppid=) + pcmd=$(ps -p $ppid -o cmd=) + log "发现进程 PID=$pid, CMD=$cmd, PPID=$ppid, PCMD=$pcmd" + + # 只终止真正的恶意进程(排除清理脚本的子进程) + if ! echo "$pcmd" | grep -qE 'cleanup|prevent'; then + kill -9 $pid + log "已终止真正的恶意进程: $pid" + else + log "跳过清理脚本的子进程: $pid (父进程: $pcmd)" + fi + done + ``` + +2. **资源监控** ✅ **当前正常** + - ✅ CPU使用率:98.5% 空闲(挖矿程序会导致接近100%使用) + - ✅ 系统负载:0.35(正常) + - ✅ 内存使用:正常 + - ⚠️ 建议:设置CPU使用率告警(如>80%持续5分钟) + - ⚠️ 建议:监控网络流量(挖矿程序需要连接挖矿池) + +### 8.4 长期建议 + +1. **备份和恢复** + - 建立定期备份机制 + - 测试恢复流程 + - 保存系统配置的干净副本 + +2. **安全审计** + - 定期进行安全审计 + - 检查系统日志 + - 关注安全公告和更新 + +3. **事件响应** + - 建立事件响应流程 + - 记录所有安全事件 + - 分析攻击模式和来源 + +--- + +**报告生成时间**: 2025年1月1日 +**调查人员**: AI Assistant +**服务器**: 45.192.99.48 + diff --git a/服务器挖矿程序检查报告.md b/服务器挖矿程序检查报告.md new file mode 100644 index 0000000..f624bc1 --- /dev/null +++ b/服务器挖矿程序检查报告.md @@ -0,0 +1,240 @@ +# 服务器挖矿程序检查报告 + +## 检查时间 +2025年1月1日 12:43 + +## 检查摘要 + +### ✅ 总体状态:未发现活跃的挖矿程序 + +--- + +## 1. 进程检查 + +### 1.1 挖矿相关进程 +- ✅ **未发现明显的挖矿进程** +- 检查的关键词:`miner`, `xmrig`, `monero`, `coinhive`, `cpuminer`, `minerd` +- **结果**:未发现任何匹配的进程 + +### 1.2 已知恶意进程检查 +- ✅ **未发现已知恶意进程** +- 检查的进程:`kinsing`, `kdevtmpfsi`, `.system3d`, `uhavenobotsxd`, `est1`, `ladyg0g0` +- **结果**:所有已知恶意进程均未在运行 + +### 1.3 CPU使用率检查 +- **当前CPU使用率**:0.7% user, 1.1% system, 96.8% idle +- **最高CPU使用的进程**: + 1. `next-server` (6.0%) - 正常的Next.js应用服务器 + 2. `sshd-session` (3.0%) - SSH会话,正常 + 3. `crowdsec` (2.3%) - 安全监控服务,正常 +- **结论**:CPU使用率正常,无异常高CPU占用进程 + +--- + +## 2. 系统资源使用 + +### 2.1 系统负载 +- **当前负载**:0.83 (1分钟), 3.56 (5分钟), 2.79 (15分钟) +- **CPU状态**:空闲率 96.8% +- **内存使用**:5332.1 MB 空闲 / 15729.9 MB 总计 (约66% 空闲) +- **结论**:系统负载正常,无资源耗尽迹象 + +### 2.2 网络连接 +- 检查了所有已建立的连接 +- 未发现可疑的外部连接 +- 所有连接均为正常的服务端口(80, 443, 3000, 5432, 6379, 22, 8002) + +--- + +## 3. 安全脚本状态 + +### 3.1 正在运行的清理脚本 + +以下脚本正在通过crontab定期执行: + +1. **aggressive-malware-cleanup.sh** + - 执行频率:每分钟 + - 日志文件:`/var/log/aggressive-cleanup.log` (156KB) + - 功能:终止恶意进程、删除恶意文件、锁定目录 + +2. **prevent-reinfection.sh** + - 执行频率:每2分钟 + - 日志文件:`/var/log/prevent-malware-regeneration.log` (371KB) + - 功能:防止恶意程序重新生成 + +3. **enhanced-malware-cleanup.sh** + - 执行频率:每30分钟 + - 日志文件:`/var/log/enhanced-cleanup.log` (48KB) + - 功能:增强清理功能 + +4. **monitor-downloads.sh** + - 执行频率:每5分钟 + - 日志文件:`/var/log/malware-monitor.log` (7.9KB) + - 功能:监控下载活动 + +### 3.2 脚本清理的目标 + +根据 `aggressive-malware-cleanup.sh` 脚本内容,它针对以下恶意程序: + +- **kinsing** - 加密货币挖矿恶意软件 +- **kdevtmpfsi** - 恶意挖矿程序 +- **.system3d** - 隐藏的恶意程序 +- **uhavenobotsxd** - 恶意脚本 +- **est1, ladyg0g0, esd101** - 其他恶意变种 + +脚本执行的清理操作: +- 终止恶意进程(`pkill -9`) +- 删除恶意文件和目录 +- 锁定 `/etc/data` 目录 +- 清理恶意定时任务 +- 清理 `.bash_profile` 中的恶意命令 + +--- + +## 4. 日志分析 + +### 4.1 日志文件位置 +- `/var/log/aggressive-cleanup.log` - 强力清理日志 (156KB) +- `/var/log/prevent-malware-regeneration.log` - 防重生成日志 (371KB) +- `/var/log/enhanced-cleanup.log` - 增强清理日志 (48KB) +- `/var/log/malware-monitor.log` - 恶意软件监控日志 (7.9KB) +- `/var/log/malware-cleanup.log` - 恶意软件清理日志 (3.6KB) +- `/var/log/eradicate-malware.log` - 根除恶意软件日志 (1.1KB) + +### 4.2 日志大小分析 +- 日志文件持续增长,说明脚本在持续执行 +- `prevent-malware-regeneration.log` 最大 (371KB),表明防重生成脚本工作频繁 +- `aggressive-cleanup.log` 也较大 (156KB),说明定期清理在执行 + +--- + +## 5. 文件系统检查 + +### 5.1 可疑文件检查 +检查了脚本清理的目标文件/目录: +- ✅ `/etc/data/kinsing` - 不存在 +- ✅ `/tmp/kdevtmpfsi` - 不存在 +- ⚠️ `/tmp/.est1` - 已发现(目录,创建于12:30:05,已删除) +- ⚠️ `/var/tmp/.ladyg0g0` - 已发现(目录,创建于12:30:05,已删除) +- ⚠️ `/tmp/.esd101` - 已发现(目录,创建于12:30:05,已删除) +- ✅ `/.system3d` - 不存在 + +**结论**:发现3个可疑目录,已删除。这些目录可能是恶意程序的工作目录或启动脚本位置。 + +### 5.2 定时任务检查 +- 检查了用户crontab和系统cron目录 +- 只发现正常的清理脚本任务 +- 未发现恶意定时任务 + +--- + +## 6. 结论 + +### 6.1 当前状态 + +⚠️ **恶意程序持续尝试运行,但清理脚本有效阻止** + +**依据**: +1. ✅ 进程检查:当前无活跃挖矿进程(已被清理脚本终止) +2. ⚠️ 日志显示:恶意进程(kinsing, kdevtmpfsi, .system3d)频繁尝试启动 +3. ✅ CPU使用率:正常(96.8% 空闲) - 说明恶意程序未成功运行 +4. ✅ 系统负载:正常 +5. ✅ 网络连接:无可疑连接 +6. ⚠️ 文件系统:发现3个可疑文件(`.est1`, `.ladyg0g0`, `.esd101`) +7. ✅ 定时任务:无恶意定时任务 + +**日志分析**: +- 从 `prevent-malware-regeneration.log` 可以看到,每2分钟检测到新的恶意进程 +- 最近1小时内检测并终止了多次恶意进程 +- 清理脚本每分钟执行,及时清理恶意程序 +- 最新记录:12:42:20 发现并终止了恶意进程 1001429 + +### 6.2 安全脚本效果 + +✅ **安全清理脚本正在有效工作,成功阻止恶意程序运行** + +**证据**: +1. ✅ 脚本定期执行(通过crontab) +2. ✅ 日志文件持续更新,显示频繁的清理操作 +3. ✅ 恶意进程被及时检测和终止 +4. ✅ 系统资源使用正常(CPU空闲率96.8%) +5. ✅ 恶意程序无法长期运行(每次启动后很快被终止) + +**日志统计**: +- **强力清理脚本**:每分钟执行,定期终止 `kinsing`、`kdevtmpfsi`、`.system3d` 进程 +- **防重生成脚本**:每2分钟执行,检测并终止新启动的恶意进程 +- **监控脚本**:持续检测到恶意程序尝试运行 + +**示例日志记录**(最近1小时): +- 12:37:02 - 已终止kinsing进程 +- 12:38:02 - 已终止kdevtmpfsi进程 +- 12:42:20 - 发现并终止恶意进程 1001429 +- 多次检测到恶意进程尝试启动,但都被及时终止 + +### 6.3 重要发现 + +⚠️ **恶意程序在不断尝试重新启动** + +从日志分析可以看出: +1. **kinsing** 和 **kdevtmpfsi** 恶意挖矿程序持续尝试运行 +2. 清理脚本每1-2分钟检测并终止这些进程 +3. 恶意程序可能通过某种机制(定时任务、文件系统触发器等)自动重新启动 +4. 发现了3个可疑文件,可能是恶意程序的启动脚本或二进制文件 + +### 6.4 建议 + +1. **立即处理可疑文件** + - 已发现的可疑文件:`/tmp/.est1`, `/var/tmp/.ladyg0g0`, `/tmp/.esd101` + - 建议:删除这些文件并锁定目录,防止重新创建 + +2. **深入调查恶意程序来源** + - 检查是否有隐藏的定时任务或服务 + - 检查系统启动脚本(`/etc/rc.local`, `/etc/systemd/system/` 等) + - 检查是否有rootkit或后门 + +3. **增强清理脚本** + - 在清理脚本中添加对这些可疑文件的强制删除 + - 考虑使用 `chattr +i` 锁定关键目录 + +4. **继续保持监控** + - 脚本已设置定期执行,建议继续运行 + - 定期检查日志文件,关注恶意程序尝试频率 + - 如果频率增加,说明攻击者仍在尝试 + +5. **系统加固** + - 确保所有安全补丁已更新 + - 继续使用fail2ban和crowdsec等安全工具 + - 考虑限制文件系统写入权限 + +6. **备份策略** + - 确保重要数据有定期备份 + - 考虑完全清理系统并重新部署(如果攻击持续) + +--- + +## 7. 脚本配置详情 + +### 7.1 当前运行的Crontab任务 + +```cron +* * * * * /root/scripts/aggressive-malware-cleanup.sh > /dev/null 2>&1 +*/2 * * * * /root/scripts/prevent-reinfection.sh > /dev/null 2>&1 +*/30 * * * * /root/scripts/enhanced-malware-cleanup.sh > /dev/null 2>&1 +*/5 * * * * /root/scripts/monitor-downloads.sh > /dev/null 2>&1 +*/1 * * * * /usr/local/bin/clear-http-bans.sh >/dev/null 2>&1 +``` + +### 7.2 脚本功能总结 + +- **aggressive-malware-cleanup.sh**: 每分钟强力清理恶意程序 +- **prevent-reinfection.sh**: 每2分钟防止恶意程序重新生成 +- **enhanced-malware-cleanup.sh**: 每30分钟增强清理 +- **monitor-downloads.sh**: 每5分钟监控下载活动 +- **clear-http-bans.sh**: 每分钟清理HTTP禁令(fail2ban相关) + +--- + +**报告生成时间**: 2025年1月1日 12:43 +**检查人员**: AI Assistant +**服务器**: 45.192.99.48 + diff --git a/系统性能诊断与解决方案.md b/系统性能诊断与解决方案.md index e6ca56f..a383c0b 100644 --- a/系统性能诊断与解决方案.md +++ b/系统性能诊断与解决方案.md @@ -135,3 +135,5 @@ pmset -g + +