仿 D 盾,我用 Go 写了个简易文件夹监控工具,ch文件篡改溯源

我是无依,做技术支持这些年,服务器文件被篡改、挂马的问题一直很头疼,排查时想快速定位被改文件、追溯操作痕迹,总觉得现有工具要么繁琐要么适配性一般。D 盾的文件监控功能用着很顺手,于是就想着用 Go 语言做一个简易版的文件夹监控工具,核心复刻 D 盾的文件状态监控、篡改识别能力,满足基础的溯源需求就够了,目前这个工具已经放在我的 Gitee 仓库 gotools 的 monitor 模块中(仓库地址:https://gitee.com/li-laihu/gotools/tree/master/monitor),代码轻量、逻辑简单,能解决日常运维中文件篡改溯源的基础问题。

之所以做这个简易版监控工具,核心就是贴合自己的基础运维需求,不用复杂的功能,只保留 D 盾最核心的文件夹实时监听文件篡改识别,再加上基础的日志记录,能快速定位哪个文件被改了、什么时候被改的,就足够应对日常的挂马文件溯源、文件篡改排查了。相比市面上的成熟工具,这个简易版没有过多的配置项和冗余功能,编译后直接运行,上手就能用,适合和我一样有基础监控、简单溯源需求的运维同学。

选择 Go 语言开发,还是看中了它的轻量和跨平台性,编译后的可执行文件无需依赖任何运行环境,Linux、Windows 服务器上都能直接部署,而且 Go 的fsnotify包能很方便的实现文件系统监听,再结合原生的哈希计算包,几行核心代码就能实现文件指纹校验,开发成本低,运行也稳定,完全契合这个简易监控工具的开发初衷。

这个仿 D 盾的简易文件夹监控工具,目前只实现了核心基础功能,没有复杂的配置和拓展能力,主要就是三点:一是指定目录的文件创建、修改、删除事件实时监听;二是通过 MD5 计算文件指纹,对比判断文件是否被篡改;三是将文件操作事件、篡改信息记录到本地日志,为后续溯源提供依据。整体逻辑简单,代码量也不大,下面放几个核心功能的实现代码,能直观看到工具的核心逻辑:

1. 核心依赖引入

主要用到fsnotify做文件监听,crypto/md5做指纹计算,原生log做日志记录,都是 Go 的基础库或成熟轻量组件,无复杂依赖:

运行

package main

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"

	"github.com/fsnotify/fsnotify"
)

2. MD5 文件指纹计算函数

这是判断文件是否被篡改的核心,读取文件内容计算 MD5 值,首次运行生成文件原始 MD5,后续文件变化时重新计算对比,不一致即判定为篡改:

// GetFileMD5 计算文件MD5值
func GetFileMD5(filePath string) (string, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return "", err
	}
	defer file.Close()

	hash := md5.New()
	if _, err := io.Copy(hash, file); err != nil {
		return "", err
	}

	md5Str := hex.EncodeToString(hash.Sum(nil))
	return md5Str, nil
}

3. 初始化文件指纹库

首次监控指定目录时,遍历目录下所有文件,计算 MD5 值并存储在 map 中,作为文件的原始指纹基准:

// InitFileMD5Map 初始化指定目录的文件MD5映射
func InitFileMD5Map(dir string) (map[string]string, error) {
	fileMD5Map := make(map[string]string)
	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		// 忽略文件夹,只计算文件MD5
		if !info.IsDir() {
			md5Str, err := GetFileMD5(path)
			if err != nil {
				log.Printf("计算文件%sMD5失败: %vn", path, err)
				return nil
			}
			fileMD5Map[path] = md5Str
		}
		return nil
	})
	return fileMD5Map, err
}

4. 核心文件监听逻辑

使用fsnotify监听指定目录,捕捉 Create、Write、Remove 事件,对创建 / 修改的文件重新计算 MD5 并与原始指纹对比,判断是否篡改,同时将所有事件记录到日志:

