Django如何禁用错误请求触发的邮件但保留文件日志记录
Django禁用恶意扫描请求告警邮件同时保留日志配置方案
问题说明
近期有攻击者尝试入侵Django服务器,发送的大量错误请求触发了海量告警邮件。需要实现:
- 禁用这类错误请求对应的邮件通知
- 保留错误请求的日志文件记录
- 兼容已有的
DisallowedHost日志配置逻辑
现有配置如下:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'null': { 'class': 'logging.NullHandler', }, }, 'loggers': { "django.security.DisallowedHost": { "handlers": ["null"], "propagate": False, }, }, }
实现逻辑
Django默认向管理员发送错误请求邮件的能力,由django.request日志器挂载的AdminEmailHandler实现:所有返回4xx/5xx状态码的请求错误都会触发该处理器。其中4xx类客户端错误(多为攻击者扫描产生的400、403、404、405等请求)日志级别为WARNING,5xx类服务端错误日志级别为ERROR。
只需要调整日志处理器的级别阈值,即可实现「5xx服务故障发告警、4xx恶意请求只写日志不发邮件」的效果。
完整配置示例
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s' }, }, 'handlers': { # 原有空处理器保留,用于屏蔽不需要输出的日志 'null': { 'class': 'logging.NullHandler', }, # 新增文件日志处理器,持久化存储所有错误请求日志 'file_request_error': { 'level': 'WARNING', 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/var/log/django/request_errors.log', # 替换为实际部署环境的日志文件路径 'maxBytes': 1024 * 1024 * 50, # 单日志文件最大50M,超过自动切割 'backupCount': 10, # 最多保留10个历史日志文件 'formatter': 'standard', }, # 调整邮件告警处理器,仅接收ERROR级别(对应5xx服务错误)日志 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'include_html': False, } }, 'loggers': { # 原有DisallowedHost配置保留,屏蔽主机头不匹配的扫描日志 "django.security.DisallowedHost": { "handlers": ["null"], "propagate": False, }, # 配置请求日志的处理规则 'django.request': { 'handlers': ['file_request_error', 'mail_admins'], 'level': 'WARNING', 'propagate': False, }, # 可选:所有安全类日志统一写入文件,不触发邮件 'django.security': { 'handlers': ['file_request_error'], 'level': 'WARNING', 'propagate': False, } }, }
补充说明
- 如果需要完全屏蔽某类特定错误的所有输出(和
DisallowedHost处理效果一致),只需要在loggers节点下新增对应日志器的配置,绑定null处理器并设置propagate: False即可,常见的扫描触发类日志包括django.security.DisallowedRedirect、django.security.InvalidHostHeader等。 - 配置部署前需要提前创建日志文件所在目录,并给Django运行用户分配目录读写权限,避免日志写入失败。
内容的提问来源于stack exchange,提问作者Jayen
相关产品推荐
相关产品推荐

