# 访问控制
# 关于拒绝访问
# allow 、deny
:允许、禁止某些 IP 地址的访问。
- 可用范围:http、server、location、limit_except
- 例:
deny 192.168.1.1; # 禁止一个 IP allow 192.168.1.0/24; # 允许一个网段 deny all; # 禁止所有 IP allow all;
- 收到客户端的 HTTP 请求时,Nginx 会从上到下检查访问规则,采用第一条与客户端 IP 匹配的规则。
- 如果客户端被禁止访问,则返回响应报文:
403 Forbidden
# auth_basic
:用于启用 HTTP Basic Auth 。
- 可用范围:http、server、location
- 例:
auth_basic ""; # 设置 realm 。默认为 off ,禁用认证 auth_basic_user_file /etc/nginx/passwd; # 使用哪个密码文件
- 密码文件用于保存一组用户名、哈希密码,可通过 htpasswd 命令生成。
# auth_delay
:当客户端认证失败时,延迟一段时间再作出响应。
- 可用范围:http、server、location
- 默认值:
auth_delay 0s;
- 可以与 auth_basic 等认证措施搭配使用,避免暴力破解,不过客户端依然会保持 TCP 连接,占用资源。
# limit_except
:只允许接收指定的 HTTP 请求方法,对其它方法做出限制(通过 deny 限制)。
- 可用范围:location
- 例:
location / { limit_except GET POST { deny all; } }
- 允许 GET 方法时也会允许 HEAD 方法。
# satisfy
:如果 ngx_http_access_module、ngx_http_auth_basic_module、ngx_http_auth_request_module、ngx_http_auth_jwt_module 模块都允许访问(或任一允许),则最终允许访问。
- 可用范围:http、server、location
- 语法:
satisfy all | any;
- 默认值:
satisfy all;
# 关于限流
# limit_rate
:用于限制响应报文的传输速率,单位为 Bytes/s 。
- 可用范围:http、server、location
- 例:
location /www/ { limit_rate 10k; }
- 默认值为 0 ,表示不限制。
# limit_req
:用于限制每个客户端 IP 在一段时间内的请求数。
- 可用范围:http、server、location
- 例:
http { # 创建一个 zone ,以 binary_remote_addr 作为限流的 key # zone :创建一个指定大小的共享内存区域,用于记录 key 信息 # rate :限制速率。例如 10r/s 表示每秒 10 个请求,10r/m 表示每分钟 10 个请求 limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s; # 创建一个 zone ,以 server_name 作为限流的 key limit_req_zone $server_name zone=perserver:10m rate=100r/s; server { location / { proxy_pass http://10.0.0.1; limit_req zone=perip; # 采用 zone ,限制每个 IP 地址的请求数 limit_req zone=perserver; # burst 队列的长度默认为 0 ,启用它有利于处理客户端的突发大量请求 # limit_req zone=perip burst=20 nodelay; # limit_req_status 503; # limit_req_log_level error; } } }
- rate 不支持小数,且实际工作时会转换成每 100ms 的平均阈值。例如:
- 如果配置 rate=10r/m ,则实际限制为每 6s 最多 1 个请求。
- 如果再配置
burst=10 nodelay
,则允许 6s 内完成 11 个请求,然后每等待 6s 还可完成一个新请求。
- 如果再配置
- 如果配置 rate=1r/m ,则实际限制为每 1m 最多 1 个请求。
- 如果配置 rate=10r/s ,则实际限制为每 100ms 最多 1 个请求。
- 如果配置 rate=10r/m ,则实际限制为每 6s 最多 1 个请求。
- limit_req 采用漏斗算法(leaky bucket):
- 每 100ms 为一个处理周期。如果当前周期内,收到的请求数超过 rate 限制,则将请求放入称为 burst 的 FIFO 队列中。
- 每隔一个周期,从队列中取出请求,正常处理。
- 如果队列溢出,则拒绝新请求:返回 limit_req_status 状态码,并记录报错日志:
limiting requests, excess 0.340 by zone "perip"
,其中 excess = 根据当前请求估测的每毫秒请求数 - 平均每毫秒允许的 rate 。
- 启用 nodelay 策略时,会将超过 rate 限制的请求立即处理,同时将 burst 队列中相应数量的槽位标记为已占用。每隔一个周期,尝试释放一次槽位。
- 每 100ms 为一个处理周期。如果当前周期内,收到的请求数超过 rate 限制,则将请求放入称为 burst 的 FIFO 队列中。
- 以 binary_remote_addr 作为限流的 key 时,每个 key 需要 128bytes 来存储状态信息,因此 10MB 内存可以记录 8W 个 key 。
- 每次记录一个新 key 时,会尝试删除两个最近 60s 未使用的 key 。
- 如果 zone 内存耗尽,也会拒绝新请求。
- rate 不支持小数,且实际工作时会转换成每 100ms 的平均阈值。例如:
# limit_conn
:用于限制每个客户端 IP 同时进行的并发连接数。
- 可用范围:http、server、location
http { limit_conn_zone $binary_remote_addr zone=perip:10m; limit_conn_zone $server_name zone=perserver:10m; server { location / { proxy_pass http://10.0.0.1; limit_conn perip 10; # 采用 zone ,限制每个 IP 地址的并发连接数 limit_conn perserver 100; # limit_conn_status 503; # limit_conn_log_level error; } } }
- 当 Nginx 读取完请求的 Headers 之后,才会将该请求计入并发连接数。
- 以 binary_remote_addr 作为限流的 key 时,每个 key 需要 64bytes 来存储状态信息,因此 10MB 内存可以记录 16W 个 key 。