func main() {
	// 要监控的目录,可手动修改或简单做命令行传参
	monitorDir := "./monitor-test"
	// 初始化文件MD5指纹库
	fileMD5Map, err := InitFileMD5Map(monitorDir)
	if err != nil {
		log.Fatalf("初始化MD5指纹库失败: %vn", err)
	}
	log.Printf("初始化完成,当前监控目录%s下共%d个文件n", monitorDir, len(fileMD5Map))

	// 创建监听器
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatalf("创建监听器失败: %vn", err)
	}
	defer watcher.Close()

	// 添加监控目录
	err = watcher.Add(monitorDir)
	if err != nil {
		log.Fatalf("添加监控目录失败: %vn", err)
	}

	// 监听事件
	for {
		select {
		case event, ok := <-watcher.Events:
			if !ok {
				return
			}
			// 文件创建/修改事件
			if event.Op&fsnotify.Create == fsnotify.Create || event.Op&fsnotify.Write == fsnotify.Write {
				// 排除文件夹,只处理文件
				if info, err := os.Stat(event.Name); err == nil && !info.IsDir() {
					newMD5, _ := GetFileMD5(event.Name)
					if oldMD5, ok := fileMD5Map[event.Name]; ok {
						if newMD5 != oldMD5 {
							log.Printf("[文件篡改] %s, 原MD5: %s, 新MD5: %sn", event.Name, oldMD5, newMD5)
							fileMD5Map[event.Name] = newMD5 // 更新指纹库
						} else {
							log.Printf("[文件修改无内容变化] %sn", event.Name)
						}
					} else {
						fileMD5Map[event.Name] = newMD5
						log.Printf("[文件新建] %s, MD5: %sn", event.Name, newMD5)
					}
				}
			}
			// 文件删除事件
			if event.Op&fsnotify.Remove == fsnotify.Remove {
				delete(fileMD5Map, event.Name)
				log.Printf("[文件删除] %sn", event.Name)
			}
		case err, ok := <-watcher.Errors:
			if !ok {
				return
			}
			log.Printf("[监听错误] %vn", err)
		}
	}
}

以上就是这个简易监控工具的全部核心代码,逻辑非常直观,没有复杂的封装和拓展,目前的版本也仅支持单目录监控,无法忽略指定文件 / 后缀,也没有多目录配置、远程告警这些功能,完全是贴合基础需求的极简版本。

实际使用时,只需要修改代码中monitorDir为需要监控的服务器目录,然后在 Go 环境中执行go build -o monitor main.go编译成可执行文件,直接后台运行即可,工具会将所有文件操作、篡改信息以日志形式输出,也可以简单修改代码将日志写入本地文件,方便后续溯源查看。我自己在几台测试服务器上部署了这个工具,运行状态稳定,能精准捕捉文件的修改、创建、删除操作,也能快速识别出被篡改的文件,日常排查挂马、文件篡改问题,这个简易版完全够用。

当然,这个工具目前还有很多不足,后续会根据自己的实际使用需求做简单的优化,比如增加命令行传参指定监控目录,不用每次修改代码;增加日志写入本地文件的功能,方便长期追溯;还有忽略指定文件 / 后缀,避免监控日志冗余。暂时不会做太复杂的功能,始终保持轻量、简易的特点,毕竟核心需求就是基础监控和简单溯源,够用就好。

把这个简易的仿 D 盾监控工具放在 gotools 仓库,一方面是方便自己在不同服务器上部署,另一方面也希望能给有同样基础需求的运维同学一个参考,代码完全开源,大家可以根据自己的需求做简单的修改和拓展。其实运维工作中,很多时候不需要复杂的大型工具,一个轻量、简单、能解决实际问题的小工具,反而能提升工作效率。

后续如果对这个工具做了新的优化,我会在博客上同步更新,也会把优化后的代码提交到 Gitee 仓库。如果有同学对这个简易监控工具有不同的优化想法,也欢迎去仓库提 issue 交流,一起把这个小工具打磨得更贴合日常运维的基础需求。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