Nginx 核心知识 100 讲

发表于 2021-03-04 分类于 学习笔记极客时间
本文字数: 40k 阅读时长 ≈ 37 分钟

Nginx 核心知识 100 讲学习笔记

初识 nginx

  1. nginx 适用场景
    静态资源服务:通过本地文件系统提供服务。
    反向代理服务:nginx 的强大性能,缓存,负载均衡。
    API 服务:OpenResty
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图1

  2. Nginx 的优点

    • 高并发,高性能
    • 可扩展性好
    • 高可靠性
    • 热部署
    • BSD 许可证(开源免费)

Nginx 核心知识 100 讲 | 董的个人笔记 - 图2

  1. Nginx 的组成
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图3

  2. Nginx 的版本发布
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图4

  3. nginx 编译

    • vim 语法支持 cp -r contrib/vim/* ~/.vim/

Nginx 核心知识 100 讲 | 董的个人笔记 - 图5

  • 查看帮助文件 ``` [root@ecs nginx-1.18.0]# ./configure —help|more

…… 第一类

—prefix=PATH

第二类:使用哪些和不使用哪些模块

—with-http_ssl_module #默认是不编译进nginx的 —without-http_charset_module #默认是编译进nginx,加这个参数就是卸载这个模块

第三类:特殊优化参数 —with-cc=PATH set C compiler pathname —with-cpp=PATH set C preprocessor pathname —with-cc-opt=OPTIONS set additional C compiler options —with-ld-opt=OPTIONS set additional linker options —with-cpu-opt=CPU

  1. -
  2. 中间文件介绍
  3. <br />**生成中间文件在什么地方?**
  4. ```powershell
  5. [root@ecs nginx-1.18.0]# cd objs/
  6. [root@ecs objs]# ll
  7. total 5148
  8. -rw-r--r-- 1 root root 17457 Feb 16 09:53 autoconf.err
  9. -rw-r--r-- 1 root root 40144 Feb 16 09:53 Makefile
  10. -rwxr-xr-x 1 root root 5130480 Feb 16 09:55 nginx
  11. -rw-r--r-- 1 root root 5375 Feb 16 09:55 nginx.8
  12. -rw-r--r-- 1 root root 7037 Feb 16 09:53 ngx_auto_config.h
  13. -rw-r--r-- 1 root root 657 Feb 16 09:53 ngx_auto_headers.h
  14. -rw-r--r-- 1 root root 5856 Feb 16 09:53 ngx_modules.c #所有的模块都放在 ngx_modules.c
  15. -rw-r--r-- 1 root root 45232 Feb 16 09:55 ngx_modules.o
  16. drwxr-xr-x 9 root root 91 Feb 16 09:53 src


为什么要知道 nginx 编译中间文件是放在这里呢?
在进行 nginx 版本升级的时候不能执行 make instal 需要把中间文件拷贝到安装目录下
c 语言编辑生成的所有中间目录都会放在 src 目录中

  1. /[root@ecs objs]# cd src
  2. [root@ecs src]# ll
  3. total 8
  4. drwxr-xr-x 2 root root 4096 Feb 16 09:55 core
  5. drwxr-xr-x 3 root root 191 Feb 16 09:55 event
  6. drwxr-xr-x 4 root root 4096 Feb 16 09:55 http
  7. drwxr-xr-x 2 root root 6 Feb 16 09:53 mail
  8. drwxr-xr-x 2 root root 6 Feb 16 09:53 misc
  9. drwxr-xr-x 4 root root 31 Feb 16 09:53 os
  10. drwxr-xr-x 2 root root 6 Feb 16 09:53 stream


如果使用了动态模块、生成的 so 文件也会放在这个目录下

  • 编译安装
    1. ./configure --prefix=/usr/local/nginx
    2. make
    3. make install
  1. 编译安装nginx需要pcre包,未安装会有如下提示:
  2. ./configure: error: the HTTP rewrite module requires the PCRE library.
  3. You can either disable the module by using --without-http_rewrite_module
  4. option, or install the PCRE library into the system, or build the PCRE library
  5. statically from the source with nginx by using --with-pcre=<path> option.
  6. 需要安装pcredevel包,pcre-devel。使用yum安装即可:(以下命令还带有sslzlib等依赖的安装)
  7. yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel
  8. 再重新编译安装
  1. nginx 配置语法
    配置文件由指令与指令块构成
    每条指令以;分号结尾,指令与参数间以空格符号分隔
    指令块以{}大括号将多条指令组织在一起
    include 语句允许组合多个配置文件以提升可维护性
    使用 #符号添加注释,提高可读性
    使用 $ 符号使用变量
    部分指令的参数支持正则表达式
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图6

  2. nginx 的命令行
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图7

    • 重载配置文件
      1. [root@ecs sbin]# ./nginx
      2. [root@ecs sbin]# ps -ef|grep nginx
      3. root 254641 1 0 10:21 ? 00:00:00 nginx: master process ./nginx
      4. nobody 254642 254641 0 10:21 ? 00:00:00 nginx: worker process
      5. root 254644 221527 0 10:21 pts/0 00:00:00 grep --color=auto nginx
      6. [root@ecs sbin]# vim ../conf/nginx.conf
      7. [root@ecs sbin]# ./nginx -s reload
      8. [root@ecs sbin]# ps -ef|grep nginx
      9. root 254641 1 0 10:21 ? 00:00:00 nginx: master process ./nginx
      10. nobody 254682 254641 0 10:22 ? 00:00:00 nginx: worker process
      11. root 254694 221527 0 10:23 pts/0 00:00:00 grep --color=auto nginx
  • 热部署 ```powershell [root@ecs sbin]# pwd /usr/local/nginx/sbin [root@ecs sbin]# cp nginx nginx.old [root@ecs sbin]# cd /data/soft/nginx/nginx-1.18.0/objs/ [root@ecs objs]# ll total 5148 -rw-r—r— 1 root root 17457 Feb 16 09:53 autoconf.err -rw-r—r— 1 root root 40144 Feb 16 09:53 Makefile -rwxr-xr-x 1 root root 5130480 Feb 16 09:55 nginx -rw-r—r— 1 root root 5375 Feb 16 09:55 nginx.8 -rw-r—r— 1 root root 7037 Feb 16 09:53 ngx_auto_config.h -rw-r—r— 1 root root 657 Feb 16 09:53 ngx_auto_headers.h -rw-r—r— 1 root root 5856 Feb 16 09:53 ngx_modules.c -rw-r—r— 1 root root 45232 Feb 16 09:55 ngx_modules.o drwxr-xr-x 9 root root 91 Feb 16 09:53 src [root@ecs objs]# cp -r nginx /usr/local/nginx/sbin/ -f cp: overwrite ‘/usr/local/nginx/sbin/nginx’? y

    给master进程发送一个信号,用新的nginx启动

    [root@ecs objs]# kill -USR2 254641

    可以看到新旧进程都在运行

    新的master会生成新的work,老的master和work也在运行,他们会平滑的把所有的请求过度到新的二进制文件启的进程中

    老的master和work已经不再监听80和443端口 所以新的请求,新的连接会进入新的nginx

[root@ecs objs]# ps -ef|grep nginx root 254641 1 0 10:21 ? 00:00:00 nginx: master process ./nginx nobody 254682 254641 0 10:22 ? 00:00:00 nginx: worker process root 254778 254641 0 10:35 ? 00:00:00 nginx: master process ./nginx nobody 254779 254778 0 10:35 ? 00:00:00 nginx: worker process root 254789 221527 0 10:36 pts/0 00:00:00 grep —color=auto nginx

优雅的关闭所有work进程

[root@ecs objs]# kill -WINCH 254641 [root@ecs objs]# ps -ef|grep nginx root 254641 1 0 10:21 ? 00:00:00 nginx: master process ./nginx root 254778 254641 0 10:35 ? 00:00:00 nginx: master process ./nginx nobody 254779 254778 0 10:35 ? 00:00:00 nginx: worker process root 254800 221527 0 10:40 pts/0 00:00:00 grep —color=auto nginx

老的master进程还在运行、所有的请求已经转接到新的nginx上了 但是我们又可能会发生一些问题

新版本退回到老版本,所以我们还可以给老的master发送信号重新把老的work拉起来

老的master是不会自动退出 允许我们做版本回退

  1. -
  2. 切割日志
  3. ```shell
  4. [root@ecs logs]# mv access.log bak.log
  5. [root@ecs logs]# ll
  6. total 12
  7. -rw-r--r-- 1 nobody root 0 Feb 16 10:21 bak.log
  8. -rw-r--r-- 1 nobody root 438 Feb 16 10:49 error.log
  9. -rw-r--r-- 1 root root 7 Feb 16 10:35 nginx.pid
  10. -rw-r--r-- 1 root root 7 Feb 16 10:21 nginx.pid.oldbin
  11. # 重新启动之后会重新生成access.log
  12. [root@ecs logs]# ../sbin/nginx -s reopen
  13. [root@ecs logs]# ll
  14. total 12
  15. -rw-r--r-- 1 nobody root 0 Feb 16 10:50 access.log
  16. -rw-r--r-- 1 nobody root 0 Feb 16 10:21 bak.log
  17. -rw-r--r-- 1 nobody root 500 Feb 16 10:50 error.log
  18. -rw-r--r-- 1 root root 7 Feb 16 10:35 nginx.pid
  19. -rw-r--r-- 1 root root 7 Feb 16 10:21 nginx.pid.oldbin
  20. # 定时切割日志
  21. [root@ecs logs]# crontab -l
  22. 0 0 1 * * root /usr/local/nginx/logs/rotate.sh
  23. [root@ecs logs]# cat rotate.sh
  24. #!/bin/bash
  25. LOGS_PATH=/usr/local/nginx/logs/history
  26. CUR_LOGS_PATH=/usr/local/nginx/logs
  27. YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
  28. mv ${CUR_LOGS_PATH}/access.log ${LOGS_PATH}/access_${YESTERDAY}.log
  29. mv ${CUR_LOGS_PATH}/error.log ${LOGS_PATH}/error_${YESTERDAY}.log
  30. # 向nginx主进程发送USR1信号。USR1信号是重新打开日志文件
  31. kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid)
  1. 搭建静态资源

    1. [root@ecs nginx]# vi conf/nginx.conf
    2. server {
    3. listen 8080;
    4. server_name www.test.com;
    5. #charset koi8-r;
    6. access_log logs/test.access.log main;
    7. location / {
    8. alis dlib/;
    9. # 打开目录
    10. #autoindex on;
    11. # 限制访问速度
    12. #set $limit_rate 1k;
    13. #index index.html index.htm;
    14. }
    15. #error_page 404 /404.html;
    16. }


Nginx 核心知识 100 讲 | 董的个人笔记 - 图8
打开 gzip

  1. gzip on;
  2. gzip_min_length 1;
  3. gzip_comp_level 2;
  4. gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;


Nginx 核心知识 100 讲 | 董的个人笔记 - 图9

  1. 搭建具备缓存功能的反向代理服务 ```shell

    nginx.conf

    proxy_cache_path /tmp/nginxcache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;

upstream local { server 127.0.0.1:8080; } server { listen 80; server_name www.test.com;

  1. location / {
  2. proxy_set_header Host $host;
  3. proxy_set_header X-Real-IP $remote_addr;
  4. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  5. proxy_cache my_cache;
  6. proxy_cache_key $host$uri$is_args$args;
  7. proxy_cache_valid 200 304 302 1d;
  8. proxy_pass http://local;
  9. }
  10. #error_page 404 /404.html;

}

server { listen 127.0.0.1:8080;

  1. #server_name www.test.com;
  2. #charset koi8-r;
  3. access_log logs/test.access.log main;
  4. location / {
  5. alias dlib/;
  6. autoindex on;
  7. set $limit_rate 1k;
  8. index index.html index.htm;
  9. }
  10. #error_page 404 /404.html;

}

upstream local { server 127.0.0.1:8080; } server { listen 80; server_name www.test.com;

  1. location / {
  2. proxy_set_header Host $host;
  3. proxy_set_header X-Real-IP $remote_addr;
  4. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  5. proxy_cache my_cache;
  6. proxy_cache_key $host$uri$is_args$args;
  7. proxy_cache_valid 200 304 302 1d;
  8. proxy_pass http://local;
  9. }
  10. #error_page 404 /404.html;

}

  1. 10.
  2. GoAccess 实现可视化并实时监控 access 日志
  3. -
  4. 安装 GoAccess `https://www.goaccess.cc/?mod=download`
  5. <br />说明:
  6. <br />GoAccess 在使用源码安装时,依赖下列组件。
  7. <br />为方便最终日志统计时显示 IP 地理位置,需要安装依赖项 GeoIP-devel
  8. <br />执行命令:_yum install GeoIP-devel.x86_64_
  9. <br />安装 ncurses-devel 开发库:
  10. <br />执行命令:_yum install ncurses-devel_
  11. <br />安装 openssl-devel 开发库:
  12. <br />执行命令:_yum install openssl-devel_
  13. -
  14. 执行报错
  15. ```powershell
  16. [root@ecs logs]# goaccess test.access.log -o ../html/report.html --real-time-html --time-format='%H:%M:%S'--date-format='%d/%b/%Y' --log-format=COMBINE
  17. GoAccess - version 1.2 - Feb 16 2021 17:14:24
  18. Config file: /usr/local/etc/goaccess.conf
  19. Fatal error has occurred
  20. Error occured at: src/parser.c - parse_log - 2705
  21. No date format was found on your conf file.
  22. # 生成报告
  23. [root@ecs logs]# goaccess test.access.log -a -o ../html/report.html
  24. # 配置nginx,访问查看
  25. location /report.html {
  26. alias /usr/local/nginx/html/report.html;
  27. }


Nginx 核心知识 100 讲 | 董的个人笔记 - 图10

  1. 从网络协议来看 SSL 安全协议
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图11

    • TLS 安全密码套件解读

Nginx 核心知识 100 讲 | 董的个人笔记 - 图12

  1. 对称加密与非对称加密各自的应用场景

    • 对称加密

Nginx 核心知识 100 讲 | 董的个人笔记 - 图13

  • 非对称加密

Nginx 核心知识 100 讲 | 董的个人笔记 - 图14

  1. SSL 证书的公信力是如何保证的?

    • PKI 公钥基础设施

Nginx 核心知识 100 讲 | 董的个人笔记 - 图15

  • 证书类型

Nginx 核心知识 100 讲 | 董的个人笔记 - 图16

  1. SSL 协议握手时 Nginx 的性能瓶颈在哪里?
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图17

  2. 用免费 SSL 证书实现一个 HTTPS 站点
    安装
    yum install certbot python2-certbot-nginx -y
    配置
    certbot --nginx --nginx-server-root=/usr/local/nginx/conf/ -d www.test.com
    nginx 配置

    1. listen 443 ssl; # managed by Certbot
    2. ssl_certificate /etc/letsencrypt/live/pazzn.com/fullchain.pem; # managed by Certbot
    3. ssl_certificate_key /etc/letsencrypt/live/pazzn.com/privkey.pem; # managed by Certbot
    4. include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    5. ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  1. 基于 OpenResty 用 Lua 语言实现简单服务

    • 下载安装 openresty
      1. [root@ecs soft]# wget https://openresty.org/download/openresty-1.19.3.1.tar.gz
      2. [root@ecs openresty-1.19.3.1]# ./configure
  1. location /lua {
  2. default_type text/html;
  3. content_by_lua 'ngx.say("User-Agent: ", ngx.req.get_headers()["User-Agent"])';
  4. }

Nginx 架构基础 (一)

  1. Nginx 请求处理流程
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图18

  2. Nginx 进程结构
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图19

    • 进程说明

      • Master 进程
        1、是进行 work 进程的监控管理的
        2、看看 work 进程是否正常工作需不需要进行热部署、需不需要重新载入配置文件

      • Cache manager 缓存的管理
        1、缓存为反向代理后端发来的动态请求做缓存使用
        2、缓存在不光是在 work 进程间使用、还要被 Cache manager 和 Cache loader 使用

      • Cache loader 载入缓存

    • 实例演示

      1. [root@ecs conf]# ps -ef|grep nginx
      2. root 262788 1 0 18:09 ? 00:00:00 nginx: master process ../sbin/nginx
      3. root 262789 262788 0 18:09 ? 00:00:00 nginx: worker process
      4. root 262790 262788 0 18:09 ? 00:00:00 nginx: cache manager process
      5. root 274250 221527 0 19:54 pts/0 00:00:00 grep --color=auto nginx
      6. [root@ecs conf]# ../sbin/nginx -s reload
      7. [root@ecs conf]# ps -ef|grep nginx
      8. root 262788 1 0 18:09 ? 00:00:00 nginx: master process ../sbin/nginx
      9. root 274252 262788 0 19:54 ? 00:00:00 nginx: worker process
      10. root 274253 262788 0 19:54 ? 00:00:00 nginx: cache manager process
      11. root 274255 221527 0 19:54 pts/0 00:00:00 grep --color=auto nginx
      12. [root@ecs conf]# kill -SIGHUP 262788
      13. [root@ecs conf]# ps -ef|grep nginx
      14. root 262788 1 0 18:09 ? 00:00:00 nginx: master process ../sbin/nginx
      15. root 274267 262788 0 19:55 ? 00:00:00 nginx: worker process
      16. root 274268 262788 0 19:55 ? 00:00:00 nginx: cache manager process
      17. root 274270 221527 0 19:55 pts/0 00:00:00 grep --color=auto nginx
  1. 使用信号管理 Nginx 的父子进程
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图20
    CHLD:终止进程信号。
    TERM,INT: 立刻停止进程
    QUIT: 优雅停止进程
    HUP: 重载配置文件
    USR1: 重新打开日志文件
    USR2、WINCH: 需要通过命令行结合 kill 命令使用

  2. reload 重载配置文件真相
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图21
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图22

  3. 热升级的完整流程
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图23
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图24

Nginx 架构基础 (二)

  1. 网络收发与 Nginx 事件间的对应关系
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图25
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图26
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图27

  2. Nginx 网络事件实例演示
    抓包工具:https://www.wireshark.org/#download

    • TCP 层:本地打开了 54756,Nginx 打开的是 8080 端口 进程与进程通信
      Nginx 核心知识 100 讲 | 董的个人笔记 - 图28

    • IP 层:本机 IP 地址:192.168.1.196 nginx 服务器的 IP 地址:127.0.0.1
      Nginx 核心知识 100 讲 | 董的个人笔记 - 图29

    • 三次握手
      windows 先向 nginx 发送一个 SYN
      相反的 nginx 所在的 linux 也会向 windos 发送一个 SYN,这个时候 nginx 是没有感知到的、因为这是一个半打开的状态
      直到 widows 再向 nginx 所在的 linux 服务器发送一个 ACK 时,linux 操作系统才会通知 nginx 这时有一个读事件需要处理
      Nginx 核心知识 100 讲 | 董的个人笔记 - 图30

  3. epoll 的优劣及原理
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图31

详解 HTTP 模块

  1. 冲突的配置指令以谁为准?

    • 配置块的嵌套
      1. main
      2. http {
      3. upstream { }
      4. split_clients {…}
      5. map {…}
      6. geo {…}
      7. server {
      8. if () {…}
      9. location {
      10. limit_except {…}
      11. }
      12. location {
      13. location {
      14. }
      15. }
      16. }
      17. server {
      18. }
      19. }
  • 指令的 Context ```shell Syntax: log_format name [escape=default|json|none] string …; Default: log_format combined “…”; Context: http

Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]]; access_log off; Default: access_log logs/access.log combined; Context: http, server, location, if in location, limit_excep

  1. -
  2. 指令的合并
  3. <br />![](https://gitee.com/dong618/blog/raw/master/img/202101/20210219171227.png#alt=)
  4. -
  5. 存储值的指令集成规则:向上覆盖
  6. <br />子配置不存在时,直接使用父配置块;
  7. <br />子配置存在时,直接覆盖父配置块。
  8. ```powershell
  9. server {
  10. listen 8080;
  11. root /home/geek/nginx/html;
  12. access_log logs/geek.access.log main;
  13. location /test {
  14. root /home/geek/nginx/test;
  15. access_log logs/access.test.log main;
  16. }
  17. location /dlib {
  18. alias dlib/;
  19. }
  20. location / {
  21. }
  22. }
  • HTTP 模块合并配置的实现

    • 指令在哪个块下生效?11 个阶段
    • 指令允许出现在那些块下?

      1. { ngx_string("valid_referers"),
      2. NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
      3. ......
    • 在 server 块内生效、从 http 向 server 合并指令:
      char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

    • 配置缓存在内存
      char *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
      1. Listen 指令
        1. listen unix:/var/run/nginx.sock;
        2. listen 127.0.0.1:8000;
        3. listen 127.0.0.1;
        4. listen 8000;
        5. listen *:8000;
        6. listen localhost:8000 bind;
        7. listen [::]:8000 ipv6only=on;
        8. listen [::1];
  1. 处理 HTTP 请求头部的流程

    • 接收请求事件模块

Nginx 核心知识 100 讲 | 董的个人笔记 - 图32

  • 接收请求 HTTP 模块
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图33
  1. 如何找到处理请求的 server 指令块
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图34

    • server 匹配顺序
      1、精确匹配
      2、 在前的泛域名
      3、
      在后的泛域名
      4、按文件中的顺序匹配正则表达式域名
      5、default server
      第 1 个
      listen 指定 default
  2. 详解 HTTP 请求的 11 个阶段
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图35
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图36
    参考地址:https://www.cnblogs.com/luoahong/p/13542203.html
    11 个阶段的顺序处理
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图37 | 阶段 | 使用的模块 | 备注 | | | | | | —- | —- | —- | —- | —- | —- | —- | | POST_READ | realip | 刚读完 http 请求头、没有经过任何加工过、获取到一些原始的值 | | | | | | SERVER_REWRITE | rewrite | 它和下面 REWRITE 的只有一个模块 | | | | | | FIND_CONFIG | 这个只有 nginx 框架会做 | 所以没有任何的模块、就是在做 location 的一个匹配 | | | | | | REWRITE | rewrite | 一般第三方模块没有一个处理 REWRITE | | | | | | POST_REWRITE | | 刚刚 REWRITE 之后要做的一些事情 | | | | | | PREACCESS | limt_conn, limit_req | 在 access 之前要不要做一些工作、 限制速度、 限制连接数 | | | | | | ACCESS | auth_basic | access | auth_request | 确认访问权限的 能不能访问 | 根据访问的 ip | 根据第三方的服务 | | POST_ACCESS | | | | | | | | PRECONFTENT | try_files mirrors | 处理 CONTENT 之前 会把这个服务发送给第三方服务、一个请求产生多个请求值 | | | | | | CONTENT | index | autoindex | concat | 反向代理 | | | | LOG | access_log | 打印 access 日志的 | | | | |

  1. postread 阶段:获取真实客户端地址的 realip 模块 ```shell [root@ecs conf.d]# cat realip.conf server { server_name realip.test.com;

    error_log logs/myerror.log debug; set_real_ip_from 127.0.0.1;

    real_ip_header X-Real-IP;

    real_ip_recursive off;

    real_ip_recursive on;

    real_ip_header X-Forwarded-For;

    location /{

    1. return 200 "Client real ip: $remote_addr\n";

    } }

    测试

    [root@ecs conf.d]# curl -H ‘X-Forwarded-For: 1.1.1.1,127.0.0.1’ realip.test.com Client real ip: 127.0.0.1

开启 real_ip_recursive on;

[root@ecs conf.d]# curl -H ‘X-Forwarded-For: 1.1.1.1,127.0.0.1’ realip.test.com Client real ip: 1.1.1.1

  1. 7.
  2. rewrite 阶段的 rewrite 模块:return 指令
  3. <br />![](https://gitee.com/dong618/blog/raw/master/img/202101/20210220095723.png#alt=)
  4. ```shell
  5. [root@ecs conf.d]# cat return.conf
  6. server {
  7. server_name return.test.com;
  8. listen 8080;
  9. root html/;
  10. error_page 404 /403.html;
  11. #return 405;
  12. location /{
  13. #return 404 "find nothing!\n";
  14. }
  15. }
  16. [root@ecs conf.d]# curl return.test.com:8080/aaa.html
  17. <!DOCTYPE html>
  18. <html>
  19. <head>
  20. <title>Error</title>
  21. <style>
  22. body {
  23. width: 35em;
  24. margin: 0 auto;
  25. font-family: Tahoma, Verdana, Arial, sans-serif;
  26. }
  27. </style>
  28. </head>
  29. <body>
  30. <h1>403 forbidden.</h1>
  31. </body>
  32. </html>
  33. # 去掉 return 404 "find nothing!\n"; 注释
  34. [root@ecs conf.d]# curl return.test.com:8080/aaa.html
  35. find nothing!
  36. # 去掉 return 405注释
  37. # 说明 return 405是在SERVER_REWRITE 阶段,而return 404 "find nothing!\n"处于REWRITE,优先处理SERVER_REWRITE
  38. [root@ecs conf.d]# curl return.test.com:8080/aaa.html
  39. <html>
  40. <head><title>405 Not Allowed</title></head>
  41. <body>
  42. <center><h1>405 Not Allowed</h1></center>
  43. <hr><center>nginx/1.18.0</center>
  44. </body>
  45. </html>
  1. rewrite 阶段的 rewrite 模块:重写 URL
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图38 ```shell [root@ecs conf.d]# cat rewrite.conf server { server_name rewrite.test.com; rewrite_log on; error_log logs/rewrite_error.log notice;

    root html/; location /first {

    1. rewrite /first(.*) /second$1 last;
    2. return 200 'first!\n';

    }

    location /second {

    1. #rewrite /second(.*) /third$1 break;
    2. rewrite /second(.*) /third$1;
    3. return 200 'second!\n';

    }

    location /third {

    1. return 200 'third!\n';

    }

  1. location /redirect1 {
  2. rewrite /redirect1(.*) $1 permanent;
  3. }
  4. location /redirect2 {
  5. rewrite /redirect2(.*) $1 redirect;
  6. }
  7. location /redirect3 {
  8. rewrite /redirect3(.*) http://rewrite.test.com$1;
  9. }
  10. location /redirect4 {
  11. rewrite /redirect4(.*) http://rewrite.test.com$1 permanent;
  12. }

}

从/first 重定向到 /second rewrite后面没有break,依次向下执行

[root@ecs conf.d]# curl rewrite.test.com/first/3.txt second!

打开rewrite /second(.*) /third$1 break;

[root@ecs conf.d]# curl rewrite.test.com/first/3.txt test3

实际访问目录是

[root@ecs conf.d]# cat /usr/local/nginx/html/third/3.txt test3

[root@ecs conf.d]# curl rewrite.test.com/redirect1/ -I HTTP/1.1 301 Moved Permanently Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 03:06:51 GMT Content-Type: text/html Content-Length: 169 Location: http://rewrite.test.com/ Connection: keep-alive

[root@ecs conf.d]# curl rewrite.test.com/redirect2/ -I HTTP/1.1 302 Moved Temporarily Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 03:06:57 GMT Content-Type: text/html Content-Length: 145 Location: http://rewrite.test.com/ Connection: keep-alive

[root@ecs conf.d]# curl rewrite.test.com/redirect3/ -I HTTP/1.1 302 Moved Temporarily Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 03:07:25 GMT Content-Type: text/html Content-Length: 145 Connection: keep-alive Location: http://rewrite.test.com/

[root@ecs conf.d]# curl rewrite.test.com/redirect4/ -I HTTP/1.1 301 Moved Permanently Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 03:07:44 GMT Content-Type: text/html Content-Length: 169 Connection: keep-alive Location: http://rewrite.test.com/

通过打开的rewrite_log on; 查看日志

[root@ecs logs]# cat rewrite_error.log 2021/02/20 11:06:51 [notice] 295965#0: 12 “/redirect1(.)” matches “/redirect1/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect1/ HTTP/1.1”, host: “rewrite.test.com” 2021/02/20 11:06:51 [notice] 295965#0: 12 rewritten redirect: “/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect1/ HTTP/1.1”, host: “rewrite.test.com” 2021/02/20 11:06:57 [notice] 295965#0: 13 “/redirect2(.)” matches “/redirect2/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect2/ HTTP/1.1”, host: “rewrite.test.com” 2021/02/20 11:06:57 [notice] 295965#0: 13 rewritten redirect: “/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect2/ HTTP/1.1”, host: “rewrite.test.com” 2021/02/20 11:07:25 [notice] 295965#0: 14 “/redirect3(.)” matches “/redirect3/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect3/ HTTP/1.1”, host: “rewrite.test.com” 2021/02/20 11:07:25 [notice] 295965#0: 14 rewritten redirect: “http://rewrite.test.com/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect3/ HTTP/1.1”, host: “rewrite.test.com” 2021/02/20 11:07:44 [notice] 295965#0: 15 “/redirect4(.)” matches “/redirect4/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect4/ HTTP/1.1”, host: “rewrite.test.com” 2021/02/20 11:07:44 [notice] 295965#0: 15 rewritten redirect: “http://rewrite.test.com/“, client: 127.0.0.1, server: rewrite.test.com, request: “HEAD /redirect4/ HTTP/1.1”, host: “rewrite.test.com”

  1. 9.
  2. rewrite 阶段的 rewrite 模块:条件判断
  3. <br />![](https://gitee.com/dong618/blog/raw/master/img/202101/20210220111129.png#alt=)
  4. <br />![](https://gitee.com/dong618/blog/raw/master/img/202101/20210220111153.png#alt=)
  5. 10.
  6. find_config 阶段:找到处理请求的 location 指令块
  7. <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220111521.png#alt=)
  8. <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220111636.png#alt=)
  9. ```shell
  10. [root@ecs conf.d]# cat locations.conf
  11. server {
  12. server_name location.test.com;
  13. error_log logs/error.log debug;
  14. #root html/;
  15. default_type text/plain;
  16. merge_slashes off;
  17. location ~ /Test1/$ {
  18. return 200 'first regular expressions match!\n';
  19. }
  20. location ~* /Test1/(\w+)$ {
  21. return 200 'longest regular expressions match!\n';
  22. }
  23. location ^~ /Test1/ {
  24. return 200 'stop regular expressions match!\n';
  25. }
  26. location /Test1/Test2 {
  27. return 200 'longest prefix string match!\n';
  28. }
  29. location /Test1 {
  30. return 200 'prefix string match!\n';
  31. }
  32. location = /Test1 {
  33. return 200 'exact match!\n';
  34. }
  35. }
  36. [root@ecs conf.d]# curl location.test.com/Test1
  37. exact match!
  38. [root@ecs conf.d]# curl location.test.com/Test1/
  39. stop regular expressions match!
  40. [root@ecs conf.d]# curl location.test.com/Test1/Test2
  41. longest regular expressions match!
  42. [root@ecs conf.d]# curl location.test.com/Test1/Test2/
  43. longest prefix string match!
  1. preaccess 阶段:对连接做限制的 limit_conn 模块
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图39
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图40
    限制发生时的日志级别
    1. Syntax: limit_conn_log_level info | notice | warn | error;
    2. Default: limit_conn_log_level error;
    3. Context: http, server, location


限制发生时向客户端返回的错误码

  1. Syntax: limit_conn_status code;
  2. Default: limit_conn_status 503;
  3. Context: http, server, location


Nginx 核心知识 100 讲 | 董的个人笔记 - 图41

  1. [root@ecs conf.d]# cat limit_conn.conf
  2. limit_conn_zone $binary_remote_addr zone=addr:10m;
  3. limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m;
  4. server {
  5. server_name limit.test.com;
  6. root html/;
  7. error_log logs/myerror.log info;
  8. location /{
  9. limit_conn_status 500; #返回错误码500
  10. limit_conn_log_level warn;
  11. limit_rate 50; #限制每秒钟向用户返回50Byte
  12. limit_conn addr 1; #限制并发连接数1
  13. #limit_req zone=one burst=3 nodelay;
  14. #limit_req zone=one;
  15. }
  16. }
  17. # 打印错误日志
  18. 2021/02/20 13:40:08 [info] 296750#0: *45 client 127.0.0.1 closed keepalive connection
  19. 2021/02/20 13:40:13 [warn] 296750#0: *47 limiting connections by zone "addr", client: 127.0.0.1, server: limit.test.com, request: "GET / HTTP/1.1", host: "limit.test.com"
  20. 2021/02/20 13:40:17 [info] 296750#0: *46 client prematurely closed connection while sending response to client, client: 127.0.0.1, server: limit.test.com, request: "GET / HTTP/1.1", host: "limit.test.com"
  21. 2021/02/20 13:40:26 [warn] 296750#0: *49 limiting connections by zone "addr", client: 127.0.0.1, server: limit.test.com, request: "GET / HTTP/1.1", host: "limit.test.com"
  22. 2021/02/20 13:40:34 [info] 296750#0: *48 client 127.0.0.1 closed keepalive connection
  1. preaccess 阶段:对请求做限制的 limit_req 模块
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图42
    限制发生时的日志级别
    1. Syntax: limit_req_log_level info | notice | warn | error;
    2. Default: limit_req_log_level error;
    3. Context: http, server, location


限制发生时向客户端返回的错误码

  1. Syntax: limit_req_status code;
  2. Default: limit_req_status 503;
  3. Context: http, server, location
  1. [root@ecs conf.d]# cat limit_conn.conf
  2. limit_conn_zone $binary_remote_addr zone=addr:10m;
  3. limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m;
  4. server {
  5. server_name limit.test.com;
  6. root html/;
  7. error_log logs/myerror.log info;
  8. location /{
  9. limit_conn_status 500;
  10. limit_conn_log_level warn;
  11. #limit_rate 50;
  12. #limit_conn addr 1;
  13. #limit_req zone=one burst=3 nodelay;
  14. limit_req zone=one;
  15. }
  16. }
  17. [root@ecs conf.d]# ../../sbin/nginx -s reload
  18. #第一次访问正常
  19. [root@ecs conf.d]# curl limit.test.com
  20. <!DOCTYPE html>
  21. <html>
  22. <head>
  23. <title>Welcome to nginx!</title>
  24. <style>
  25. body {
  26. width: 35em;
  27. margin: 0 auto;
  28. font-family: Tahoma, Verdana, Arial, sans-serif;
  29. }
  30. </style>
  31. </head>
  32. <body>
  33. <h1>Welcome to nginx!</h1>
  34. <p>If you see this page, the nginx web server is successfully installed and
  35. working. Further configuration is required.</p>
  36. <p>For online documentation and support please refer to
  37. <a href="http://nginx.org/">nginx.org</a>.<br/>
  38. Commercial support is available at
  39. <a href="http://nginx.com/">nginx.com</a>.</p>
  40. <p><em>Thank you for using nginx.</em></p>
  41. </body>
  42. </html>
  43. #第二次返回503
  44. [root@ecs conf.d]# curl limit.test.com
  45. <html>
  46. <head><title>503 Service Temporarily Unavailable</title></head>
  47. <body>
  48. <center><h1>503 Service Temporarily Unavailable</h1></center>
  49. <hr><center>nginx/1.18.0</center>
  50. </body>
  51. </html>
  52. # 打开 limit_req zone=one burst=3 nodelay; 之后,访问3次正常,第四次返回503
  53. # 同时打开limit_conn 和 limit_req,返回503,limit_req访问在前。
  1. access 阶段:对 ip 做限制的 access 模块
    如何限制某些 IP 地址的访问权限。
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图43

  2. access 阶段:对用户名密码做限制的 auth_basic 模块
    auth_basic 模块指令:
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图44

    1. # 安装工具包
    2. [root@ecs ~]# yum install httpd-tools -y
    3. # 生成文件
    4. [root@ecs conf.d]# htpasswd -c auth.pass temp
    5. New password:
    6. Re-type new password:
    7. Adding password for user temp
  1. access 阶段:使用第三方做权限控制的 auth_request 模块
    重新编译安装 ```powershell [root@ecs nginx]# cd sbin/ [root@ecs sbin]# ll total 15724 -rwxr-xr-x 1 root root 5833272 Feb 20 09:43 nginx -rwxr-xr-x 1 root root 5130480 Feb 16 10:32 nginx.2.old -rwxr-xr-x 1 root root 5130480 Feb 16 10:26 nginx.old [root@ecs sbin]# mv nginx nginx.3.old

[root@ecs nginx-1.18.0]# ./configure —prefix=/usr/local/nginx —with-http_ssl_module —with-http_realip_module —with-http_auth_request_module [root@ecs nginx-1.18.0]# make #切勿执行make install

将objs下的nginx复制到安装目录

[root@ecs objs]# cp nginx /usr/local/nginx/sbin/

热部署

[root@ecs nginx-1.18.0]# kill -USR2 300175

  1. ```shell
  2. server {
  3. server_name access.test.com;
  4. error_log logs/error.log debug;
  5. #root html/;
  6. default_type text/plain;
  7. location /auth_basic {
  8. satisfy any;
  9. auth_basic "test auth_basic";
  10. auth_basic_user_file conf.d/auth.pass;
  11. deny all;
  12. }
  13. location / {
  14. auth_request /test_auth;
  15. }
  16. location = /test_auth {
  17. proxy_pass http://127.0.0.1:8090/auth_upstream;
  18. proxy_pass_request_body off;
  19. proxy_set_header Content-Length "";
  20. proxy_set_header X-Original-URI $request_uri;
  21. }
  22. }
  1. access 阶段的 satisfy 指令
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图45

    • 如果有 return 指令,access 阶段会生效吗?
      不会生效,因为 return 指令在 SERVER_REWRITE 和 REWRITE 阶段,领先于 access。

    • 多个 access 模块的顺序有影响吗?
      查看 ngx-modules.c
      &ngx_http_auth_request_module,
      &ngx_http_auth_basic_module
      &ngx_http_access_module
      有影响

    • 输对密码,下面可以访问到文件吗?可以

      1. location/{
      2. satisfy any;
      3. auth_basic "test auth basic"
      4. auth_basic_user_file examples/auth.pass;
      5. deny all:
      6. }
  • 如果把 deny all 提到 auth basic 之前呢?
    可以,和指令顺序无关,主要取决于模块顺序。

  • 如果改为 allow all, 有机会输入密码吗?
    没有,因为配置的 satisfy any; 只要有一个模块放行即可。而且 allow 属于 access, 先于 auth_basic 执行。

  1. precontent 阶段:按序访问资源的 try_files 模块
    Nginx 核心知识 100 讲 | 董的个人笔记 - 图46 ```powershell [root@ecs conf.d]# cat tryfiles.conf server { server_name tryfiles.test.com; error_log logs/myerror.log info; root html/; default_type text/plain;

    location /first {

    1. try_files /system/maintenance.html
    2. $uri $uri/index.html $uri.html
    3. @lasturl;

    }

    location @lasturl {

    1. return 200 'lasturl!\n';

    }

    location /second {

    1. try_files $uri $uri/index.html $uri.html =404;

    }

} [root@ecs conf.d]# curl tryfiles.test.com/first lasturl! [root@ecs conf.d]# curl tryfiles.test.com/second

404 Not Found


nginx/1.18.0
18. 实时拷贝流量:precontent 阶段的 mirror 模块 <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220145826.png#alt=)powershell # 本地服务 [root@ecs conf.d]# cat mirror.conf server { listen 10020; location / { return 200 ‘mirror response!’; } } #上游服务 [root@ecs conf]# vim mirror.conf server{ listen 8001; error_log Logs/error. log debug; location / { mirror /mirror; mirror request _body off; } location =/mirror { internal; proxy_pass http://127.0.0.1:10020$request_uri; proxy_pass_request_body off; proxy_set_header Content-Length “”; proxy_set_header X-Oriqinal-URI $request_uri; } } 19. content 阶段:详解 root 和 alias 指令 <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220151044.png#alt=)powershell [root@ecs conf.d]# cat static.conf server { server_name static.test.com; error_log logs/myerror.log info; location /root { root html; } location /alias { alias html; } location ~ /root/(\w+.txt) { root html/first/$1; } location ~ /alias/(\w+.txt) { alias html/first/$1; } location /RealPath/ { alias html/realpath/; return 200 ‘$request_filename:$document_root:$realpath_root\n’; } } [root@ecs conf.d]# curl static.test.com/root/

404 Not Found


nginx/1.18.0
# 日志信息 2021/02/20 15:13:46 [error] 300277#0: *5 “/usr/local/nginx/html/root/index.html” is not found (2: No such file or directory), client: 127.0.0.1, server: static.test.com, request: “GET /root/ HTTP/1.1”, host: “static.test.com” [root@ecs conf.d]# curl static.test.com/root/1.txt

404 Not Found


nginx/1.18.0

日志信息

2021/02/20 15:15:09 [error] 300277#0: *7 open() “/usr/local/nginx/html/first/1.txt/root/1.txt” failed (20: Not a directory), client: 127.0.0.1, server: static.test.com, request: “GET /root/1.txt HTTP/1.1”, host: “static.test.com”

[root@ecs conf.d]# curl static.test.com/alias/ <!DOCTYPE html>

Welcome to nginx!

[root@ecs conf.d]# curl static.test.com/alias/1.txt test1 20. static 模块提供的 3 个变量 <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220151852.png#alt=)powershell # 建立软连接 [root@ecs html]# ln -s first realpath [root@ecs html]# ll total 352 -rw-r—r— 1 root root 242 Feb 20 10:05 403.html -rw-r—r— 1 root root 494 Feb 16 09:55 50x.html drwxr-xr-x 2 root root 32 Feb 20 15:23 first -rw-r—r— 1 root root 612 Feb 16 09:55 index.html lrwxrwxrwx 1 root root 5 Feb 20 15:23 realpath -> first -rw-r—r— 1 root root 344328 Feb 16 17:55 report.html drwxr-xr-x 2 root root 19 Feb 20 10:59 second drwxr-xr-x 2 root root 19 Feb 20 10:59 third [root@ecs html]# pwd /usr/local/nginx/html location /RealPath/ { alias html/realpath/; return 200 ‘$request_filename:$document_root:$realpath_root\n’; } [root@ecs conf.d]# curl static.test.com/RealPath/1.txt /usr/local/nginx/html/realpath/1.txt:/usr/local/nginx/html/realpath/:/usr/local/nginx/html/first - 静态文件返回时的 content-type <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220152722.png#alt=) - 未找到文件时的错误日志 <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220152733.png#alt=) 21. static 模块对 url 不以斜杠结尾却访问目录的做法powershell [root@ecs conf.d]# cat dirredirect.conf server { server_name return.test.com dir.test.com; server_name_in_redirect off; listen 8088; port_in_redirect on; absolute_redirect off; root html/; } [root@ecs conf.d]# curl localhost:8088/first -I HTTP/1.1 301 Moved Permanently Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 07:31:28 GMT Content-Type: text/html Content-Length: 169 Connection: keep-alive Location: /first/ # 添加注释 absolute_redirect off [root@ecs conf.d]# curl localhost:8088/first -I HTTP/1.1 301 Moved Permanently Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 07:40:40 GMT Content-Type: text/html Content-Length: 169 Location: http://localhost:8088/first/ Connection: keep-alive [root@ecs conf.d]# curl -H ‘Host:aaa’ localhost:8088/first -I HTTP/1.1 301 Moved Permanently Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 07:41:24 GMT Content-Type: text/html Content-Length: 169 Location: http://aaa:8088/first/ Connection: keep-alive # 修改 server_name_in_redirect on 返回server_name中的域名 [root@ecs conf.d]# curl -H ‘Host:aaa’ localhost:8088/first -I HTTP/1.1 301 Moved Permanently Server: nginx/1.18.0 Date: Sat, 20 Feb 2021 07:42:15 GMT Content-Type: text/html Content-Length: 169 Location: http://return.test.com:8088/first/ Connection: keep-alive 22. index 和 autoindex 模块的用法 - 对访问 / 时的处理:content 阶段的 index 模块 <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220155144.png#alt=) - 随机 index.html 文件:content 阶段的 autoindex 模块 <br /> - 显示目录内容:content 阶段的 autoindex 模块 <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220155334.png#alt=) - autoindex 模块的指令 <br />![](https://gitee.com/dong618/blog/raw/master/img/202102/20210220155501.png#alt=)powershell [root@ecs conf.d]# cat autoindex.conf server { server_name autoindex.test.com; listen 8080; location / { alias html/; autoindex on; #index a.html; autoindex_exact_size off; autoindex_format html; autoindex_localtime on; } } [root@ecs conf.d]# curl autoindex.test.com:8080 <!DOCTYPE html>

** 以html的形式显示文件目录 **

[root@ecs conf.d]# cat autoindex.conf server { server_name autoindex.test.com; listen 8080; location / { alias html/; autoindex on; index a.html; autoindex_exact_size off; autoindex_format html; autoindex_localtime on; } } [root@ecs conf.d]# ../../sbin/nginx -s reload [root@ecs conf.d]# curl autoindex.test.com:8080

Index of /


```

../first/realpath/second/third/403.htmlnginx.org nginx.com Thank you for using nginx. nginx.org nginx.com Thank you for using nginx.
For online documentation and support please refer to sub.test.com/nginx.
Commercial support is available at sub.test.com/nginx.

403 Forbidden


403 Forbidden


403 Forbidden


403 Forbidden