Nginx配置⽂件

  • Nginx主配置⽂件 /etc/nginx/nginx.conf 是⼀个纯⽂本类型的⽂件,整个配置⽂件是以区块的
    形式组织的。⼀般,每个区块以⼀对⼤括号 {} 来表示开始与结束。

    • Main位于nginx.conf配置⽂件的最⾼层
    • Main层下可以有Event、HTTP层
    • HTTP层下⾯有允许有多个Server层, ⽤于对不同的⽹站做不同的配置
    • Server层也允许有多个Location, ⽤于对不同的路径进⾏不同模块的配置
  • nginx默认配置语法
user  nginx;                   # 设置nginx服务的系统使⽤⽤户
worker_processes  auto;        # ⼯作进程,配置和CPU个数保持⼀致

error_log  /var/log/nginx/error.log notice;  # 错误⽇志,后⾯接⼊的是存放文件路径
pid        /var/run/nginx.pid;               # Nginx服务启动时的pid,,后⾯接⼊的是存放文件路径

events {
    worker_connections  1024;
}
# ⾮虚拟主机的配置或公共配置定义在http{}段内,    server{}段外
http {        
    # 必须使⽤虚拟机配置站点,    每个虚拟机使⽤⼀个server{}段
    server    {
        listen 80; # 监听端⼝,    默认80
        server_name        localhost;    # 提供服务的域名或主机名
        #控制⽹站访问路径
        location    /    {
            root            /usr/share/nginx/html;            # 存放⽹站路径
            index        index.html    index.htm;                # 默认访问⾸⻚⽂件
        }
                                
        # 指定错误代码,    统⼀定义错误⻚⾯,    错误代码重定向到新的Locaiton
        error_page            500 502 503 504        /50x.html;
        location    =    /50x.html    {
            root html;
        }
    }
    # 第⼆个虚拟主机配置
    server    {
    }
}

Nginx⽇志配置规范

  • 配置语法包括

    • access.log
    • error.log
  • Nginx默认日志格式设置

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

Nginx⽇志变量

参数说明
$remote_addr客户端地址
$remote_user客户端用户名称
$time_local访问时间和时区
$request请求的URI和HTTP协议
$http_host请求地址,即浏览器中你输入的地址(IP或域名)
$statusHTTP请求状态
$upstream_statusupstream状态
$body_bytes_sent发送给客户端文件内容大小
$http_refererurl跳转来源
$http_user_agent用户终端浏览器等信息
$ssl_protocolSSL协议版本
$ssl_cipher交换数据中的算法
$upstream_addr后台upstream的地址,即真正提供服务的主机地址
$request_time整个请求的总时间
$upstream_response_time请求过程中,upstream响应时间

Nginx状态监控

  • 开启Nginx监控模块 (--with-http_stub_status_module)
  • 具体配置如下

    location /mystatus {
      stub_status on;
      access_log off;
    }
  • 状态监控结果

    Active connections: 2 
    server accepts handled requests
     2 2 1 
    Reading: 0 Writing: 1 Waiting: 1 
  • 状态监控结果详细解读

    • Active connections: 2 当前nginx正处理的活动连接数
    • server accepts handled requests 3 3 10 总共处理了3次连接,成功创建了3次连接,共请求了10次。总连接数-成功连接数为失败连接数
    • Reading: o Writing: 1 Waiting: 1

      • reading为nginx读取到客户端的header信息数
      • Writing为nginx返回给客户端的Header信息数,Waiting开启 keep-alive的情况下,这个值等于active-(reading+writing),意思指nginx已经处理完正在等候下一次请求的驻留连接

