You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGINX+Rails环境下恶意请求IP的记录、封禁及高频请求统计与安全优化咨询

针对你遇到的机器人扫描和攻击问题,结合Rails+Nginx的架构,我整理了一套从日志收集、IP封禁到安全加固的完整方案,具体如下:

解决方案:Rails+Nginx环境下的机器人攻击防护与日志分析

一、捕获路由错误并记录关键信息

首先,我们需要在Rails应用中主动捕获ActionController::RoutingError,并记录请求IP、URL及请求次数。推荐用Redis做实时计数,它高效且适配这类统计场景:

  1. 配置Redis依赖
    在Gemfile中添加:

    gem 'redis'
    

    执行bundle install完成安装。

  2. 自定义异常处理逻辑
    在app/controllers/application_controller.rb中添加异常捕获代码:

    rescue_from ActionController::RoutingError do |exception|
      # 获取请求来源IP
      client_ip = request.remote_ip
      # 获取被请求的恶意URL
      requested_url = request.fullpath
    
      # 用Redis统计该IP的攻击次数
      Redis.current.incr("attack:ip:#{client_ip}")
      # 统计恶意URL的被请求频次
      Redis.current.incr("attack:url:#{requested_url}")
    
      # 将详细攻击日志写入自定义文件
      File.open(Rails.root.join('log', 'attack_logs.log'), 'a') do |f|
        f.puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} | IP: #{client_ip} | URL: #{requested_url} | Error: #{exception.message}"
      end
    
      # 保持原有404返回逻辑
      render file: Rails.public_path.join('404.html'), status: :not_found, layout: false
    end
    

    注意:MAC地址无法通过公网HTTP请求获取,因为HTTP是基于IP的应用层协议,MAC属于链路层信息,仅同一局域网内的设备才能获取对方MAC,公网环境下服务器无法拿到攻击者的MAC地址。

二、自动封禁恶意IP

方案1:用Fail2ban监听日志(推荐)

Fail2ban可以自动扫描日志文件、匹配攻击特征,通过iptables自动封禁违规IP,配置步骤如下:

  1. 安装Fail2ban
    Debian/Ubuntu系统:

    sudo apt-get install fail2ban
    

    CentOS/RHEL系统:

    sudo yum install fail2ban
    
  2. 自定义过滤规则
    在/etc/fail2ban/filter.d/rails-routing-error.conf中添加:

    [Definition]
    failregex = ^.*IP: <HOST>.*No route matches.*$
    ignoreregex =
    
  3. 配置封禁规则
    在/etc/fail2ban/jail.local中添加:

    [rails-routing-error]
    enabled = true
    filter = rails-routing-error
    logpath = /path/to/your/rails/app/log/attack_logs.log
    maxretry = 5  # 累计5次错误请求即封禁
    bantime = 3600  # 封禁时长1小时(可按需调整)
    findtime = 600  # 统计周期为10分钟
    
  4. 重启Fail2ban生效

    sudo systemctl restart fail2ban
    

方案2:Nginx内置模块限制请求

如果不想额外部署工具,可以用Nginx的ngx_http_limit_req_module限制单IP请求速率:
在Nginx的http块中添加:

limit_req_zone $binary_remote_addr zone=one:10m rate=10r/m;

然后在你的Rails应用server配置块中添加:

location / {
  limit_req zone=one burst=5 nodelay;
  # 保留原有Nginx配置...
}

该规则限制单IP每分钟最多10次请求,超出部分直接返回503。

三、统计高频被攻击URL

方式1:Redis实时统计

之前的异常处理逻辑已经用Redis记录了URL请求次数,你可以写一个简单的Rake任务获取Top N恶意URL:
在lib/tasks/attack_stats.rake中添加:

namespace :attack do
  desc "获取被攻击频次最高的前10个URL"
  task top_urls: :environment do
    url_counts = Redis.current.keys("attack:url:*").each_with_object({}) do |key, hash|
      url = key.gsub("attack:url:", "")
      hash[url] = Redis.current.get(key).to_i
    end

    puts "Top 10 被攻击URL:"
    url_counts.sort_by { |_, count| -count }.first(10).each do |url, count|
      puts "#{url}: #{count} 次请求"
    end
  end
end

执行rake attack:top_urls即可查看结果。

方式2:直接分析日志文件

如果不用Redis,也可以用awk命令直接解析自定义攻击日志:

awk '{print $7}' /path/to/attack_logs.log | sort | uniq -c | sort -nr | head -10

注:命令中的$7需根据你的日志格式调整,确保对应到URL所在的列。

四、额外安全优化建议

  • 隐藏Rails版本信息:在config/application.rb中添加config.action_dispatch.default_headers['X-Rails-Version'] = nil,避免泄露版本给攻击者。
  • 启用Nginx安全头:在server块中添加:
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    
  • 强制HTTPS访问:配置Nginx将所有HTTP请求重定向到HTTPS,避免明文传输敏感信息。
  • 部署Web应用防火墙(WAF):给Nginx安装ModSecurity模块,拦截XSS、SQL注入等常见攻击。
  • 定期更新依赖:用bundle audit检查Gem中的安全漏洞,及时更新补丁。
  • 限制后台路径访问:如果有Rails控制台或管理后台,用Nginx配置仅允许特定IP访问。
  • 添加CAPTCHA验证:在登录、注册等敏感页面加入CAPTCHA,防止机器人自动化攻击。

内容的提问来源于stack exchange,提问作者CJG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:47:43