ClamAV扫描必须通过clamd守护进程(非clamscan命令行),上传后先落盘为临时文件,再用Go客户端(如go-clamd)通过Unix/TCP socket发送SCAN命令;需配置StreamSaveToDisk yes、设超时、校验响应、原子化处置恶意文件。

上传后立即调用 ClamAV 扫描临时文件
Go 本身不内置病毒扫描能力,必须依赖外部引擎。ClamAV 是最常用且可嵌入服务的开源方案,推荐用 clamd 守护进程模式(而非 clamscan 命令行),避免每次 fork 进程的开销和权限问题。
关键点是:文件上传后先保存为临时路径(如 /tmp/upload_abc123.bin),再通过 Unix socket 或 TCP 向 clamd 发送 SCAN 命令。不要等文件写完再启动扫描——应使用 io.Copy 边写边刷到磁盘,并在 Close() 后立刻触发扫描。
- 确保
clamd配置中启用了StreamSaveToDisk yes(否则流式扫描可能失败) - 临时文件路径需对
clamd进程用户(通常是clamav)可读,建议用os.Chmod(tmpFile, 0444)显式降权 - 扫描超时必须设限,
clamd默认响应超时是 120 秒,Go 客户端应设更短的context.WithTimeout(如 30 秒)
用 Go 封装 clamd SCAN 协议避免手动拼包
clamd 使用简单文本协议:发送 SCAN /path/to/file\n,接收类似 /path/to/file: OK\n 或 /path/to/file: Win.Trojan.XYZ-123.UNOFFICIAL FOUND。手动处理容易出错,尤其换行符、空格、路径含特殊字符时。
推荐直接使用 github.com/dutchcoders/go-clamd(轻量无 CGO),它已封装连接池、重试、协议解析。注意两点:
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
立即学习“go语言免费学习笔记(深入)”;
- 初始化客户端时传入正确的 socket 路径或地址,例如
clamd.New("unix:///var/run/clamd.scan/clamd.sock") - 调用
client.ScanFile(path)返回(string, bool, error):第一个值是原始响应字符串,第二个是是否干净(true表示 OK),第三个是网络/协议错误 - 不要忽略返回的
error—— 比如clamd重启中会导致连接拒绝,此时应退回到异步队列重试,而非直接放行文件
扫描结果为 FOUND 时的安全处置流程
检测出病毒不能只删临时文件就完事。攻击者可能利用竞争条件在扫描间隙移动或硬链接原文件,必须确保「上传→扫描→落库→清理」原子性。
- 扫描前生成唯一
upload_id(如 UUID),所有中间文件、数据库记录、日志都带上该 ID,便于追踪 - 若扫描返回
FOUND,立即执行:os.Remove(tmpPath)+os.RemoveAll(filepath.Dir(tmpPath))(清空整个临时目录层级)+ 记录告警到 SIEM - 严禁把恶意文件路径回显给用户(防止信息泄露),HTTP 响应统一返回
400 Bad Request+ 泛化提示如"File failed security validation" - 对高频触发病毒扫描的 IP,建议在网关层加限速或临时封禁,避免被当成免费杀毒 API 利用
绕过扫描的常见逃逸手段与应对
攻击者会尝试压缩、分卷、加密、空字节填充等方式绕过签名匹配。ClamAV 默认不自动解压深层嵌套,也不扫描密码保护 ZIP。
- 在
clamd.conf中启用ArchiveBlockEncrypted yes和MaxRecursion 16(默认 5 太浅) - 对上传的
.zip、.7z、.rar等归档类型,可额外用archive/zip或golang.org/x/exp/archive/zip提前检查文件头和内部路径,拦截明显异常(如../etc/passwd) - ClamAV 对混淆 JS/HTML 的检测较弱,若业务允许,可对
.js、.html文件追加 YARA 规则扫描(需编译支持 YARA 的 clamd) - 永远假设单层扫描不够——生产环境应搭配文件行为沙箱(如 Cuckoo)做二次分析,但那是异步离线流程,不在本次上传链路中阻塞
真正的难点不在调用 ClamAV,而在临时文件生命周期管理、错误传播边界、以及如何不让防御逻辑本身成为 DoS 入口。比如没设好 clamd 并发连接数,上传洪峰会把扫描服务拖垮,反而让所有文件“漏扫”。

















