概述
本章,您将学习到 Nginx 的访问控制功能。
在 Apache httpd 中,目录保护功能即对用户访问的资源设置相关的用户身份认证机制,以保护相关的资源。在 Nginx 当中也有类似功能,即访问控制功能,其由两种机制实现:
- 基于 IP 地址的访问控制
- 基于用户身份认证的访问控制
对同一资源而言,可配置任意一种机制或混用两种机制。
基于 IP 地址的访问控制
涉及到的指令有:
-
allow指令 - 允许特定 IP 地址或 IP 段访问资源,语法为allow address | CIDR | unix: | all;- address - 替换为具体的 IPv4 或 IPv6 地址
- CIDR - 替换为无类别域间路由表示法的网段,如 192.168.100.0/24 或 2001:db8::/32
- unix: :允许来自 Unix 域套接字的连接
- all - 指令参数中的关键字,允许所有地址访问资源
该指令可配置在 http、server、location、limit_except 上下文中,但是大部分情况下都配置在 location 上下文中。
-
deny指令 - 拒绝特定 IP 地址或 IP 段访问资源,语法为deny address | CIDR | unix: | all;该指令可配置在 http、server、location、limit_except 上下文中,但是大部分情况下都配置在 location 上下文中。
对于同一个资源而言,若 location 上下文中同时存在 allow 和 deny 指令,Nginx 的处理逻辑是:
- 自上而下顺序执行
- 首次匹配终止
- 若上下文中未包含任何
allow和deny指令,则表示允许所有地址进行访问,相当于隐式配置了allow all;
场景一:白名单模式(推荐)
只允许特定 IP 地址访问资源,但拒绝其他所有 IP 地址进行访问。要达到这种效果,必须以 deny all; 结尾
location /images/ {
allow 192.168.1.0/24; # 允许内网网段
allow 10.0.0.5; # 允许特定单个 IP 地址
deny all; # 拒绝其余所有 IP 地址
}
场景二:黑名单模式
先拒绝部分 IP 地址访问资源,再允许其他的 IP 地址访问资源。
location /download/ {
deny 192.168.1.100; # 拒绝特定单个 IP 地址
deny 198.51.100.0/24; # 拒绝某个网段
allow all; # 允许其余所有 IP 地址。可省略不写,但显式配置会更加清楚逻辑。
}
场景三:网站需维护,全站拒绝访问
假设网站需要进行后台维护:
...
http {
...
server {
listen 192.168.100.20:80;
server_name www.my-tests.com;
return 301 https://www.my-tests.com$request_uri;
}
server {
listen 192.168.100.20:443 ssl http2 backlog=8000 reuseport;
server_name www.my-tests.com;
...
deny all;
error_page 403 /403-maintenance.html;
location = /403-maintenance.html {
root /var/www/html/; # 确保该目录下有 403-maintenance.html 文件
internal; # 防止用户直接访问该文件
}
...
}
}
Nginx 处理请求的逻辑:
- 使用者在浏览器中输入 www.my-tests.com 时,浏览器自动补全 "http://" 协议部分
- 进入到 80 端口的 server 上下文,重定向到 443 端口
- 进入到 443 端口的 server 上下文,完成 SSL/TLS 握手,将协议变更为 " https:// ",进入到加密通道
- 被
deny all;拦截,拒绝访问 - 给使用者的浏览器返回 403 状态码和 403-maintenance.html 的页面
基于用户身份认证的访问控制
在使用这种机制之前,您需要使用相关命令创建一个包含用户名和密码的密码文件,推荐使用 Apache httpd 当中的 htpasswd 命令,该命令在前面的 Apache httpd 目录保护 文档中已经说明了。
# 创建第一名用户时需要使用 -c 选项
Shell > /usr/local/apache2/bin/htpasswd -B -c /usr/local/.htpasswd admin1
New password:
Re-type new password:
Adding password for user admin1
# 创建第二名用户时不需要使用 -c 选项
Shell > /usr/local/apache2/bin/htpasswd -B /usr/local/.htpasswd guest-user
New password:
Re-type new password:
Adding password for user guest-user
# 查看密码文件的内容
Shell > cat /usr/local/.htpasswd
admin1:$2y$05$Xv9PxteTR7DvrL5.DMsvkOoDPpfmZ5nKsq9ot6g2S6ApANb1xAFvS
guest-user:$2y$05$EZRwj/AlZUzdIktAO7FDheLkRufnMrzt.pnwUzlhHo4PkTwurkLmy
# 需要注意的是,htpasswd 不支持对密码文件已有用户进行密码更新。若要更新用户密码,您需要先使用 -D 选项删除密码文件的对于用户
## 删除 guset-user 用户
Shell > /usr/local/apache2/bin/htpasswd -D /usr/local/.htpasswd guest-user
Deleting password for user guest-user
# 使用添加新用户的方式更新密码
Shell > /usr/local/apache2/bin/htpasswd -B /usr/local/.htpasswd guest-user
/usr/local/apache2/bin/htpasswd -B /usr/local/.htpasswd guest-user
New password:
Re-type new password:
Adding password for user guest-user
# 再次查看密码文件的内容
Shell > cat /usr/local/.htpasswd
admin1:$2y$05$Xv9PxteTR7DvrL5.DMsvkOoDPpfmZ5nKsq9ot6g2S6ApANb1xAFvS
guest-user:$2y$05$IC3jrTEymWXibSW40F1DJe5V.SXSUcxosFlecsJQ6GOng/fHoNkaq
涉及到 Nginx 中的相关指令:
auth_basic指令 - 开启认证并设置提示信息,浏览器弹出的登录框中会显示此字符串。语法为auth_basic string | off;auth_basic_user_file- 指定密码文件所在的路径。语法为auth_basic_user_file file;
比如我将 nginx.conf 配置为如下的内容:
user nginx;
worker_processes 4;
error_log logs/error.log error;
pid logs/nginx.pid;
worker_rlimit_nofile 7400;
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
tcp_nopush on;
keepalive_timeout 30;
server_tokens off;
gzip on;
gzip_vary on;
gzip_buffers 32 4K;
gzip_comp_level 5;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml application/xhtml+xml image/svg+xml application/x-font-ttf application/x-font-opentype application/vnd.ms-fontobject font/woff;
gzip_min_length 256;
server {
listen 192.168.100.20:80 backlog=8000 reuseport;
server_name www.games.com;
access_log logs/games-access.log main;
charset utf-8;
location / {
root /html/games/;
index index.html index.htm;
location ~* \.(jpg|css|jpeg|xml|js|gif) {
expires 4h;
}
}
location /images/ {
alias /var/www/attachment/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
autoindex_format html;
auth_basic "Enter your username and password";
auth_basic_user_file /usr/local/.htpasswd;
}
}
}
启动 Nginx :
Shell > /usr/local/nginx/sbin/nginx -t && /usr/local/nginx/sbin/nginx
当浏览器访问 http://192.168.100.20:80/images/ 时,需要输入正确的用户名以及密码才能获取对应资源的目录列表。

