• 07 . Nginx常用模块及案例


    访问控制

    用户访问控制

    ngx_http_auth_basic_module

    有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们希望的是某些特定的客户端可以访问。那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一把锁,以拒绝那些不速之客。我们在服务课程中学习过apache的访问控制,对于Nginx来说同样可以实现,并且整个过程和Apache 非常的相似。

    #1.建立口令文件
    htpasswd -c /etc/nginx/passwd.db user1
    New password:
    Re-type new password:
    Adding password for user user1
    #2.实现认证
    vim default.conf
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            auth_basic "hello";                                # 这一行是你登录窗口写的提示文字
            auth_basic_user_file /etc/nginx/passwd.db;         # 密码存放的目录
        }
        
    # htpasswd -c选项只有第一次没有密码文件的时候需要添加,第二再添加账户的时候,不需要跟-c
    systemctl reload nginx
    
    # 用户认证局限性
    # 1. 用户信息依赖文件方式
    # 2. 用户管理文件过多,无法联动
    # 3. 操作管理机械,效率低下
    
    # 解决办法
    # 1. Nginx结合LUA实现高效验证
    # 2. Nginx结合LDAP利用nginx-auth-ldap模块
    

    访问测试
    重新加载配置文件后如果用elinks,curl访问会报错401,需要授权,需要用浏览器访问.

    主机访问控制

    ngx_http_access_module

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            # auth_basic "hello";
            # auth_basic_user_file /etc/nginx/passwd.db;
            allow 39.108.140.0;  #只允许此IP访问
            deny all;	     	 #拒绝所有
        }
    elinks --dump 49.233.69.195
                                     403 Forbidden
    

    状态访问

    ngx_http_stub_status_module

    使用第三方的软件监控nginx时,需要保证其本身能显示状态信息,然后利用这些数据显示一些监控数据和生成图表,使用该模块需要在编译nginx时启用该模块.

    # 在server中加入以下几行
        location ~ /status {
            stub_status on;
            access_log off;            # 状态模块的访问不记录日志
            allow 39.108.140.0;        # 只允许管理员访问
            deny all;                 
        }
    curl 49.233.69.195/status
    Active connections: 1             # Nginx当前活跃连接数
    server accepts handled requests
    14 14 14      
    Reading: 0 Writing: 1 Waiting: 0
                
    #第一个14:	为一共处理的多少个连接请求
    #第二个14:	为创建多少次握手
    #第三个14:	为总处理了多少请求    
    
    # Active connections        对后端发起的当前活动连接数
    # server accepts handled requests:
    # server:    Nginx总共处理了14个连接, 表示Nginx处理接收握手总次数
    
    #    成功创建了14次握手,也就是成功的连接数connection     失败连接=(总连接数-成功连接数) (相等表示中间没有失败的)
    #    总共处理了14个请求数requests (server和client建立一条连接之后开始请求数据,每有一个请求此数字会+1)
    
    # request:                   http请求,GET/POST/DELETE/UPLOAD(指的是请求资源),默认情况下下一个请求需要一个连接,但是如果开启了长连接,那么一个连接可以对应多个请求.
    
    # Reading:                   nginx读取到客户端的Header信息数,请求头,Nginx读取数据
    
    # Waiting:                    
    # nginx返回给客户端的Header信息数,响应头,如果这个值飙升,说明后面的节点挂掉了,例如数据库等. Nginx写的情况
    
    
    # Waiting:                   开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx说已经处理完正在等候下一次请求指令的驻留连接.
                            # 处理完等待下次请求的数量, 通俗点就是即没有读也没有写,建立连接情况.
    #  一般监控都是通过此模块监控状态比如蓝鲸,zabbix;如果需要监控进程和端口需要
    

    网站过滤

    替换网站响应内容: ngx_http_sub_module

    server里面加入下面两行代码.
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            sub_filter nginx 'flying';        # 默认只替换第一个nginx为flying,如果有多的nginx是不会替换的.
        }
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            sub_filter nginx 'flying';
            sub_filter_once off;             # 替换全部nginx为flying
        }
    

    实用用法

    如果我们用模板生成网站的时候,因为疏漏或者别的原因造成代码不如意,但是此时因为文件数量巨大,不方便全部重新生成,那么这个时候我们就可以用此模块来暂时实现纠错,另一方面,我们也可以利用这个实现服务器端文字过滤的效果.

    Nginx流量控制(连接和请求)

    http协议的连接与请求

    HTTP是建立在TCP, 在完成HTTP请求需要先建立TCP三次握手(称为TCP连接),在连接的基础上再HTTP请求

    HTTP请求建立在一次TCP连接基础上,一次TCP请求至少产生一次HTTP请求

    连接频率限制限制模块

    ngx_http_limit_conn_module
    (nginx的连接频率限制模块可以根据定义的key来限制每个键值的连接数.)

    # Syntax: limit_req_zone key zone=name:size rate=rate;(设置速率每秒多少个请求)
    # Default: —
    # Context: http
    
    # Syntax: limit_req zone=name [burst=number] [nodelay];(burst可以设置前多少个请求不限制,也可以设置是否延迟访问)
    # Default: —
    # Context: http, server, location
    
    # Example:
    yum -y install httpd-tools
    
    vim /etc/nginx/nginx.conf
    http {
    limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
    
    vim /etc/nginx/conf.d/default.conf
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            limit_req zone=req_zone;
           #limit_req zone=req_zone burst=5;            #5个请求时不限制的,但有延迟
           #limit_req zone=req_zone burst=5 nodelay;    #无延迟,只要拿到令牌就可以处理
        }
    
    ab  -n 100 -c 10 http://39.108.140.0/
    Time taken for tests:   0.940 seconds                     # 请求花费的总时间
    Complete requests:      100
    Failed requests:        99                                # 请求了100,失败了99
       (Connect: 0, Receive: 0, Length: 99, Exceptions: 0)    
    Write errors:           0
    Non-2xx responses:      99                                # 非200请求99个
    

    连接限制没有请求限制有效?

    我们前面说过, 多个请求可以建立在一次的TCP连接之上, 那么我们对请求的精度限制,当然比对一个连接的限制会更加的有效。
    因为同一时刻只允许一个连接请求进入。
    但是同一时刻多个请求可以通过一个连接进入。
    所以请求限制才是比较优的解决方案。

    防盗链

    图片防盗链

    防止网站资源被盗用 ngx_http_referer_module

    # 盗链是本网站的url显示其他网站图片,而直接用它的URL是转发,宣传的也是人家的URL.
    # 主机proxy准备一张图片放到根目录
    mv 1.png  /usr/share/nginx/html/
    
    # 主机rearend修改index.html
    cat /usr/share/nginx/html/index.html
    <html>
    <head>
        <meta charset="utf-8">
        <title>hello everyone</title>
    </head>
    <body style="background-color:red;">
        <img src="http://39.108.140.0/1.png"/>
    </body>
    </html>
    

    此时用windows10谷歌浏览器访问rearend主机,但是日志在proxy主机上,消耗资源也是proxy主机

    tail -1 /var/log/nginx/access.log
    114.242.249.222 - - [03/Nov/2019:17:00:31 +0800] "GET /1.png HTTP/1.1" 304 0 "http://49.233.69.195/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36" "-"

    修改proxy主机配置文件

    vim /etc/nginx/conf.d/default.conf
        location ~ .(img|png|gif)$ {
            root /usr/share/nginx/html/images;
            index index.html;
        valid_referers none blocked *.youmen.cn server_names ~youmen  ~.google
    . ~baidu;
        if ($invalid_referer) {
            return 403;
        }
    }
    systemctl reload nginx
    

    此时再用浏览器访问rearend主机就会显示一张破碎的图片标志,图片资源也加载不出来

    如何区分哪些是不正常的用户?

    http referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上referer,告诉服务器我是从那个页面链接过来的,服务器借此可以获得一些信息用于处理,例如防止未经允许的网站盗链图片、文件等,因此Http Referer头信息是可以通过程序伪装生成的,所以通过Referer信息防盗链并非100%可靠,但是他能限制大部分盗链情况。

    Nginx下载站点

    Nginx默认不允许整个目录浏览下载

    如果需要开启,修改一下配置文件即可

    autoindex常用参数

    autoindex_exact_size off;
    # 默认为on, 显示出文件的确切大小,单位是bytes。
    # 修改为off,显示出文件的大概大小,单位是kB或者MB或者GB。
    autoindex_localtime on;
    # 默认为off,显示的文件时间为GMT时间。
    # 修改为on, 显示的文件时间为文件的服务器时间。
    charset utf-8,gbk;
    # 默认中文目录乱码,添加上解决乱码。
    
    开启全站目录浏览器功能(http下面添加如下内容)
    autoindex on;  # 开启目录文件列表
    autoindex_exact_size on;  # 显示出文件的确切大小,单位是bytes
    autoindex_localtime on;  # 显示的文件时间为文件的服务器时间
    charset utf-8,gbk,gb2312;  # 避免中文乱码
    
    add_header Content-Disposition attachment;  # 文件下载(可以不开启该功能)
    
    开启网站部分目录浏览器功能
    # 编辑nginx.conf,在Server{}模块或者localtion模块加入以下内容:
    autoindex on;  # 开启目录文件列表
    autoindex_exact_size on;  # 显示出文件的确切大小,单位是bytes
    autoindex_localtime on;  # 显示的文件时间为文件的服务器时间
    charset utf-8,gbk,gb2312;  # 避免中文乱码
    
  • 相关阅读:
    Spring AOP前置通知实例说明AOP相关概念
    什么是面向切面编程AOP
    关于IOC容器的一些个人理解
    在.Net Core WebAPI下给Swagger增加导出离线文档功能
    .Net Core ORM选择之路,哪个才适合你
    真香.小程序云开发(时光邮局小程序)
    Cordova的安装与配置
    JS三座大山再学习(三、异步和单线程)
    JS三座大山再学习(二、作用域和闭包)
    JS三座大山再学习(一、原型和原型链)
  • 原文地址:https://www.cnblogs.com/you-men/p/12827547.html
Copyright © 2020-2023  润新知