Nginx访问控制

06-27 1115阅读

 

目录

一、nginx 访问控制模块

二、基于IP的访问控制

配置语法

allow 指令

deny 指令

注意事项

示例: 

在 http 块中进行配置

在 server 块中进行配置

在 location 块中进行配置

limit_except 指令 

示例配置

示例 1:仅允许 GET 方法,其他方法需要 IP 控制

示例 2:允许 GET 和 POST 方法,其他方法需要 IP 控制 

局限性

解决方法

real_ip 模块的配置

示例配置

combined 日志格式

综合示例

三、基于用户的信任登录

auth_basic 和 auth_basic_user_file

1. auth_basic

2. auth_basic_user_file

配置示例

关键点总结

局限性

解决方法

JWT(JSON Web Token)认证

1. 安装 Nginx 的 nginx-http-auth-jwt 模块

2. 配置 Nginx

配置语法

示例配置

OAuth

1. 使用 OAuth 代理

2. 配置 Nginx

示例配置


一、nginx 访问控制模块

(1)基于IP的访问控制:http_access_module (2)基于用户的信任登录:http_auth_basic_module

二、基于IP的访问控制

配置语法

基于 IP 的访问控制是 Web 服务器安全管理中的一项重要功能,可以用来允许或拒绝来自特定 IP 地址或 IP 地址范围的访问。在 Nginx 中,这种控制通常是通过 allow 和 deny 指令来实现的,这些指令可以在 Nginx 的配置文件中的 http、server 或 location 上下文中使用。

 

allow 指令

语法:

