优化使用Python定时从Nginx的日志中获取黑客的ip并加入访问黑名单

2024-11-07 11:21 优化使用Python定时从Nginx的日志中获取黑客的ip并加入访问黑名单已关闭评论

需要优化,考虑每次整个nginx日志文件读取内容长度很大,存在耗时并占用过多服务器资源,需要间隔时间内针对已经分析过的nginx日志不用重复分析,提供几种优化策略以减少读取文件的频率和资源占用:

1. 记录日志文件的上次分析位置

可以利用日志文件的偏移量来优化读取方式,每次只读取新增的日志内容。这种方式特别适合于增长型日志文件,例如 Nginx 的访问日志。

具体实现方法:

  • 保存上次读取的偏移量:每次读取日志文件后,记录该文件的最后一个读取位置(偏移量)。
  • 仅读取新增日志:下次运行时,从该偏移量继续读取新的日志内容,避免重复分析已读取的日志。
import os
import re
import subprocess
from datetime import datetime

NGINX_LOG_FILE = '/var/log/nginx/access.log'
BLACKLIST_FILE = '/etc/nginx/includes/blackListIp.conf'
OFFSET_FILE = '/tmp/nginx_log_offset.txt'

HEX_PATTERN = re.compile(r'\\x[0-9A-Fa-f]{2}')
IP_PATTERN = re.compile(r'(\d{1,3}\.){3}\d{1,3}')

def get_last_offset():
    """获取上次日志读取的偏移量"""
    if os.path.exists(OFFSET_FILE):
        with open(OFFSET_FILE, 'r') as f:
            return int(f.read().strip())
    return 0

def save_offset(offset):
    """保存当前日志读取的偏移量"""
    with open(OFFSET_FILE, 'w') as f:
        f.write(str(offset))

def extract_suspicious_ips(log_file):
    """从上次偏移量开始提取可疑IP"""
    suspicious_ips = set()
    last_offset = get_last_offset()

    with open(log_file, 'r') as file:
        # 移动到上次读取的位置
        file.seek(last_offset)

        # 逐行读取新增日志
        for line in file:
            if HEX_PATTERN.search(line):
                match = IP_PATTERN.search(line)
                if match:
                    ip_address = match.group(0)
                    suspicious_ips.add(ip_address)

        # 保存当前偏移量
        save_offset(file.tell())

    return suspicious_ips

def update_blacklist(blacklist_file, suspicious_ips):
    """更新黑名单文件,添加新的可疑IP"""
    existing_ips = set()
    with open(blacklist_file, 'r') as file:
        for line in file:
            ip_match = IP_PATTERN.search(line)
            if ip_match:
                existing_ips.add(ip_match.group(0))

    new_ips = suspicious_ips - existing_ips
    if not new_ips:
        print(f"{datetime.now()}: 没有新的可疑IP需要添加。")
        return False

    with open(blacklist_file, 'a') as file:
        for ip in new_ips:
            file.write(f"deny {ip};\n")

    print(f"{datetime.now()}: 添加新的可疑IP到黑名单: {', '.join(new_ips)}")
    return True

def reload_nginx():
    try:
        subprocess.run(['nginx', '-s', 'reload'], check=True)
        print(f"{datetime.now()}: 成功重新加载Nginx配置。")
    except subprocess.CalledProcessError:
        print(f"{datetime.now()}: 重新加载Nginx配置失败。")

def main():
    suspicious_ips = extract_suspicious_ips(NGINX_LOG_FILE)
    if update_blacklist(BLACKLIST_FILE, suspicious_ips):
        reload_nginx()

if __name__ == "__main__":
    main()

优势
- 减少重复分析已读取的日志条目,提高了效率。
- 偏移量记录文件较小,资源占用低。


2. 使用 Nginx 日志轮替机制

使用 Nginx 的日志轮替功能(logrotate),结合脚本只分析最近轮替出来的日志文件,避免处理过于庞大的日志文件。

具体步骤:

  • 配置 logrotate,为 Nginx 日志设置合理的轮替间隔(如每天或每小时),并设置保留的旧日志数量。
  • 仅分析最新的日志文件(如 /var/log/nginx/access.log),无需遍历所有旧日志。

logrotate 示例配置

/etc/logrotate.d/nginx 文件中,添加以下内容:

/var/log/nginx/access.log {
    daily
    rotate 7
    missingok
    notifempty
    compress
    delaycompress
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

优势
- 有助于控制日志文件大小,便于定期清理和压缩历史日志。
- 减少脚本每次读取的数据量,提高效率。


3. 使用文件监控来自动触发

可以使用文件监控工具(如 inotify)来监视日志文件的变更,只有在文件变更时才触发分析脚本,从而减少无用的定时检查。

示例命令

inotifywait -m /var/log/nginx/access.log -e modify |
while read path action file; do
    /usr/bin/python3 /path/to/your/script.py
done

优势
- 实时监控文件变化,无需定时检查。
- 仅在文件修改时触发分析,避免无用的资源消耗。


4. 使用高效的定时机制和日志采样

如无需实时检测,可以通过 低频率采样多进程并发 优化性能:

  • 将脚本设为每小时执行一次,而不是每几分钟,适合不需要实时检测的场景。
  • 使用并发的方式对大日志文件进行分块处理,提高处理效率。

最佳组合建议

  • 若需要实时检测,使用 文件偏移量记录inotify 监控 是较佳选择。
  • 若日常分析即可,轮替日志结合偏移量记录 是较为节省资源的选择。

当前文章价值7.65元,扫一扫支付后添加微信提供帮助!(如不能解决您的问题,可以申请退款)

你可能感兴趣的文章

来源:每日教程每日一例,深入学习实用技术教程,关注公众号TeachCourse
转载请注明出处: https://teachcourse.cn/3690.html ,谢谢支持!

资源分享

nginx服务器配置合并缓存特定资源配置和防盗链配置 nginx服务器配置合并缓存特定资源
Windows系统创建Python虚拟环境示例 Windows系统创建Python虚拟环境
Eclipse开发项目中红色感叹号问题解决办法 Eclipse开发项目中红色感叹号问
Claude Code安装过程记录 Claude Code安装过程记录

评论已关闭!