Nginx + Passenger:缓存 404 URL

Nginx + Passenger:缓存 404 URL

语境

我有一个带有 nginx 服务器和 Passenger 的 Rails 应用程序。

应用程序根据请求 URL 动态生成页面:如果数据库中存在 URL,则应用程序呈现相应的页面。如果数据库中不存在 URL,则应用程序呈现 404 页面。

问题

许多爬虫程序正在尝试寻找漏洞并请求大量的 URL(.git、admin/config.php、wp-login.php 等...)

每个请求都会到达 Rails 应用程序,从而在数据库中产生点击。

解决方案

我正在寻找一种方法来做到这一点:

  1. 第一次请求“不存在”的 URL 时,它会通过 Rails 应用程序进行处理,并返回 404
  2. nginx 缓存并记住此 URL
  3. 下次请求相同的 URL 时,nginx 直接响应 404 状态,而不通过 Rails 应用

另外,当 Rails 应用程序重新启动时(通过 Passenger),应该清除该缓存。

特里斯

  • 我尝试添加fastcgi_cache_valid 404 10m;服务器块,但没有作用。
  • 也尝试过proxy_cache_valid 404 10m;

您可能已经猜到了,我是 nginx 新手。感谢您的帮助。

Nginx 配置

server {
  listen ...;

  server_name ...;

  root /path/to/rails/app;

  error_page 404 /404;
  error_page 500 502 503 504 /500;

  # First I tried this, no success so I removed it
  fastcgi_cache_valid 404 10m;

  # Then I tried this, no success so I removed it also
  proxy_cache_valid 404 10m;

  location / {
    gzip_static on;
    etag off;
    charset utf-8;
    add_header Cache-Control "max-age=0, private, must-revalidate";
    add_header Referrer-Policy strict-origin-when-cross-origin;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options deny;
    add_header X-XSS-Protection "1; mode=block";

    location = / {
      try_files /cached/index.html @rails;
    }

    location / {
      try_files /cached$uri.html /cached$uri $uri @rails;
    }
  }

  location @rails {
    passenger_enabled on;
    passenger_ruby /path/to/ruby;
    passenger_app_env production;
  }
}

答案1

我最熟悉反向代理环境中的缓存,因此我会采用这种方法。幸运的是,Nginx 能够相当轻松地为自己进行代理:

# define your cache
proxy_cache_path /path/to/cache levels=1:2 keys_zone=cacheName:[metaDataSize] max_size=[maxCacheSize] inactive=60m use_temp_path=off;

http {
  server {
    # Any TLS, caching, or gzipping on this virtual server
    listen ...;
    server_name [Actual Domain];

    location / {
      proxy_pass http://127.0.0.1:80;
      proxy_set_header Host [domain.passenger];

      # Activate and configure caching here
      proxy_cache cacheName;
      proxy_cache_valid 404 10m;
      ...any other proxy settings you want.

      # Forward original request info
      proxy_set_header X-Original-Host $http_host;
      proxy_set_header X-Original-Scheme $scheme;
      proxy_set_header X-Forwarded-For $remote_addr;

      # Gzip if you want
      gzip on;
      gzip_proxied any;

      ...etc
    }
  }

  server {
    # Any Rails/Passenger configuration on this virtual server
    listen 80;
    server_name [domain.passenger]; 

    # Don't log requests twice
    access_log off; 

    # Only allow local requests
    allow 127.0.0.1;
    deny all;

    location / {
      passenger_enabled on;
      passenger_ruby /path/to/ruby;
      passenger_app_env production;
    }
  }
}

清除缓存只需要运行rm -rf /path/to/cache/*,因此您可以按照自己最喜欢的方式将其编写到 Rails 重启过程中。

相关内容