allow address | CIDR | unix: | all;
  • address 可以是一个具体的 IP 地址,如 192.168.1.101。
  • CIDR 表示地址段,如 192.168.1.0/24。
  • unix: 表示允许所有通过 Unix 套接字的请求。
  • all 表示允许来自任何 IP 地址的请求。

    默认值:默认情况下,Nginx 没有设置任何 allow 指令。

    可配置区域:可以在 http、server、location、limit_except 中使用。

     

     

    deny 指令

    语法:

    deny address | CIDR | unix: | all;
    
    • 此语法与 allow 指令类似,用于拒绝特定的 IP 地址或地址段等的访问。

      默认值:默认情况下,Nginx 没有设置任何 deny 指令。

      可配置区域:可以在 http、server、location、limit_except 中使用。

       

      注意事项

      1. 指令顺序:Nginx 检查 allow 和 deny 指令的顺序很重要。它会按顺序检查每个指令直到找到匹配项为止。建议的做法是先放置 allow 指令,然后再放置 deny 指令。

      2. CIDR 表示法:可以使用 CIDR 表示法来指定一个 IP 地址段,例如 192.168.1.0/24,这表示允许或拒绝来自该子网的所有请求。

      3. 多个 allow 和 deny 指令:你可以使用多个 allow 或 deny 指令来定义复杂的访问控制策略。

      4. 指令的生效范围:这些指令可以在 http、server 或 location 三种不同的配置块中使用,也可以和limit_except 指令配合使用,意味着可以根据需要在全局、特定虚拟主机或特定路径上施加访问控制。

       

      示例: 

      在 http 块中进行配置

      这种配置会影响所有服务器块中的请求。

      http {
          # 允许特定的 IP 地址访问
          allow 192.168.1.101;
          allow 192.168.1.201;
          # 拒绝所有其他 IP 地址访问
          deny all;
          server {
              listen 80;
              server_name example.com;
              location / {
                  # 其他配置指令
                  ...
              }
          }
      }
      
      在 server 块中进行配置

      这种配置会影响特定的服务器块中的请求。

      server {
          listen 80;
          server_name example.com;
          # 允许特定的 IP 地址访问
          allow 192.168.1.101;
          allow 192.168.1.201;
          # 拒绝所有其他 IP 地址访问
          deny all;
          location / {
              # 其他配置指令
              ...
          }
      }
      
      在 location 块中进行配置

      这种配置会影响特定 URL 路径的请求。

      server {
          listen 80;
          server_name example.com;
          location /admin {
              # 允许特定 IP 地址访问
              allow 192.168.1.101;
              allow 192.168.1.201;
              # 拒绝所有其他 IP 地址访问
              deny all;
              # 处理请求的其他指令
              ...
          }
          location / {
              # 其他配置指令
              ...
          }
      }
      
      limit_except 指令 

      语法

      limit_except method ... {
          # 允许和拒绝指令
      }
      

      配置上下文

      • location
        示例配置

        以下示例展示了如何在 limit_except 块中使用 allow 和 deny 指令,基于 IP 地址限制对特定 HTTP 方法的访问:

        示例 1:仅允许 GET 方法,其他方法需要 IP 控制
        server {
            listen 80;
            server_name example.com;
            location /admin {
                # 允许所有 IP 地址进行 GET 请求
                limit_except GET {
                    # 允许特定 IP 地址进行非 GET 请求
                    allow 192.168.1.101;
                    allow 192.168.1.201;
                    # 拒绝所有其他 IP 地址进行非 GET 请求
                    deny all;
                }
                # 处理请求的其他指令
                ...
            }
            location / {
                # 其他配置指令
                ...
            }
        }
        

         在这个示例中,只有 IP 地址 192.168.1.101 和 192.168.1.201 可以进行非 GET 请求,所有其他 IP 地址只能进行 GET 请求。

         

        示例 2:允许 GET 和 POST 方法,其他方法需要 IP 控制 
        server {
            listen 80;
            server_name example.com;
            location /secure {
                # 允许所有 IP 地址进行 GET 和 POST 请求
                limit_except GET POST {
                    # 允许特定 IP 地址进行非 GET 和 POST 请求
                    allow 192.168.1.101;
                    allow 192.168.1.201;
                    # 拒绝所有其他 IP 地址进行非 GET 和 POST 请求
                    deny all;
                }
                # 处理请求的其他指令
                ...
            }
            location / {
                # 其他配置指令
                ...
            }
        }
        
        在这个示例中,只有 IP 地址 192.168.1.101 和 192.168.1.201 可以进行非 GET 和 POST 请求,所有其他 IP 地址只能进行 GET 和 POST 请求。

         

        关键点

        • limit_except 指令:用于限制除指定方法之外的所有方法。
        • allow 和 deny 指令:在 limit_except 块中使用,以基于 IP 地址控制对特定方法的访问。
        • 配置上下文:limit_except 指令只能在 location 块中使用。

          局限性

          remote_addr只能记录上一层与服务器直接建立连接的IP地址,若中间有代理,则记录的是代理的IP地址。

          http_x_forwarded_for可以记录每一层级的IP。

          Nginx访问控制

           

          解决方法

          (1)采用别的HTTP头信息控制访问,如HTTP_X_FORWARD_FOR(无法避免被改写)

          (2)结合geo模块

          (3)通过HTTP自定义变量传递

           

           

          在 Nginx 中,通过 remote_addr 和 http_x_forwarded_for 来处理客户端 IP 地址时,需要注意这些细节。

          • remote_addr:记录与 Nginx 服务器直接建立连接的上一层的 IP 地址。如果客户端通过代理访问 Nginx,remote_addr 会记录代理服务器的 IP 地址,而不是客户端的真实 IP 地址。
          • http_x_forwarded_for:记录每一级代理服务器的 IP 地址,通常由代理服务器添加到请求头中,包含客户端的真实 IP 地址和经过的每一个代理的 IP 地址。

            为了准确获取客户端的真实 IP 地址,可以使用 Nginx 的 real_ip 模块,该模块可以将 http_x_forwarded_for 头中的第一个 IP 地址(即客户端的真实 IP 地址)设置为 $remote_addr。

            real_ip 模块的配置

            语法

            • set_real_ip_from: 指定哪些 IP 地址(通常是代理服务器的 IP 地址)应该被信任。
            • real_ip_header: 指定用于替换 $remote_addr 的头字段,通常是 X-Forwarded-For。
              示例配置

              假设代理服务器的 IP 地址是 192.168.1.1 和 192.168.1.2,并且这些服务器会在请求头中添加 X-Forwarded-For 字段。

              http {
                  # 允许 Nginx 处理这些代理服务器发来的请求
                  set_real_ip_from 192.168.1.1;
                  set_real_ip_from 192.168.1.2;
                  # 指定 X-Forwarded-For 头字段用于获取真实的客户端 IP
                  real_ip_header X-Forwarded-For;
                  server {
                      listen 80;
                      server_name example.com;
                      location / {
                          # 记录日志时使用 $remote_addr 和 $http_x_forwarded_for
                          access_log /var/log/nginx/access.log combined;
                          # 其他配置指令
                          ...
                      }
                  }
              }
              
              combined 日志格式

              默认情况下,combined 日志格式已经包含 $remote_addr 和 $http_x_forwarded_for,这在标准的 Nginx 配置文件中是这样的:

              log_format combined '$remote_addr - $remote_user [$time_local] "$request" '
                                  '$status $body_bytes_sent "$http_referer" '
                                  '"$http_user_agent" "$http_x_forwarded_for"';
              

              在使用上述配置后,$remote_addr 将包含客户端的真实 IP 地址,而不再是代理服务器的 IP 地址。

              综合示例

              如下配置示例,展示了如何使用 real_ip 模块来获取客户端的真实 IP 地址,并在访问日志中记录这些信息。

               

              http {
                  # 允许 Nginx 处理这些代理服务器发来的请求
                  set_real_ip_from 192.168.1.1;
                  set_real_ip_from 192.168.1.2;
                  # 指定 X-Forwarded-For 头字段用于获取真实的客户端 IP
                  real_ip_header X-Forwarded-For;
                  # 定义日志格式
                  log_format combined '$remote_addr - $remote_user [$time_local] "$request" '
                                      '$status $body_bytes_sent "$http_referer" '
                                      '"$http_user_agent" "$http_x_forwarded_for"';
                  server {
                      listen 80;
                      server_name example.com;
                      location / {
                          # 记录访问日志
                          access_log /var/log/nginx/access.log combined;
                          # 其他配置指令
                          ...
                      }
                  }
              }
              

               通过以上配置,可以确保 Nginx 记录的 $remote_addr 是客户端的真实 IP 地址,即使请求通过多个代理服务器。

               

              三、基于用户的信任登录

              auth_basic 和 auth_basic_user_file

              auth_basic 和 auth_basic_user_file 是 Nginx 提供的两个指令,用于实现基本的 HTTP 认证。这一认证机制允许网站管理员设置一个简单的安全层,要求用户在访问特定资源之前输入用户名和密码。

              1. auth_basic

              auth_basic 指令用来开启或关闭基本的 HTTP 认证,并定义用于认证请求的提示信息(例如:“请输入用户名和密码”)。

              语法:

              auth_basic string | off;
              • string 指的是在登录提示框中显示的消息文字。当用户尝试访问受保护的内容时,这个字符串会显示在登录窗口上,通常是用来提示用户该区域需要认证。
              • off 用于关闭认证。

                默认值:auth_basic off;

                上下文:可以在 http、server、location、limit_except 中使用。

                 

                2. auth_basic_user_file

                auth_basic_user_file 指令指定一个文件位置,该文件包含认证所需的用户名和密码。密码文件需要使用 htpasswd 工具(通常随 Apache HTTP 服务器或 Nginx 附带)来创建。

                语法:

                auth_basic_user_file file;

                file 是存储用户名和加密密码信息的文件路径。

                默认值:默认不设置。

                上下文:可以在 http、server、location、limit_except 中使用。

                 

                配置示例

                下面的例子展示了如何为位于 /secure/ 路径的内容设置基本 HTTP 认证:

                 

                location /secure/ {
                    auth_basic "Restricted Content";
                    auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
                }

                在这个示例中,任何尝试访问 /secure/ 路径下内容的用户都将看到一个登录提示,提示信息为 “Restricted Content”。他们必须输入有效的用户名和密码,这些凭据会与 /etc/nginx/conf.d/.htpasswd 文件中存储的凭据进行比对。只有成功匹配的用户才能访问该路径下的内容。

                创建密码文件

                #htpasswd 是开源 http 服务器 apache httpd 的一个命令工具,用于生成 http 基本认证的密码文件 
                yum install -y httpd-tools 

                可以使用 htpasswd 命令来创建或更新密码文件。例如,要为用户 user1 添加或更新密码,可以使用以下命令:

                htpasswd -c /etc/nginx/conf.d/.htpasswd user1

                请注意,-c 选项是用于创建新文件。如果文件已经存在,并且你只想添加新用户或更新现有用户的密码,不要使用 -c 选项。

                 

                在 http 块中进行配置 

                这将影响所有虚拟主机和所有位置

                http {
                    auth_basic "Restricted Area";
                    auth_basic_user_file /etc/nginx/.htpasswd;
                    server {
                        listen 80;
                        server_name example.com;
                        location / {
                            # 其他配置指令
                            ...
                        }
                    }
                }
                

                在 server 块中进行配置 

                这将影响特定的虚拟主机。

                server {
                    listen 80;
                    server_name example.com;
                    auth_basic "Restricted Area";
                    auth_basic_user_file /etc/nginx/.htpasswd;
                    location / {
                        # 其他配置指令
                        ...
                    }
                }
                

                在 location 块中进行配置

                这将影响特定的 URL 路径。 

                server {
                    listen 80;
                    server_name example.com;
                    location /admin {
                        auth_basic "Restricted Area";
                        auth_basic_user_file /etc/nginx/.htpasswd;
                        # 其他配置指令
                        ...
                    }
                    location / {
                        # 其他配置指令
                        ...
                    }
                }
                

                 

                在 limit_except 块中进行配置

                这将影响除指定方法之外的所有方法。

                 

                server {
                    listen 80;
                    server_name example.com;
                    location /admin {
                        limit_except GET {
                            auth_basic "Restricted Area";
                            auth_basic_user_file /etc/nginx/.htpasswd;
                        }
                        # 其他配置指令
                        ...
                    }
                    location / {
                        # 其他配置指令
                        ...
                    }
                }
                
                关键点总结
                • auth_basic:启用或禁用基本身份验证,接受一个字符串参数作为提示信息或者 off。
                • auth_basic_user_file:指定包含用户名和密码的文件。
                • 配置上下文:这两个指令可以在 http、server、location 和 limit_except 块中使用。

                  通过以上配置示例,可以在不同的级别和上下文中灵活地启用基本身份验证,保护 Nginx 服务器上的资源。

                   

                  局限性

                  (1)用户信息依赖文件方式

                  (2)操作管理机械,效率低下

                  解决方法

                  (1)Nginx结合LUA实现高效验证

                  (2)Nginx和LDAP打通,利用nginx-auth-ldap模块

                  (3)Nginx只做中间代理,具体认证交给应用。

                   

                   

                  JWT(JSON Web Token)认证

                  JWT 是一种更现代的认证方法,可以更灵活地控制用户的访问权限。这里假设你已经有一个生成和验证 JWT 的服务。

                  1. 安装 Nginx 的 nginx-http-auth-jwt 模块

                  首先需要一个支持 JWT 认证的 Nginx 模块。可以使用 nginx-http-auth-jwt 模块。

                  2. 配置 Nginx

                  在 Nginx 配置文件中使用 auth_jwt 和 auth_jwt_key_file 指令来启用 JWT 认证。

                  配置语法
                  auth_jwt "string";
                  auth_jwt_key_file file;
                  auth_jwt_alg HS256 | HS512 | RS256;
                  
                  示例配置
                  http {
                      server {
                          listen 80;
                          server_name example.com;
                          location / {
                              # 启用 JWT 认证
                              auth_jwt "Restricted Area";
                              auth_jwt_key_file /etc/nginx/jwt_key.pub;
                              auth_jwt_alg RS256;
                              # 其他配置指令
                              ...
                          }
                      }
                  }
                  

                  在这个示例中,访问 example.com 时,Nginx 会检查请求头中的 JWT,并根据配置验证其有效性。

                  OAuth

                  OAuth 是一种开放标准的授权协议,允许第三方应用在不暴露用户凭据的情况下获取用户的授权。

                  1. 使用 OAuth 代理

                  通常,是使用一个 OAuth 代理(如 oauth2_proxy)与 Nginx 集成。

                  2. 配置 Nginx

                  在 Nginx 配置文件中使用反向代理指令将请求转发给 OAuth 代理。

                  示例配置
                  server {
                      listen 80;
                      server_name example.com;
                      location /oauth2/ {
                          proxy_pass http://127.0.0.1:4180;
                          proxy_set_header Host $host;
                          proxy_set_header X-Real-IP $remote_addr;
                          proxy_set_header X-Scheme $scheme;
                          proxy_connect_timeout 1;
                          proxy_send_timeout 30;
                          proxy_read_timeout 30;
                      }
                      location / {
                          auth_request /oauth2/auth;
                          error_page 401 = /oauth2/sign_in;
                          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;
                          proxy_set_header X-Scheme $scheme;
                      }
                  }
                  

                   在这个示例中,/oauth2/ 路径处理 OAuth 代理请求,主路径 / 受 OAuth 认证保护。

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]