使用 limit_except 拒绝除 GET、HEAD 和 POST 之外的所有内容

Has*_*aig 7 nginx

在典型的网站 nginx 配置(例如博客)中,如何使用 nginxlimit_except拒绝除典型的 http 方法(即GETPOST)之外的所有方法?想象一下,它驻留在server块中,并且块被配置为将所有流量重定向到httpswww

如何实现这一点的说明性示例会很棒。

我知道有些有争议的方法是:

add_header Allow "GET, POST, HEAD" always;
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
return 405;
}
Run Code Online (Sandbox Code Playgroud)

然而,鉴于if is evil,探索替代方法是有意义的。

anx*_*anx 8

除了将文档中已经提到的内容添加到您的服务器块之外,真的没有更多的事情要做:

server {
  server_name www.example.org;
  root /var/www/blog;

  ...
  # add this line (HEAD is implicit - it's a just special case of GET)
  limit_except GET POST { deny  all; }
  ...

}
Run Code Online (Sandbox Code Playgroud)

但是,这样做不一定是最好的主意:

在选择配置任一方法之前,请注意 405 和 403 之间的区别

  • 403 表示访问客户端未被授权执行该请求。
  • 405 是指服务器不允许在该 uri 上使用该方法。

使用两者的组合是有效的:您可能想告诉用户这里不允许 PROPFIND,但是当客户端尝试 PUT 时仍然告诉他,虽然这可能是一种可以理解的方法,但仍然禁止特定请求。

您可以配置limit_except的只是可能导致 403 的限制子集 - 我没有看到使用limit_except它来触发 405 的方法比立即使用更清楚if

这是一个(未经测试的)示例,它结合了 401、403 和 405 响应,并应阐明它们在典型配置中的优先级:

server {
    listen 192.0.2.1 ssl http2;
    server_name example.org;
    ssl_certificate_key /etc/ssl/private/example.org.key;

    # nobody shall be able to delete anything on this server
    if ($request_method = DELETE)
    {
        # the concerns about using if are not applicable
        # if the block only contains "return" or "rewrite .. last"
        return 405;
    }

    root /var/www/html;

    location /.well-known {
        alias /var/www/well-known;
    }
    location / {
        # logging in from specific IPs grants acces without HBA login
        satisfy any;
        allow 203.0.113.0/24;
        deny all;
        auth_basic_user_file /etc/nginx/users.passwd;
        auth_basic "join VPN or hit enter on this prompt:";

        limit_except GET {
            # block does not inherit the access limitations from above
            deny all;
        }

        location /uploading {
            limit_except GET POST {
               deny all;
            }
            proxy_pass http://unix:/run/backend.sock:/upload/;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

示例请求:

  1. DELETE requests 方法将返回 405(符合标准的配置应添加Allow标头,此处省略)
  2. 来自 203.0.113.0/24 的 GET 将始终基于 /var/www/html 回复
  3. 来自 203.0.113.0/24 的 PROPFIND 将返回 403
  4. 来自另一个 IP 缺少 HBA 标头的任何请求都将返回 401
  5. 任何在 /writable 之外具有有效 HBA 的 POST 请求都将返回 403
  6. 但在 /writable 内部,POST 请求将被代理到后端
  7. 具有有效 HBA 的 PROPFIND 请求将返回 403
  8. 除 DELETE 之外的任何方法都将根据 /var/www/well-known 进行回复

  • 不确定自您发布此答案以来是否发生了变化,但“limit_ except”的上下文被记录为“location”,并且如果将其放置在“server”块中,nginx 会拒绝它。 (2认同)