Nginx 提供了多种访问控制方法,以下是主要的技术方案:
一、基于 IP 地址的控制
1. allow/deny 指令
location /admin/ {
deny 192.168.1.100; # 拒绝单个IP
allow 10.0.0.0/24; # 允许整个网段
allow 172.16.0.0/16;
deny all; # 拒绝其他所有
}
# 顺序很重要,从上到下匹配
location /api/ {
allow 192.168.1.0/24;
deny all;
}
2. geo 模块(更灵活的IP控制)
geo $blacklist {
default 0;
10.0.0.0/8 1;
192.168.1.100 1;
172.16.0.0/12 1;
}
server {
location / {
if ($blacklist) {
return 403;
}
# 或者使用 map
}
}
二、基于密码的认证(Basic Auth)
1. 使用 htpasswd 创建密码文件
# 创建密码文件
sudo apt install apache2-utils
htpasswd -c /etc/nginx/.htpasswd username
# 或使用 openssl
openssl passwd -apr1
2. Nginx 配置
location /secure/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
# 可选:只为特定方法启用认证
satisfy any;
allow 192.168.1.0/24;
deny all;
auth_basic "Restricted";
}
三、基于请求特征的控制
1. 限制请求方法
location /api/ {
limit_except GET POST {
deny all;
}
}
2. User-Agent 过滤
# 使用 map 模块
map $http_user_agent $badagent {
default 0;
~*(curl|wget|scan|bot|spider) 1;
}
server {
if ($badagent) {
return 403;
}
}
3. Referer 检查
valid_referers none blocked server_names
*.example.com example.* ~\.google\.;
if ($invalid_referer) {
return 403;
}
四、访问频率限制
1. limit_req 模块
# 定义限制区域
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
server {
location /api/ {
limit_req zone=one burst=5 nodelay;
limit_req_status 429; # 自定义状态码
}
}
2. limit_conn 模块
# 限制并发连接数
limit_conn_zone $binary_remote_addr zone=addr:10m;
location /download/ {
limit_conn addr 1; # 每个IP最多1个连接
}
五、基于时间的控制
# 使用 map 和 变量
map $time_iso8601 $outside_office_hours {
default 0;
"~^(\d{4})-(\d{2})-(\d{2})T([01][0-9]|2[0-3])" 0;
"~^.*T(0[0-8]|2[0-3]).*" 1; # 0-8点允许访问
}
location /maintenance/ {
if ($outside_office_hours) {
return 503;
}
}
六、地理位置控制(需要 ngx_http_geoip2_module)
# 加载 GeoIP2 数据库
load_module modules/ngx_http_geoip2_module.so;
http {
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_country_code country iso_code;
}
map $geoip2_country_code $allowed_country {
default no;
CN yes;
US yes;
JP yes;
}
server {
if ($allowed_country = no) {
return 403;
}
}
}
七、综合示例
# 多层访问控制示例
http {
# 定义黑白名单
geo $blocked_ip {
default 0;
10.0.0.0/8 1;
192.168.100.0/24 1;
}
# 请求频率限制
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location /api/v1/ {
# 1. IP过滤
if ($blocked_ip) {
return 403;
}
# 2. 频率限制
limit_req zone=api burst=20 nodelay;
# 3. 方法限制
limit_except GET POST PUT DELETE {
deny all;
}
# 4. 认证
auth_basic "API Access";
auth_basic_user_file /etc/nginx/api_users;
# 继续处理请求...
}
# 管理后台
location /admin/ {
allow 192.168.1.0/24;
deny all;
# 需要HTTPS
if ($scheme != "https") {
return 301 https://$server_name$request_uri;
}
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/admin_users;
}
}
}
八、最佳实践建议
分层防御:结合多种方法,不要依赖单一机制
白名单优于黑名单:默认拒绝,明确允许
日志记录:记录被拒绝的访问尝试
定期审计:审查访问日志和规则
测试规则:新规则上线前充分测试
使用 include:将访问控制规则放在单独文件中
include /etc/nginx/access_rules/*.conf;
九、安全注意事项
- 避免在配置中暴露敏感信息
- 定期更新密码文件和证书
- 监控失败登录尝试
- 使用 fail2ban 等工具配合防护
- 考虑使用 WAF(Web应用防火墙)增强保护
选择哪种方法取决于具体的安全需求、性能考虑和运维复杂度。对于生产环境,建议采用多层次、深度防御的策略。