乐闻世界logo
搜索文章和话题

Nginx 如何实现访问控制?有哪些访问控制方法?

2月21日 16:57

Nginx 如何实现访问控制?有哪些访问控制方法?

Nginx 提供了多种访问控制方法,包括基于 IP 的访问控制、基本认证、访问令牌等,可以有效保护敏感资源。

IP 访问控制:

nginx
server { listen 80; server_name example.com; # IP 白名单 location /admin { allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; proxy_pass http://backend; } # IP 黑名单 location / { deny 192.168.1.100; deny 192.168.1.101; allow all; proxy_pass http://backend; } }

基本认证:

nginx
server { listen 80; server_name example.com; # 创建密码文件 # htpasswd -c /etc/nginx/.htpasswd username location /admin { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; } # 多用户认证 location /api { auth_basic "API Access"; auth_basic_user_file /etc/nginx/.htpasswd_api; proxy_pass http://api_backend; } }

访问令牌:

nginx
server { listen 80; server_name example.com; # 基于 Header 的访问控制 location /api { if ($http_authorization !~* "Bearer .*") { return 401; } proxy_pass http://api_backend; } # 基于查询参数的访问控制 location /protected { if ($arg_token != "secret_token") { return 403; } proxy_pass http://backend; } }

地理位置访问控制:

nginx
http { # 定义地理位置映射 geo $allowed_country { default no; CN yes; US yes; } server { listen 80; server_name example.com; location / { if ($allowed_country = no) { return 403; } proxy_pass http://backend; } } }

基于请求方法的访问控制:

nginx
server { listen 80; server_name example.com; # 限制允许的请求方法 if ($request_method !~ ^(GET|HEAD|POST)$ ) { return 405; } # 特定路径只允许特定方法 location /api { if ($request_method !~ ^(GET|POST)$ ) { return 405; } proxy_pass http://api_backend; } # 只读接口 location /api/read { if ($request_method !~ ^(GET|HEAD)$ ) { return 405; } proxy_pass http://api_backend; } }

基于请求头的访问控制:

nginx
server { listen 80; server_name example.com; # 检查特定的请求头 location /api { if ($http_x_api_key = "") { return 401; } proxy_pass http://api_backend; } # 检查 User-Agent location / { if ($http_user_agent ~* (bot|crawl|spider)) { return 403; } proxy_pass http://backend; } # 检查 Referer location /download { valid_referers none blocked example.com *.example.com; if ($invalid_referer) { return 403; } root /var/www/files; } }

复杂访问控制:

nginx
http { # 定义多个访问控制变量 geo $whitelist { default 0; 192.168.1.0/24 1; 10.0.0.0/8 1; } map $http_x_api_key $api_valid { default 0; "secret_key_123" 1; "secret_key_456" 1; } server { listen 80; server_name example.com; # 组合多个访问控制条件 location /admin { # IP 白名单 allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; # 基本认证 auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://backend; } # API 访问控制 location /api { # 检查 API Key if ($api_valid = 0) { return 401; } # 限制请求方法 if ($request_method !~ ^(GET|POST|PUT|DELETE)$ ) { return 405; } proxy_pass http://api_backend; } # 静态资源访问控制 location /protected { # IP 白名单或认证 satisfy any; allow 192.168.1.0/24; deny all; auth_basic "Protected Area"; auth_basic_user_file /etc/nginx/.htpasswd; root /var/www/protected; } } }

基于时间的访问控制:

nginx
http { # 定义时间段 map $time_iso8601 $business_hours { default 0; ~^(\d{4}-\d{2}-\d{2}T(09|1[0-9]|2[0-1])) 1; } server { listen 80; server_name example.com; # 只在工作时间允许访问 location /admin { if ($business_hours = 0) { return 403; } proxy_pass http://backend; } } }

防止目录遍历:

nginx
server { listen 80; server_name example.com; # 禁止访问父目录 location ~* /\.\. { deny all; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } # 禁止目录浏览 autoindex off; location / { proxy_pass http://backend; } }

限制文件类型访问:

nginx
server { listen 80; server_name example.com; # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; log_not_found off; } # 只允许特定文件类型 location /uploads { location ~* \.(jpg|jpeg|png|gif|pdf|doc|docx)$ { root /var/www/uploads; } location ~* \.(php|sh|exe|bat)$ { deny all; } } }

访问控制最佳实践:

  1. 最小权限原则:只授予必要的访问权限
  2. 多层防护:组合使用多种访问控制方法
  3. 定期审查:定期检查和更新访问控制规则
  4. 日志记录:记录所有访问控制事件
  5. 白名单优先:优先使用白名单而非黑名单
  6. 测试配置:在生产环境前充分测试访问控制规则
  7. 监控异常:监控异常访问行为
  8. 及时更新:及时更新密码和访问令牌

完整访问控制配置示例:

nginx
http { # IP 白名单 geo $whitelist { default 0; 192.168.1.0/24 1; 10.0.0.0/8 1; } # API Key 验证 map $http_x_api_key $api_valid { default 0; "secret_key_123" 1; "secret_key_456" 1; } # 工作时间 map $time_iso8601 $business_hours { default 0; ~^(\d{4}-\d{2}-\d{2}T(09|1[0-9]|2[0-1])) 1; } server { listen 80; server_name example.com; # 管理后台 location /admin { # IP 白名单 allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; # 基本认证 auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; # 工作时间限制 if ($business_hours = 0) { return 403; } proxy_pass http://backend; } # API 接口 location /api { # API Key 验证 if ($api_valid = 0) { return 401; } # 限制请求方法 if ($request_method !~ ^(GET|POST|PUT|DELETE)$ ) { return 405; } # 限流 limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/min; limit_req zone=api_limit burst=10 nodelay; proxy_pass http://api_backend; } # 受保护资源 location /protected { # IP 白名单或认证 satisfy any; allow 192.168.1.0/24; deny all; auth_basic "Protected Area"; auth_basic_user_file /etc/nginx/.htpasswd; root /var/www/protected; } # 禁止访问敏感文件 location ~* \.(htaccess|htpasswd|ini|log|sh|sql|bak|old|swp|tmp)$ { deny all; access_log off; log_not_found off; } # 禁止目录遍历 location ~* /\.\. { deny all; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } # 主站点 location / { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } }
标签:Nginx