Nginx下载站点

  • autoindex常⽤参数

    • autoindex_exact_size off;

      • 默认为on, 显示出⽂件的确切⼤⼩,单位是bytes。
      • 修改为off,显示出⽂件的⼤概⼤⼩,单位是kB或者MB或者GB。
    • autoindex_localtime on;

      • 默认为off,显示的⽂件时间为GMT时间。
      • 修改为on, 显示的⽂件时间为⽂件的服务器时间。
    • charset utf-8,gbk;

      • 默认中⽂⽬录乱码,添加上解决乱码
  • 配置⽬录浏览功能
location /www {
  #root /data;
  alias /data/www/;             # 指定目录 
  autoindex    on;             # 列出整个目录列表
  autoindex_localtime    on;     # 显示的文件时间为文件的服务器时间
  charset utf-8,gbk;        # 解决中文乱码
  autoindex_exact_size    off;    # 以kB或者MB或者GB单位显示出文件的大小,而不是字节
}

Nginx访问限制

  • nginx 文档地址
  • ngx_http_limit_req_module 模块文档地址
  • 配置
  •  http {
          #  http段配置请求限制, rate限制速率,限制⼀秒钟最多⼀个IP请求
          limit_req_zone    $binary_remote_addr    zone=req_zone:10m    rate=1r/s;
          server    {}
     }
    • key 定义用于限制请求的变量,在这个示例中使用的是NGINX的自带变量 $binary_remote_addr(客户端的ip地址)
    • zone 定义用于存储前面定义的key变量,如zone=mylimit:10m 就是一个名为mylimit的大小为10m的共享内存空间
    • rate 允放相同标识的客户端的访问频次, 在这个例子中:就是同一个ip地址在每秒内只能访问1次
  • 使用

    server {
         location / {
              # limit_req zone=req_zone;
              # limit_req zone=perip burst=2;
              limit_req zone=perip burst=2 nodelay;
         }   
    }   
    • burst 如上例子burst=2,允许2个突发,有大量请求时,超过频次限制的请求,会允许2个访问,注意:burst指定的请求数量,不会马上进行处理,而是按照rate指定的值,以固定的速率进行处理。
    • nodelay 只是对放到burst队列中的请求立即处理,但处理完成后队列并不立即清空,队列清空的速度仍然按原来的速度每秒一个清空,所以当再有请求过来时,并不会马上又有两个burst请求被处理。
  • 安装压力测试,以每秒处理1个请求的速率做限制

       limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
      # centos
      sudo yum install -y httpd-tools  
      # ubuntu 
      sudo apt-get install -y apache2-utils
  • 测试1

       location / {
           root   /usr/share/nginx/html;
           index  index.html index.htm;
           limit_req zone=req_zone;
       }
  • 测试1重启nginx后执行ab

     vagrant@swarm3:/etc/nginx$ ab -n 10 -c 10  http://192.168.56.3/ 
     Concurrency Level:      10
     Time taken for tests:   0.002 seconds
     Complete requests:      10
     Failed requests:        9
      (Connect: 0, Receive: 0, Length: 9, Exceptions: 0)
    • 只有一个成功,有9个请求失败,时长是0.002 seconds,同一个ip地址在每秒内只能访问1次
  • 测试2

       location / {
           root   /usr/share/nginx/html;
           index  index.html index.htm;
           limit_req zone=req_zone burst=2;
       }
  • 测试2重启nginx后执行ab

     vagrant@swarm3:/etc/nginx$ ab -n 10 -c 10  http://192.168.56.3/ 
     Concurrency Level:      10
     Time taken for tests:   2.001 seconds
     Complete requests:      10
     Failed requests:        7
        (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
    • 有7个请求失败,注意时间变成了2.001 seconds,burst=2允许2个突发, 有大量请求时,超过频次限制的请求,会允许2个访问,burst指定的请求数量, 不会马上进行处理, 而是按照rate指定的值,以固定的速率进行处理。
  • 测试3

       location / {
           root   /usr/share/nginx/html;
           index  index.html index.htm;
           limit_req zone=req_zone burst=2 nodelay;
       }
  • 测试3重启nginx后执行ab

     vagrant@swarm3:/etc/nginx$ ab -n 10 -c 10  http://192.168.56.3/ 
     Concurrency Level:      10
     Time taken for tests:   0.002 seconds
     Complete requests:      10
     Failed requests:        7
     (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
    • 有7个请求失败,注意时间:这次是0.002 seconds,burst的队列虽然可以处理用户的需求,但需要用户按照处理时间等待, 对用户不够友好, nodelay参数允许请求在排队的时候就立即被处理, 这里有一点要注意:因为nodelay允许立即处理,也就是有并发请求时,事实上已经超过了rate设置的处理速率了, 所以要根据机器的实际情况设置这个值

Nginx连接限制

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

  • 多个请求可以建⽴在⼀次的TCP连接之上, 那么我们对请求的精度限制,当然⽐对⼀个连接的限制会更加的有效。
  • 因为同⼀时刻只允许⼀个连接请求进⼊,但是同⼀时刻多个请求可以通过⼀个连接进⼊,所以请求限制才是⽐较优的解决⽅案。

Nginx访问控制

  • 文档地址

  • 基于IP的访问控制

    • 配置拒绝某⼀个IP, 其他全部允许

      location / {
           deny 192.168.56.1;
           allow all;
      }
    • 只允许某⼀个⽹段访问,其它全部拒绝

      location / {
            allow 192.168.56.0/24;
            deny all;
      }
    • 缺陷

      • 当真实客户端直接访问目标服务器被deny拒绝之后,真实客户端通过多层代理服务器访问目标服务器仍然是可以访问的。
    • 解决方法

      • 采用别的http头信息访问控制,如HTTP_X_FORWARDED_FOR。

        • 多层代理服务器以及目标服务开启http_x_forwarded_for,这个局限性很大,因为代理服务器可能不遵循开启http_x_forwarded_for,这是一个协议要求的,并不是所有的cdn和代理厂商它会按照要求来做,甚至x_forwarded_for存在被修改的可能,因为只是一个头信息,所以最终还是不真实。
        • http_x_forwarded_for 也是Nginx的http头变量的一个常用的变量,它和remote_addr是有区别的。不同的是,x_forwarded_for是http协议中规定头中要携带的,所以在客户端访问中间件,再访问服务端的时候,那么服务端通过Nginx会记录真实IP和中间件的IP。
        • 格式为http_x_forwarded_for = 客户端ip,第一台代理ip,第二台代理ip,第N台代理ip,所以http_x_forwarded_for是由一连串以逗号分隔的ip组成的。
        • 192.168.56.1(客户端) -> 192.168.56.2(代理机) -> 192.168.56.3(代理机) -> 192.168.56.5(目标机器)

           # 192.168.56.2
           location ^~ /proxy1/ {
               proxy_set_header X-Real-IP $remote_addr;
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_set_header Host $http_host;
               proxy_set_header X-NginX-Proxy true;
               proxy_pass http://192.168.56.3:80;
               proxy_redirect off;
           }
           # 192.168.56.3
           location ^~ /proxy1/ {
               proxy_set_header X-Real-IP $remote_addr;
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_set_header Host $http_host;
               proxy_set_header X-NginX-Proxy true;
               proxy_pass http://192.168.56.5:80;
               proxy_redirect off;
           }
           # 192.168.56.5
           location / {
               root   /usr/share/nginx/html;
               index   index.php index.html index.htm;
           }
           location ~ \.php$ {
              root /usr/share/nginx/html;
              fastcgi_pass   127.0.0.1:9000;
              fastcgi_index  index.php;
              fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
              include        fastcgi_params;
           }
      • 结合geo模块 想了解的话可以移步到 使用Nginx+GeoIP获取IP信息
      • 通过HTTP自定义变量传递
  • 基于IP的访问控制(待完善)

    Nginx虚拟主机

Last modification:April 12, 2023
如果觉得我的文章对你有用,请随意赞赏