div做网站排版,什么是品牌vi设计,导视设计原则,网站发布与推广【背景】最近要做一个防篡改的功能#xff0c;一开始是采用事件型的方式实现的#xff0c;结果发现会有一种情况如果某个文件短时间一直被外部进行多次恶意操作时#xff0c;一直防也不是个事#xff0c;应该在加一层防护—文件锁定#xff0c;这样就舒服多了… 【背景】最近要做一个防篡改的功能一开始是采用事件型的方式实现的结果发现会有一种情况如果某个文件短时间一直被外部进行多次恶意操作时一直防也不是个事应该在加一层防护—文件锁定这样就舒服多了
【好处】避免短时间站点被频繁攻击保证安全性的同时尽量保证业务正常运行
【实现思路】 一开始是想着用全局map去存储每一个文件的修改次数和最后一次时间后面发现这样子操作需要注意内存释放问题一不小心就会导致内存泄漏的情况。 所以盯上了一个好东西——优先队列通过结构体进行实现
【具体实现逻辑】 先定义了两个结构体和一个数据结构FileInfo用于存储文件的修改次数和最后修改时间UnlockTask用于存储待解锁的文件名和预定解锁时间。
type FileInfo struct {ModCount intLastMod time.Time
}type UnlockTask struct {FileName stringTime time.Time
}type UnlockQueue []*UnlockTask 再写下实现heap.Interface接口的方法主要用于操作优先队列用堆操作如Push和Pop来管理队列。
func (q UnlockQueue) Len() int { return len(q) }func (q UnlockQueue) Less(i, j int) bool {return q[i].Time.Before(q[j].Time)
}func (q UnlockQueue) Swap(i, j int) {q[i], q[j] q[j], q[i]
}func (q *UnlockQueue) Push(x interface{}) {item : x.(*UnlockTask)*q append(*q, item)
}func (q *UnlockQueue) Pop() interface{} {old : *qn : len(old)item : old[n-1]*q old[0 : n-1]return item
}
主实现函数 首先OnFileModified函数会在文件被修改时被调用更新文件的修改次数和最后修改时间。 然后CheckFileModCount函数定时检查文件的修改次数如果在5秒内文件被修改了10次就会调用lockFile函数锁定文件并将其添加到优先队列中预定在60秒后解锁。 最后CheckUnlockQueue函数会检查优先队列如果到了预定的解锁时间就会调用unlockFile函数解锁文件。
// 在文件被篡改时调用这个函数
func OnFileModified(fileName string) {info, ok : fileMap[fileName]if !ok {info FileInfo{ModCount: 0, LastMod: time.Now()}fileMap[fileName] info}//fmt.Printf(---检测该文件【%s】被篡改次数1, fileName)info.ModCountinfo.LastMod time.Now()
}// 定时检查文件修改次数
func CheckFileModCount() {for fileName, info : range fileMap {if time.Since(info.LastMod).Seconds() 5 info.ModCount 10 {fmt.Printf(---检测到文件【%s】在5s内被篡改了10次即将封锁该文件, fileName)lockFile(fileName)queueLock.Lock()heap.Push(unlockQueue, UnlockTask{FileName: fileName, Time: time.Now().Add(60 * time.Second)})queueLock.Unlock()}}
}// 检查解锁队列
func CheckUnlockQueue() {queueLock.Lock()for unlockQueue.Len() 0 time.Now().After(unlockQueue[0].Time) {task : heap.Pop(unlockQueue).(*UnlockTask)unlockFile(task.FileName)}queueLock.Unlock()
}// 锁定文件
func lockFile(fileName string) {cmd : exec.Command(chattr, i, fileName)err : cmd.Run()if err ! nil {fmt.Printf(Error locking file %s: %v\n, fileName, err)}
}// 解锁文件
func unlockFile(fileName string) {cmd : exec.Command(chattr, -i, fileName)err : cmd.Run()if err ! nil {fmt.Printf(Error unlocking file %s: %v\n, fileName, err)}
} main.go 主调用函数
func main() {heap.Init(core.UnlockQueue{})// 当文件确定被篡改时调用这个函数core.OnFileModified(event.Name)go func() {for {core.CheckFileModCount()core.CheckUnlockQueue()time.Sleep(1 * time.Second)}}()
}