Nginx功能篇11—访问控制

概述

本章,您将学习到 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 上下文中同时存在 allowdeny 指令,Nginx 的处理逻辑是:

  • 自上而下顺序执行
  • 首次匹配终止
  • 若上下文中未包含任何 allowdeny 指令,则表示允许所有地址进行访问,相当于隐式配置了 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/ 时,需要输入正确的用户名以及密码才能获取对应资源的目录列表。

file

混用两种机制

在实际情况下,您还可以混用这两种机制,以上面 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
Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