混用两种机制
在实际情况下,您还可以混用这两种机制,以上面 location /images/ { ... } 为例:
location /images/ {
alias /var/www/attachment/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
autoindex_format html;
allow 192.168.100.0/24;
deny all;
auth_basic "Enter your username and password";
auth_basic_user_file /usr/local/.htpasswd;
}
仅允许 192.168.100.0/24 这个网段的 IP 地址能访问 /images/ 这个目录资源,且访问后需要正确输入对应的用户名和密码。
访问日志会记录下如下内容(main 日志格式):
192.168.100.10 - - [10/Sep/2026:20:34:21 +0800] "GET /images/ HTTP/1.1" 401 574 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36" "-"
192.168.100.10 - admin1 [10/Sep/2026:20:34:41 +0800] "GET /images/ HTTP/1.1" 200 172 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36" "-"
192.168.100.10 - - [10/Sep/2026:20:34:42 +0800] "GET /favicon.ico HTTP/1.1" 404 178 "http://192.168.100.20/images/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/153.0.0.0 Safari/537.36" "-"
还原
为方便后续的演示,先将环境还原。
# 停止 Nginx
Shell > /usr/local/nginx/sbin/nginx -s stop
# 还原 nginx.conf
Shell > vim /usr/local/nginx/conf/nginx.conf
...
http {
...
server {
...
location /images/ {
alias /var/www/attachment/;
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
autoindex_format html;
}
}
}
# 删除密码文件
Shell > rm -rf /usr/local/.htpasswd









