#!/usr/bin/env bash # ============================================================================= # ClamAV 病毒库离线同步脚本(外网侧执行) # ============================================================================= # # 场景:内网 MeshSafe 部署在光闸之后,无法访问外网签名服务器。 # 在外网机器上运行本脚本拉取最新 CVD 文件 → 打包 → 光闸摆渡 → 内网导入 # # 用法: # bash scripts/sync_clamav_db.sh # # 输出: # clamav-db-YYYYMMDD.tar.gz # 包含 main.cvd / daily.cvd / bytecode.cvd # # 和一个 import_clamav_db.sh 脚本(在光闸内侧执行) # # 完整流程: # 1) 外网:bash scripts/sync_clamav_db.sh → 生成 tar.gz # 2) 光闸:将 clamav-db-*.tar.gz 摆渡到内网 # 3) 内网:bash import_clamav_db.sh clamav-db-*.tar.gz # # 维护节奏:每周一次(官方每天更新,内网环境 7-14 天更新可接受) # ============================================================================= set -euo pipefail WORKDIR=$(mktemp -d) cleanup() { rm -rf "$WORKDIR"; } trap cleanup EXIT OUTDIR="$(pwd)/dist" mkdir -p "$OUTDIR" VERSION="$(date +%Y%m%d)" OUTFILE="clamav-db-${VERSION}.tar.gz" echo "=== MeshSafe ClamAV 离线同步 ===" echo "输出文件:$OUTDIR/$OUTFILE" echo # --- 方式 A:用 Docker 拉取(需要 Docker 环境)--- if command -v docker &>/dev/null; then echo "[1/2] 通过 Docker freshclam 拉取签名库..." docker run --rm \ -v "$WORKDIR":/var/lib/clamav \ clamav/clamav:latest \ freshclam --stdout echo " ✓ 签名库已下载到 $WORKDIR" else # --- 方式 B:系统已安装 ClamAV --- echo "[1/2] 系统内 freshclam 拉取..." if ! command -v freshclam &>/dev/null; then echo "✗ 未找到 docker 或 freshclam,退出" exit 1 fi freshclam --datadir="$WORKDIR" echo " ✓ 签名库已下载到 $WORKDIR" fi echo echo "[2/2] 打包..." ls -la "$WORKDIR"/*.cvd 2>/dev/null || ls -la "$WORKDIR"/*.cld 2>/dev/null || { echo "✗ 未找到 .cvd/.cld 文件,freshclam 可能失败" exit 1 } tar -czf "$OUTDIR/$OUTFILE" -C "$WORKDIR" . # 附带 import 脚本模板 cat > "$WORKDIR/import_clamav_db.sh" << 'EOF' #!/usr/bin/env bash # ============================================================================= # ClamAV 病毒库离线导入脚本(内网侧执行) # ============================================================================= # # 用法:bash import_clamav_db.sh clamav-db-*.tar.gz # # 要求:docker compose 已经启动 meshsafe-clamav 容器 # ============================================================================= set -euo pipefail TARBALL="${1:?用法: bash import_clamav_db.sh clamav-db-*.tar.gz}" if [ ! -f "$TARBALL" ]; then echo "✗ 文件不存在: $TARBALL" exit 1 fi echo "=== MeshSafe ClamAV 离线导入 ===" echo "输入:$TARBALL" echo # 解压到临时目录 TMPDIR=$(mktemp -d) trap "rm -rf $TMPDIR" EXIT tar -xzf "$TARBALL" -C "$TMPDIR" echo "[1/3] 停止 clamd(如果在运行)..." docker compose -f docker-compose.yml exec -T clamav supervisorctl stop clamd 2>/dev/null || true sleep 2 echo "[2/3] 覆盖签名库文件..." docker compose -f docker-compose.yml cp "$TMPDIR"/. clamav:/var/lib/clamav/ echo "[3/3] 重启 clamd..." docker compose -f docker-compose.yml restart clamav echo echo "✓ 导入完成。验证:" echo " docker compose logs --tail 20 clamav" echo " 或 curl http://localhost:8443/api/v1/health 看 clamav signature 字段" EOF chmod +x "$WORKDIR/import_clamav_db.sh" # 重新打包包含 import 脚本 tar -czf "$OUTDIR/$OUTFILE" -C "$WORKDIR" . echo echo "✓ 完成:$OUTDIR/$OUTFILE" echo " 大小:$(du -h "$OUTDIR/$OUTFILE" | cut -f1)" echo echo "后续步骤(内网侧):" echo " 1. 将 $OUTFILE 从光闸摆渡到内网" echo " 2. docker compose up -d" echo " 3. bash import_clamav_db.sh $OUTFILE"