nginx

nginx

  • 一、nginx简介
  • 二、nginx的特性与优点
    • 2.1 nginx的特性
    • 2.2 nginx的优点
  • 三、nginx的功能及应用类别
    • 3.1 nginx的基本功能
    • 3.2 nginx的扩展功能
    • 3.3 nginx的应用类别
  • 四、nginx的模块与工作原理
    • 4.1 nginx的模块分类
    • 4.2 nginx的工作原理
    • 4.3 web服务器请求资源的过程:
  • 五、nginx的安装与配置
    • 5.1 nginx的安装
    • 5.2 nginx安装后配置
  • 六、nginx的配置文件详解
    • 6.1 nginx.conf配置详解
    • 6.2 用于调试、定位问题的配置参数
    • 6.3 正常运行必备的配置参数
    • 6.4 优化性能的配置参数
    • 6.5 事件相关的配置:event{}段中的配置参数
    • 6.6 网络连接相关的配置参数
    • 6.7 fastcgi的相关配置参数
    • 6.8 常需要进行调整的参数
    • 6.9 nginx作为web服务器时使用的配置:http{}段的配置参数
      • 6.9.1 错误页面配置
      • 6.9.2 平滑升级加echo功能
      • 6.9.3 location配置
    • 6.10 访问控制
    • 6.11 基于用户认证
    • 6.12 https配置
    • 6.13 状态界面配置
      • 6.13.1 状态界面监控
    • 6.14 rewrite
    • 6.15 if
      • 6.15.1 基于浏览器实现分离案例
      • 6.15.2 防盗链案例
    • 6.16 反向代理与负载均衡

一、nginx简介

nginx(发音同engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。

nginx由俄罗斯的程序设计师Igor Sysoev所开发,最初供俄国大型的入口网站及搜寻引擎Rambler使用。

第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

nginx的特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

二、nginx的特性与优点

2.1 nginx的特性

nginx是一个很牛的高性能Web和反向代理服务器,它具有很多非常优越的特性:

  • 在高连接并发的情况下,nginx是Apache服务器不错的替代品,能够支持高达50000个并发连接数的响应
  • 使用epoll and kqueue作为开发模型
  • nginx作为负载均衡服务器:nginx既可在内部直接支持和PHP程序对外进行服务,也可支持作为HTTP代理服务器对外进行服务
  • nginx采用C进行编写,不论系统资源开销还是CPU使用效率都比Perlbal要好很多

2.2 nginx的优点

  • 高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2-3万并发连接数
  • 内存消耗少:在3万并发连接下,开启的10个nginx进程才消耗150M内存(15M*10=150M)
  • 配置文件非常简单:风格跟程序一样通俗易懂
  • 成本低廉:nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币
  • 支持Rewrite重写规则:能够根据域名、URL的不同,将HTTP请求分到不同的后端服务器群组
  • 内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问
  • 节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头
  • 稳定性高:用于反向代理,宕机的概率微乎其微
  • 模块化设计:模块可以动态编译
  • 外围支持好:文档全,二次开发和模块较多
  • 支持热部署:可以不停机重载配置文件
  • 支持事件驱动、AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化

三、nginx的功能及应用类别

3.1 nginx的基本功能

  • 静态资源的web服务器,能缓存打开的文件描述符
  • http、smtp、pop3协议的反向代理服务器
  • 缓存加速、负载均衡
  • 支持FastCGI(fpm,LNMP),uWSGI(Python)等
  • 模块化(非DSO机制),过滤器zip、SSI及图像的大小调整
  • 支持SSL

3.2 nginx的扩展功能

  • 基于名称和IP的虚拟主机
  • 支持keepalive
  • 支持平滑升级
  • 定制访问日志、支持使用日志缓冲区提高日志存储性能
  • 支持URL重写
  • 支持路径别名
  • 支持基于IP及用户的访问控制
  • 支持速率限制,支持并发数限制

3.3 nginx的应用类别

  • 使用nginx结合FastCGI运行PHP、JSP、Perl等程序
  • 使用nginx作反向代理、负载均衡、规则过滤
  • 使用nginx运行静态HTML网页、图片
  • nginx与其他新技术的结合应用

四、nginx的模块与工作原理

nginx由内核和模块组成。其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

URI:Uniform Resource Indentifier,统一资源标识符。用于定义全局范围内(包括但不仅限于互联网)去标识唯一的、定位一种资源访问路径的方式,或者命名方式,被称作统一资源标识符。这里的统一指的是路径格式上的统一。

URL:Uniform Resource Location,统一资源定位符,是URI的一个子集,用于描述在互联网上互联网资源的统一表示格式(protocol://host:port/path/to/file)

PV:Page View,打开了多少页面
UV:User View,独立IP量(UV的数量多说明访问的人多)

4.1 nginx的模块分类

nginx的模块从结构上分为核心模块、基础模块和第三方模块

  • HTTP模块、EVENT模块和MAIL模块等属于核心模块
  • HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块属于基本模块
  • HTTP Upstream模块、Request Hash模块、Notice模块和HTTP Access Key模块属于第三方模块

用户根据自己的需要开发的模块都属于第三方(任何人)模块,第三方模块是一定要编译的。正是有了如此多模块的支撑,nginx的功能才会如此强大

nginx模块从功能上分为三类,分别是:

  • Proxies(代理器模块)。就是nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如fastcgi等操作交互,实现服务代理和负载均衡等功能
  • Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。handlers处理器模块一般只能有一个
  • Filters(过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由nginx输出

nginx模块分为:核心模块、事件模块、标准Http模块、可选Http模块、邮件模块、第三方模块和补丁等

  • nginx基本模块:所谓基本模块,指的是nginx默认的功能模块,它们提供的指令,允许你使用定义nginx基本功能的变量,在编译时不能被禁用,包括:

核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令,大部分是放置在配置文件的顶部(每一行的顶部,帮助文档指的顶部是main)

事件模块:在Nginx内配置网络使用的能力。常见的events(事件)模块指令,大部分是放置在配置文件的顶部

配置模块:提供包含机制

具体的指令,请参考nginx的官方文档

4.2 nginx的工作原理

nginx的模块直接被编译进nginx,因此属于静态编译方式。

启动nginx后,nginx的模块被自动加载,与Apache不一样,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。

在解析配置文件时,nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。

Nginx默认采用多进程工作方式,Nginx启动后,会运行一个master进程和多个worker进程。其中master充当整个进程组与用户的交互接口,同时对进程进行监护,管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。worker用来处理基本的网络事件,worker之间是平等的,他们共同竞争来处理来自客户端的请求。

nginx的进程架构:
启动nginx时,会启动一个Master进程,这个进程不处理任何客户端的请求,主要用来产生worker线程,一个worker线程用来处理n个request。
nginx_第1张图片
web sever:web服务器的集群
application server : 应用服务器的集群
mencached: 缓存服务器的集群
backend: 后端
advaced I/O: 同步
sendfile,AIO 异步

工作方式
在工作方式上,Nginx分为单工作进程和多工作进程两种模式。在单工作进程模式下,除主进程外,还有一个工作进程,工作进程是单线程的;在多工作进程模式下,每个工作进程包含多个线程。Nginx默认为单工作进程模式。

Nginx在启动后,会有一个master进程和多个worker进程。

下图展示了nginx模块一次常规的HTTP请求和响应的过程
nginx_第2张图片

4.3 web服务器请求资源的过程:

nginx_第3张图片
1 、建立连接:接收或拒绝连接请求:三次握手的过程
提高HTTP 连接性能:

并行连接:通过多条TCP 连接发起并发的HTTP 请求

持久连接:keep-alive, 长连接,重用TCP 连接,以消除连接和关闭的时延, 以事务个数和时间来决定是否关闭连接

管道化连接:通过共享TCP 连接发起并发的HTTP 请求

复用的连接:交替传送请求和响应报文(实验阶段,还未实现)

2 、接收请求:接收客户端请求报文中对某资源的一次请求的过程,请求报文
Web 访问响应模型(Web I/O)

单进程I/O 模型: 启动一个进程处理用户请求,而且一次只处理一个,多个请求被串行响应,太古老了

多进程I/O 模型 : 并行启动多个进程, 每个进程响应一个连接请求

复用I/O 结构 :启动一个进程,同时响应N 个连接请求,连接池

实现方法: 多线程模型和事件驱动

多线程模型:一个进程生成N个线程,每线程响应一个连接请求

事件驱动:一个进程处理N 个请求,Nginx

进程:比如复制的工作,项目小组,耗资源

线程:比如人,轻量级

一个进程必有一个线程,一个进程可以有多个线程

复用的多进程I/O 模型:启动M个进程,每个进程响应N个连接请求,同时接收M*N 个请求

3 、处理请求
服务器对请求报文进行解析,并获取请求的资源及请求方法等相关信息 ,根据方法,资源,首部和可选的主体部分对请求进行处理

元数据:请求报文首部

HEADERS 格式 name:value

4 、访问资源
服务器获取请求报文中请求的资源web 服务器,即存放了web 资源的服务器,负责向请求者提供对方请求的静态资源,或动态运行后生成的资源
资源放置于本地文件系统特定的路径:DocRoot 服务的根

DocRoot —> /var/www/html

例:/var/www/html/images/logo.jpg

http://www.along.com/images/logo.jpg

web 服务器资源路径映射方式:

(a) docroot

(b) alias

© 虚拟主机docroot

(d) 用户家目录docroot

5、构建响应报文
一旦Web 服务器识别出了资源,就执行请求方法中描述中的动作,并返回响应报文。响应报文中 ,包含有响应状态码、响应首部,如果生成了响应主体的话,还包括响应主体。

1)响应实体:如果事务处理产生了响应主体,就将内容放在响应报文中回送过去。响应报文中通常包括:

描述了响应主体MIME 类型的Content-Type 首部

描述了响应主体长度大小的Content-Length

实际报文的主体内容

2)URL 重定向:web 服务构建的响应并非客户端请求的资源,而是资源另外一个访问路径

永久重定向:http://www.360buy.com —> http://www.jd.com

临时重定向:http://www.taobao.com —> https://www.taobao.com

3)MIME 类型:多媒体的邮件扩展

Web 服务器要负责确定响应主体的MIME 类型。有很多配置服务器的方法可以将MIME 类型与资源管理起来

魔法分类(扫描首部信息):Apache web 服务器可以扫描每个资源的内容,并将其与一个已知模式表,首部( 被称为魔法文件) 进行匹配,以决定每个文件的MIME 类型。这样做可能比较慢,但很方便,尤其是文件没有标准扩展名的时候

显式分类:可以对Web 服务器进行配置,使其不考虑文件的扩展名或内容,强制特定文件或目录内容拥有某个MIME 类型,例如:php,Apache不识别,强制识别

类型协商: 有些Web 服务器经过配置,可以以多种文档格式来存储资源。在这种情况下,可以配置Web 服务器,使其可以通过与用户的协商来决定使用哪种格式( 及相关的MIME 类型)" 最好"

6 、发送响应报文
Web 服务器通过连接发送数据时也会面临与接收数据一样的问题。服务器可能有很多条到各个客户端的连接, 有些是空闲的,有些在向服务器发送数据,还有一些在向客户端回送响应数据 。服务器 要记录连接的状态,还要特别注意对持久连接的处理。对非持久连接而言,服务器应该在发送了整条报文之后,关闭自己这一端的连接 。对持久连接来说,连接可能仍保持打开状态,在这种情况下, 服务器要 正确地计算Content-Length 首部,不然客户端就无法知道响应什么时候结束了

7 、记录日志
最后 ,当事务结束时,Web 服务器会在日志文件中添加一个条目,来描述已执行的事务

日志类型:下一篇会详解日志各项格式的意义

访问日志:现在愈发重要,大数据的时代

错误日志:排错使用

五、nginx的安装与配置

nginx及apache网站存放的位置:

  • 源码安装的nginx,网站存放在安装目录上的HTML下面
  • yum安装的nginx,网站存放在/usr/share/nginx/html下面
  • 源码安装的apache,网站存放在安装目录的htdocs下面
  • yum安装的apache,网站放在/var/www/html下面

5.1 nginx的安装

// 关闭防火墙和selinux
[root@localhost ~]# systemctl disable --now firewalld.service
[root@localhost ~]# setenforce 0

// 安装epel源、vim、wget
[root@nginx ~]# yum -y install epel-release vim wget

//创建系统用户nginx
[root@localhost ~]# useradd -r -M -s /sbin/nologin nginx

//安装依赖环境
[root@localhost ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++

//创建日志存放目录
[root@localhost ~]# mkdir -p /var/log/nginx
[root@localhost ~]# chown -R nginx.nginx /var/log/nginx

//下载nginx
[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
--2021-10-25 18:34:46--  http://nginx.org/download/nginx-1.20.1.tar.gz
正在解析主机 nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5702::6, ...
正在连接 nginx.org (nginx.org)|3.125.197.172|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:980831 (958K) [application/octet-stream]
正在保存至: “nginx-1.20.1.tar.gz”

100%[=========================>] 980,831      498KB/s 用时 1.9s   

2021-10-25 18:34:48 (498 KB/s) - 已保存 “nginx-1.20.1.tar.gz” [980831/980831])

//编译安装
[root@localhost src]# ls
debug  kernels  nginx-1.20.1.tar.gz
[root@localhost src]# tar xf nginx-1.20.1.tar.gz
[root@localhost src]# cd nginx-1.20.1
[root@localhost nginx-1.20.1]# ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-debug \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_image_filter_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=/var/log/nginx/error.log

[root@localhost nginx-1.20.1]# make && make install

5.2 nginx安装后配置

//配置环境变量
[root@localhost ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@localhost ~]# cat /etc/profile.d/nginx.sh 
export PATH=/usr/local/nginx/sbin:$PATH
[root@localhost ~]# bash

//服务控制方式,使用nginx命令
    -t  //检查配置文件语法
[root@localhost ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

    -v  //输出nginx的版本
[root@localhost ~]# nginx -v
nginx version: nginx/1.12.0

    -V  //查看编译nginx时,用了哪些参数
[root@localhost ~]# nginx -V
nginx version: nginx/1.12.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

    -c  //指定配置文件的路径
[root@localhost ~]# nginx -s stop ; nginx -c /opt/nginx.conf
    -s  //发送服务控制信号,可选值有{stop|quit|reopen|reload}
[root@localhost ~]# nginx -s quit
[root@localhost ~]# ss -antl
State  Recv-Q Send-Q  Local Address:Port   Peer Address:Port Process                                                      
LISTEN 0      128           0.0.0.0:22          0.0.0.0:*                                                                 
LISTEN 0      128              [::]:22             [::]:*              

//启动nginx
[root@localhost ~]# nginx
[root@localhost ~]# ss -antl
State       Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN      0      128     *:80                  *:*                  
LISTEN      0      128     *:22                  *:*                  
LISTEN      0      100    127.0.0.1:25                  *:*                  
LISTEN      0      128    :::22                 :::*                  
LISTEN      0      100       ::1:25                 :::*                  

六、nginx的配置文件详解

主配置文件:/usr/local/nginx/conf/nginx.conf

  • 默认启动nginx时,使用的配置文件是:安装路径/conf/nginx.conf文件
  • 可以在启动nginx时通过-c选项来指定要读取的配置文件

nginx常见的配置文件及其作用

配置文件 作用
nginx.conf nginx的基本配置文件
mime.types MIME类型关联的扩展文件
fastcgi.conf 与fastcgi相关的配置
proxy.conf 与proxy相关的配置
sites.conf 配置nginx提供的网站,包括虚拟主机

6.1 nginx.conf配置详解

nginx.conf的内容分为以下几段:

  • main配置段:全局配置段。其中main配置段中可能包含event配置段
  • event {}:定义event模型工作特性
  • http{}:定义http协议相关的配置

配置指令:要以分号结尾,语法格式如下:

derective value1 [value2 …];

支持使用变量:

  • 内置变量:模块会提供内建变量定义
  • 自定义变量:set var_name value

6.2 用于调试、定位问题的配置参数

daemon {on|off};        //是否以守护进程方式运行nginx,调试时应设置为off
master_process{on|off};     //是否以master/worker模型来运行nginx,调试时可以设置为off
error_log 位置 级别;      //配置错误日志

error_log里的位置和级别能有以下可选项:

位置 级别
file(文件)
stderr(在屏幕里输出的)
syslog:server=address[,parameter=value](用系统里自带的日志服务来管理)
memory:size(用内存来管理)
debug:若要使用debug级别,需要在编译nginx时使用–with-debug选项
info
notice
warn
error
crit
alert
emerg

位置一般用的是file 文件
级别一般默认的是error

6.3 正常运行必备的配置参数

user USERNAME [GROUPNAME];    //指定运行worker进程的用户和组
pid  /path/to/pid_file;     //指定nginx守护进程的pid文件
worker_rlimit_nofile number;    //设置所有worker进程最大可以打开的文件数,默认为1024
worker_rlimit_core size;      //指明所有worker进程所能够使用的总体的最大核心文件大小,保持默认即可

6.4 优化性能的配置参数

worker_processes n;    //启动n个worker进程,这里的n为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数
worker_cpu_affinity cpumask …;    //将进程绑定到某cpu中,避免频繁刷新缓存
//cpumask:使用8位二进制表示cpu核心,如:
 0000 0001 //第一颗cpu核心
 0000 0010 //第二颗cpu核心
 0000 0100 //第三颗cpu核心
 0000 1000 //第四颗cpu核心
 0001 0000 //第五颗cpu核心
 0010 0000 //第六颗cpu核心
 0100 0000 //第七颗cpu核心
 1000 0000 //第八颗cpu核心
timer_resolution interval;     //计时器解析度。降低此值,可减少gettimeofday()系统调用的次数
worker_priority number;    //指明worker进程的nice值

6.5 事件相关的配置:event{}段中的配置参数

accept_mutex {off|on};    //master调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求
lock_file file;     //accept_mutex用到的互斥锁锁文件路径 use [epoll | rtsig |
select | poll];    //指明使用的事件模型,建议让nginx自行选择
worker_connections #;    //每个进程能够接受的最大连接数

6.6 网络连接相关的配置参数

keepalive_timeout number;    //长连接的超时时长,默认为65s
keepalive_requests number;   //在一个长连接上所能够允许请求的最大资源数
keepalive_disable [msie6|safari|none];    //为指定类型的UserAgent禁用长连接
tcp_nodelay on|off;    //是否对长连接使用TCP_NODELAY选项,为了提升用户体验,通常设为on
client_header_timeout number;    //读取http请求报文首部的超时时长
client_body_timeout number;    //读取http请求报文body部分的超时时长
send_timeout number;    //发送响应报文的超时时长

6.7 fastcgi的相关配置参数

LNMP:php要启用fpm模型
配置示例如下:

location ~ \.php$ {
  root html;
  fastcgi_pass 127.0.0.1:9000;      //定义反向代理
  fastcgi_index index.php;
  fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
  include fastcgi_params;
}

6.8 常需要进行调整的参数

  • worker_processes
  • worker_connections
  • worker_cpu_affinity
  • worker_priority

6.9 nginx作为web服务器时使用的配置:http{}段的配置参数

http{…}:配置http相关,由ngx_http_core_module模块引入。nginx的HTTP配置主要包括四个区块,结构如下:

http {//协议级别
  include mime.types;
  default_type application/octet-stream;
  keepalive_timeout 65;
  gzip on;
  upstream {//负载均衡配置
    ...
  }
  server {//服务器级别,每个server类似于httpd中的一个<VirtualHost>
    listen 80;
    server_name localhost;
    location / {//请求级别,类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系
      root html;
      index index.html index.htm;
    }
  }
}

http{}段配置指令:
server {}:定义一个虚拟主机,示例如下:

server {
  listen 80;
  server_name www.idfsoft.com;
  root "/vhosts/web";
}

listen:指定监听的地址和端口

listen address[:port];
listen port;

server_name NAME […]; 后面可跟多个主机,名称可使用正则表达式或通配符

当有多个server时,匹配顺序如下:

  1. 先做精确匹配检查
  2. 左侧通配符匹配检查,如*.idfsoft.com
  3. 右侧通配符匹配检查,如mail.*
  4. 正则表达式匹配检查,如~ ^.*.idfsoft.com$
  5. default_server

root path; 设置资源路径映射,用于指明请求的URL所对应的资源所在的文件系统上的起始路径

alias path; 用于location配置段,定义路径别名

index file; 默认主页面

index index.php index.html;

6.9.1 错误页面配置

error_page code […] [=code] URI | @name 根据http响应状态码来指明特用的错误页面,例如 error_page 404 /404_customed.html

[=code]:以指定的响应码进行响应,而不是默认的原来的响应,默认表示以新资源的响应码为其响应码,例如 error_page 404 =200 /404_customed.html

[root@localhost ]# vim /usr/local/nginx/conf/nginx.conf
48         error_page  404              /404.html;     ## 取消注释

// 提供404页面
[root@localhost ~]# ls /usr/local/nginx/html/
50x.html  index.html  index.php

## 随便下载一个网站
[root@localhost ~]# cd /usr/local/nginx/html/
[root@localhost html]# ls
50x.html  index.html  index.php
[root@localhost html]# ls
50x.html                                    index.html
百度翻译-200种语言互译、沟通全世界!_files  index.php
百度翻译-200种语言互译、沟通全世界!.html
[root@localhost html]# mv 百度翻译-200种语言互译、沟通全世界!.html 404.html
[root@localhost html]# ls
404.html  百度翻译-200种语言互译、沟通全世界!_files  index.php
50x.html  index.html

## 重新加载一下
[root@localhost html]# nginx -s reload

测试,故意把网站输错
nginx_第4张图片
nginx_第5张图片

// 把状态码改为200,200代表正常,访问到了则显示为200
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 48         error_page  404    =200          /404.html;
[root@localhost ~]# nginx -s reload

重新加载一下网页
nginx_第6张图片
log_format 定义日志格式

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
access_log  logs/access.log  main;

//注意:此处可用变量为nginx各模块内建变量

6.9.2 平滑升级加echo功能

平滑升级:不能执行安装操作

  1. 获取老版本的编译参数 -V
  2. 获取新版本或新功能的软件包
  3. 对新功能或新版本的软件包进行编译
  4. 备份老程序
  5. 停掉老程序并用新程序使用老程序的配置文件进行启动
  6. 检验功能,若无问题即用新程序替换老程序;如果有问题,就把新程序启动,用老程序直接启动
// 用echo这个模块来测试,测试location写的有没有问题
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root   html;
 45             index  index.php index.html index.htm;
 46         }
 47 
 48         location /abc {        //在配置文件中间加上这两行,这句话的意思是一旦匹配到abc这个URI了就打印wjj
 49             echo "wjj";
 50         }
 51 
 52         error_page  404    =200          /404.html;

// 检查一下nginx语法,报错说没有echo这个模块
[root@localhost ~]# nginx -t
nginx: [emerg] unknown directive "echo" in /usr/local/nginx/conf/nginx.conf:49
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

// 去github.com上面搜索echo nginx,找到echo-nginx-module,然后把这个包下载下来
[root@localhost ~]# ls
anaconda-ks.cfg  echo-nginx-module-master.zip  password

// 查看编译nginx时,用了哪些参数
[root@localhost ~]# nginx -V
nginx version: nginx/1.20.1
built by gcc 8.5.0 20210514 (Red Hat 8.5.0-3) (GCC) 
built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

// 解压
[root@localhost ~]# unzip echo-nginx-module-master.zip 
[root@localhost ~]# ls
anaconda-ks.cfg           echo-nginx-module-master.zip
echo-nginx-module-master  password

// 对nginx重新编译,把老版本的编译编译参数复制过来,再在它的基础上加--add-module=/root/echo-nginx-module-master,然后再编译
[root@localhost nginx-1.20.1]# cd /usr/local/nginx-1.20.1/
[root@localhost nginx-1.20.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-debug --with-http_ssl_module --with-http_realip_module --with-http_image_filter_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_stub_status_module --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --add-module=/root/echo-nginx-module-master
.............此处省略过程
  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"
[root@localhost nginx-1.20.1]# ls
auto     CHANGES.ru  configure  html     Makefile  objs    src
CHANGES  conf        contrib    LICENSE  man       README
[root@localhost nginx-1.20.1]# ls objs/
addon         ngx_auto_headers.h  src
autoconf.err  nginx.8            ngx_modules.c
Makefile      ngx_auto_config.h  ngx_modules.o
[root@localhost nginx-1.20.1]# make
..............此处省略编译过程
-ldl -lpthread -lcrypt -lpcre -lssl -lcrypto -ldl -lpthread -lz -lgd \
-Wl,-E
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
        -e "s|%%PID_PATH%%|/usr/local/nginx/logs/nginx.pid|" \
        -e "s|%%CONF_PATH%%|/usr/local/nginx/conf/nginx.conf|" \
        -e "s|%%ERROR_LOG_PATH%%|/var/log/nginx/error.log|" \
        < man/nginx.8 > objs/nginx.8
make[1]: 离开目录“/usr/local/nginx-1.20.1”

// 编译完,objs下面就会出现一个主程序
[root@localhost nginx-1.20.1]# ls objs/
addon         nginx              ngx_auto_headers.h  src
autoconf.err  nginx.8            ngx_modules.c
Makefile      ngx_auto_config.h  ngx_modules.o

// [root@localhost nginx-1.20.1]# ll objs/nginx /usr/local/nginx/sbin/nginx 
-rwxr-xr-x 1 root root 6831128 1027 18:54 objs/nginx
-rwxr-xr-x 1 root root 6308640 1026 18:55 /usr/local/nginx/sbin/nginx

// 备份老程序
[root@localhost nginx-1.20.1]# cp /usr/local/nginx/sbin/nginx /opt/
[root@localhost nginx-1.20.1]# ls /opt/
data  nginx

// 停掉老程序并用新程序使用老程序的配置文件进行启动(先把最开始在配置文件里写的location注释掉)
[root@localhost nginx-1.20.1]# nginx -s stop;objs/nginx -c /usr/local/nginx/conf/nginx.conf
[root@localhost nginx-1.20.1]# ps -ef|grep nginx
root      254344       1  0 19:04 ?        00:00:00 nginx: master process objs/nginx -c /usr/local/nginx/conf/nginx.conf
nginx     254345  254344  0 19:04 ?        00:00:00 nginx: worker process
root      255543    9653  0 19:04 pts/2    00:00:00 grep --color=auto nginx

// 再把配置文件的locatian那两行取消注释,再检查一下新程序的语法
[root@localhost nginx-1.20.1]# objs/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost nginx-1.20.1]# objs/nginx -s reload

// 检验功能,若无问题即用新程序替换老程序
[root@localhost ~]# curl http://192.168.47.169/abc
wjj
[root@localhost nginx-1.20.1]# \cp objs/nginx /usr/local/nginx/sbin/
[root@localhost nginx-1.20.1]# ll objs/nginx /usr/local/nginx/sbin/nginx 
-rwxr-xr-x 1 root root 6831128 1027 18:54 objs/nginx
-rwxr-xr-x 1 root root 6831128 1027 19:09 /usr/local/nginx/sbin/nginx

// 把objs/nginx先停了,用默认的先启动
[root@localhost nginx-1.20.1]# objs/nginx -s stop;nginx
[root@localhost nginx-1.20.1]# ps -ef|grep nginx
root      278151       1  0 19:11 ?        00:00:00 nginx: master process nginx
nginx     278152  278151  0 19:11 ?        00:00:00 nginx: worker process
root      279202    9653  0 19:11 pts/2    00:00:00 grep --color=auto nginx

6.9.3 location配置

语法:location [ = | ~ | ~* | ^~ ] uri { … }
location @name { … }

location区段,通过指定模式来与客户端请求的URI相匹配

//功能:允许根据用户请求的URI来匹配定义的各location,匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能

//语法:location [ 修饰符 ] pattern {......}

常用修饰符说明:

修饰符 功能
= 精确匹配
~ 正则表达式模式匹配,区分大小写
~* 正则表达式模式匹配,不区分大小写
^~ 前缀匹配,类似于无修饰符的行为,也是以指定模块开始,不同的是,如果模式匹配,那么就停止搜索其他模式了,不支持正则表达式
@ 定义命名location区段,这些区段客户端不能访问,只可以由内部产生的请求来访问,如try_files或error_page等
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
## 注释掉以下几行
     43         #location / {
     44         #   root   html;
     45         #    index  index.php index.html index.htm;
     46         #}
## 加入以下这几行
     47 
     48         location = / {       // 等于号是精确匹配,优先级最高
     49             echo "[ configuration A ]";
     50         }
     51 
     52         location / {       //默认主页
     53             echo "[ configuration B ]";
     54         }
     55 
     56         location /documents/ {
     57             echo "[ configuration C ]";
     58         }
     59 
     60         location ^~ /images/ {
     61             echo "[ configuration D ]";
     62         }
     63 
     64         location ~* \.(gif|jpg|jpeg)$ {
     65             echo "[ configuration E ]";
     66         }
[root@localhost conf]# nginx -s reload

// 检查访问
[root@localhost ~]# curl http://192.168.47.169
[ configuration A ]
[root@localhost ~]# curl http://192.168.47.169/index.html
[ configuration B ]
[root@localhost ~]# curl http://192.168.47.169/documents/document.html
[ configuration C ]
[root@localhost ~]# curl http://192.168.47.169/images/1.gif
[ configuration D ]
[root@localhost ~]# curl http://192.168.47.169/documents/1.jpg
[ configuration E ]

没有修饰符表示必须以指定模式开始,如:

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 48         location /abc {
 49             echo "无修饰符的location";
 50         }
 51 
[root@localhost conf]# nginx -s reload
[root@localhost conf]# curl http://192.168.47.169/abc      
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abc/
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abc\?a\=10\&b\=20 
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abcde      // 只要匹配到其中的某一部分,那么后面也能匹配到
无修饰符的location

那么如下内容就可正确匹配:
http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22
http://www.idfsoft.com/abc/

=:表示必须与指定的模式精确匹配,如:

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 48         location /abc {
 49             echo "无修饰符的location";
 50         }
 51 
 52         location = /abc {
 53             echo "有等于号的location";
 54         }
[root@localhost conf]# nginx -s reload
[root@localhost conf]# curl http://192.168.47.169/abc
有等于号的location
[root@localhost conf]# curl http://192.168.47.169/abc\?a\=10\&b\=20
有等于号的location
[root@localhost conf]# curl http://192.168.47.169/abc/
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abcde
无修饰符的location

那么如下内容就可正确匹配:

http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22

如下内容则无法匹配:

http://www.idfsoft.com/abc/
http://www.idfsoft.com/abc/abcde

~:表示指定的正则表达式要区分大小写,如:

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 48         location /abc {
 49             echo "无修饰符的location";
 50         }
 51 
 52         location ~ ^ /abc$ {
 53             echo "区分大小写的location";
 54         }
[root@localhost conf]# nginx -s reload
[root@localhost conf]# curl http://192.168.47.169/abc
区分大小写的location
[root@localhost conf]# curl http://192.168.47.169/abc/
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abcde
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abc\?a\=10\&b\=20
区分大小写的location

那么如下内容就可正确匹配:

http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22

如下内容则无法匹配:

http://www.idfsoft.com/abc/
http://www.idfsoft.com/ABC
http://www.idfsoft.com/abcde

~*:表示指定的正则表达式不区分大小写,如:

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 48         location /abc {
 49             echo "无修饰符的location";
 50         }
 51 
 52         location ~ ^/abc$ {
 53             echo "区分大小写的location";
 54         }
 55 
 56         location ~* ^/abc$ {
 57             echo "不区分大小写的location";
 58         }
[root@localhost conf]# nginx -s reload
[root@localhost conf]# curl http://192.168.47.169/abc
区分大小写的location         //因为把区分大小写的放在前面去了,优先级高,所以匹配到的是区分大小写的

// 把不区分大小写的放在前面,把区分大小写的放在后面就能匹配到
[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 48         location /abc {
 49             echo "无修饰符的location";
 50         }
 51 
 52         location ~ ^*/abc$ {
 53             echo "不区分大小写的location";
 54         }
 55 
 56         location ~ ^/abc$ {
 57             echo "区分大小写的location";
 58         }
[root@localhost conf]# nginx -s reload
[root@localhost conf]# curl http://192.168.47.169/abc
不区分大小写的location
[root@localhost conf]# curl http://192.168.47.169/aBc
不区分大小写的location
[root@localhost conf]# curl http://192.168.47.169/abc\?a\=10\&b\=20
不区分大小写的location
[root@localhost conf]# curl http://192.168.47.169/abcde
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abc/
无修饰符的location
[root@localhost conf]# curl http://192.168.47.169/abc
不区分大小写的location
[root@localhost conf]# curl http://192.168.47.169/ABC
不区分大小写的location

那么如下内容就可正确匹配:

http://www.idfsoft.com/abc
http://www.idfsoft.com/abc?p1=11&p2=22
http://www.idfsoft.com/ABC

如下内容则无法匹配:

http://www.idfsoft.com/abc/
http://www.idfsoft.com/abcde

~:类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,则停止搜索其他模式

查找顺序和优先级:由高到底依次为

  1. 带有=的精确匹配优先
  2. 正则表达式按照他们在配置文件中定义的顺序
  3. 带有^~修饰符的,开头匹配
  4. 带有*修饰符的,如果正则表达式与URI匹配
  5. 没有修饰符的精确匹配

优先级次序如下:

( location = 路径 ) --> ( location ^~ 路径 ) --> ( location ~ 正则 ) --> ( location ~* 正则 ) --> ( location 路径 )

6.10 访问控制

访问控制在https://nginx.org/en/docs/http/ngx_http_access_module.html

用法:allow IP地址 | 网段 | unix: | all;
环境:http(在这个里面用就影响整个主机的所有的网站),server(在这个里面用就影响某一个虚拟主机),location(在这个里面用就影响某一个资源),limit_except

这个东西在什么地方用就影响哪里

用于location段
allow:设定允许哪台或哪些主机访问,多个参数间用空格隔开
deny:设定禁止哪台或哪些主机访问,多个参数间用空格隔开
示例:

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root   html;
 45             index  index.html;
 46         }
 47 
 48         location /test {
 49             root html;
 50             index index.html;
 51         }
[root@localhost conf]# cd ../html/
[root@localhost html]# mkdir test
[root@localhost html]# ls
404.html  百度翻译-200种语言互译、沟通全世界!_files  index.php
50x.html  index.html                                  test
[root@localhost test]# touch index.html
[root@localhost test]# vim index.html 
[root@localhost test]# cat index.html 
<html>
<head>
<title>test page</title>
</head>
<body>
<a href="http://www.baidu.com/">baidu</a>
</body>
</html>
[root@localhost html]# nginx -s reload

nginx_第7张图片
做一下访问控制,让它不能访问(设置黑名单)

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root   html;
 45             index  index.html;
 46         }
 47 
 48         location /test {
 49             deny 192.168.47.1;     //拒绝访问
 50             root html;
 51             index index.html;
 52        }
[root@localhost conf]# nginx -s reload

再查看
nginx_第8张图片
但是在本机上可以访问到

[root@localhost conf]# curl http://192.168.47.169/test/index.html
<html>
<head>
<title>test page</title>
</head>
<body>
<a href="http://www.baidu.com">baidu</a>
</body>
</html>

白名单

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root   html;
 45             index  index.html;
 46         }
 47 
 48         location /test {
 49             allow 192.168.47.1;     
                deny all;
 50             root html;
 51             index index.html;
 52        }
[root@localhost conf]# nginx -s reload

// 在本机上访问不了
[root@localhost conf]# curl http://192.168.47.169/test/index.html
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>

在网页上可以访问
nginx_第9张图片

6.11 基于用户认证

帮助文档:https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html

语法:auth_basic string(字符串) | off;
默认:auth_basic off;
环境:http,server,location,limit_except

auth_basic "欢迎信息";
auth_basic_user_file "/path/to/user_auth_file"

user_auth_file内容格式为:

username:password

这里的密码为加密后的密码串,建议用htpasswd来创建此文件:

htpasswd -c -m /path/to/.user_auth_file USERNAME
//下载安装包并生成密码
[root@localhost conf]# yum -y install httpd-tools

[root@localhost conf]# htpasswd -c -m .pass admin     // admin是虚拟账户,不能用来登录系统,但是可以访问nginx
New password: 
Re-type new password: 
Adding password for user admin
[root@localhost conf]# cat .pass 
admin:$apr1$6RckE/0o$BApzVdLJZNKUUXAPi3Su3/

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
 48         location /test {
 49             auth_basic "王静静";
 50             auth_basic_user_file ".pass";     //认证的密码文件
 51             root html;
 52             index index.html;
 53        }
[root@localhost conf]# nginx -s reload

访问测试
nginx_第10张图片
nginx_第11张图片

6.12 https配置

生成私钥,生成证书签署请求并获得证书,然后在nginx.conf中配置如下内容:

server {
  listen       443 ssl;
  server_name  www.idfsoft.com;
  ssl_certificate      /etc/nginx/ssl/nginx.crt;
  ssl_certificate_key  /etc/nginx/ssl/nginx.key;
  ssl_session_cache    shared:SSL:1m;
  ssl_session_timeout  5m;
  ssl_ciphers  HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers  on;
  location / {
    root   html;
    index  index.html index.htm;
  }
}
[root@localhost conf]# pwd
/usr/local/nginx/conf
[root@localhost conf]# ls
fastcgi.conf            koi-win             scgi_params
fastcgi.conf.default    mime.types          scgi_params.default
fastcgi_params          mime.types.default  uwsgi_params
fastcgi_params.default  nginx.conf          uwsgi_params.default
koi-utf                 nginx.conf.default  win-utf
[root@localhost conf]# mkdir ssl
[root@localhost conf]# cd ssl/
[root@localhost ssl]# ls
[root@localhost ssl]# cd /etc/pki/
[root@localhost pki]# mkdir CA
[root@localhost pki]# cd CA/

// 生成一对密钥
[root@localhost CA]# mkdir private && (umask 077;openssl genrsa -out private/cakey.pem 2048)      
Generating RSA private key, 2048 bit long modulus (2 primes)
..............................................................................................................................................................+++++
.....................................................................+++++
e is 65537 (0x010001)

[root@localhost CA]# ls private/
cakey.pem

 // 生成自签署证书
[root@localhost CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365        
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:WH
Organization Name (eg, company) [Default Company Ltd]:wangjingjing 
Organizational Unit Name (eg, section) []:wangjingjing
Common Name (eg, your name or your server's hostname) []:test.wangjingjing.com
Email Address []:[email protected]
[root@localhost CA]# ls
cacert.pem  private
[root@localhost CA]# mkdir certs newcerts crl
[root@localhost CA]# ls
cacert.pem  certs  crl  newcerts  private
[root@localhost CA]# touch index.txt && echo 01 > serial
[root@localhost CA]# ls
cacert.pem  certs  crl  index.txt  newcerts  private  serial
[root@localhost ~]# cd /usr/local/nginx/conf/ssl/
[root@localhost ssl]# (umask 077;openssl genrsa -out nginx.key 2048)     // 客户端生成密钥
Generating RSA private key, 2048 bit long modulus (2 primes)
.............................................+++++
............................................................................+++++
e is 65537 (0x010001)
[root@localhost ssl]# ls
nginx.key

// 客户端生成证书签署请求
[root@localhost ssl]# openssl req -new -key nginx.key -days 365 -out nginx.csr
Ignoring -days; not generating a certificate
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN      
State or Province Name (full name) []:HB
Locality Name (eg, city) [Default City]:WH
Organization Name (eg, company) [Default Company Ltd]:wangjingjing
Organizational Unit Name (eg, section) []:wangjingjing
Common Name (eg, your name or your server's hostname) []:test.wangjingjing.com
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

[root@localhost ssl]# ll
总用量 8
-rw-r--r-- 1 root root 1058 1027 21:45 nginx.csr
-rw------- 1 root root 1675 1027 21:41 nginx.key

// CA签署客户端提交上来的证书
[root@localhost ssl]# openssl ca -in nginx.csr -out nginx.crt -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Oct 27 13:47:59 2021 GMT
            Not After : Oct 27 13:47:59 2022 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = HB
            organizationName          = wangjingjing
            organizationalUnitName    = wangjingjing
            commonName                = test.wangjingjing.com
            emailAddress              = 1@2.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                5E:63:B4:7C:CD:0F:07:56:78:AC:E2:16:98:AD:DD:B5:BD:F6:F4:E7
            X509v3 Authority Key Identifier: 
                keyid:B0:92:1F:06:5E:6B:72:77:D4:34:C0:A6:4B:75:E7:72:93:0E:CC:D0

Certificate is to be certified until Oct 27 13:47:59 2022 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
[root@localhost ssl]# ll
总用量 16
-rw-r--r-- 1 root root 4648 1027 21:48 nginx.crt
-rw-r--r-- 1 root root 1058 1027 21:45 nginx.csr
-rw------- 1 root root 1675 1027 21:41 nginx.key

[root@localhost ssl]# rm -f nginx.csr 
[root@localhost ssl]# ls
nginx.crt  nginx.key

[root@localhost ~]# vim /usr/local/nginx/conf/nginx.conf
##  取消下面所有的注释
105     server {
106         listen       443 ssl;
107         server_name  test.wangjingjing.com;     ## 域名要跟证书上的一样
108 
             ## 修改一下,以下两行
109         ssl_certificate      ssl/nginx.crt;     
110         ssl_certificate_key  ssl/nginx.key;
111 
112         ssl_session_cache    shared:SSL:1m;
113         ssl_session_timeout  5m;
114 
115         ssl_ciphers  HIGH:!aNULL:!MD5;
116         ssl_prefer_server_ciphers  on;
117 
118         location / {
119             root   html;
120             index  index.html index.htm;
121         }
122     }
[root@localhost conf]# nginx -s reload
[root@localhost conf]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:443        0.0.0.0:*            
LISTEN 0      128          0.0.0.0:80         0.0.0.0:*            
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*          

访问
nginx_第12张图片
nginx_第13张图片
nginx_第14张图片

6.13 状态界面配置

帮助文档:https://nginx.org/en/docs/http/ngx_http_stub_status_module.html

语法: stub_status;
环境:server,location

编译的时候一定要把状态编译上去,否则看不见
开启status:

location /status {
  stub_status {on | off};
  allow 172.16.0.0/16;
  deny all;
}

location /status {
    stub_status;
}

访问状态页面的方式:http://server_ip/status

[root@localhost conf]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root html;
 45             index index.html;
 46         }
 47 
           ## 加上以下两行
 48         location /status {
 49             stub_status;
 50         }
 51 
 52         location /test {
 53             auth_basic "王静静";
 54             auth_basic_user_file ".pass";
 55             root   html;
 56             index  index.html;
 57         }
[root@localhost conf]# nginx -s reload

访问网页
nginx_第15张图片
状态页面信息详解:

状态码 表示的意义
Active connections 2 当前所有处于打开状态的连接数
accepts 总共处理了多少个连接
handled 成功创建多少握手
requests总共处理了多少个请求
Reading nginx读取到客户端的Header信息数,表示正处于接收请求状态的连接数
Writing nginx返回给客户端的Header信息数,表示请求已经接收完成,
且正处于处理请求或发送响应的过程中的连接数
Waiting 开启keep-alive的情况下,这个值等于active - (reading + writing),
意思就是Nginx已处理完正在等候下一次请求指令的驻留连接

6.13.1 状态界面监控

环境说明:

主机名 IP 需要安装的包 系统
nginx 192.168.47.169 nginx zabbix_client cenos 7
zabbix 192.168.47.130 zabbix_server redhat 8

准备工作:
zabbix_serverd端安装
zabbix 客户端安装及部署

配置:

// 修改agent配置文件/usr/local/etc/zabbix_agentd.conf
[root@nginx zabbix-5.4.4]# tr -dc A-Za-z < /dev/urandom | head -c 8 |xargs
KRWWtKWg
[root@nginx zabbix-5.4.4]# cd /usr/local/etc/
[root@nginx etc]# ls
zabbix_agentd.conf  zabbix_agentd.conf.d
[root@nginx etc]# vim zabbix_agentd.conf
113 Server=192.168.47.130           #服务端ip
154 ServerActive=192.168.47.130     #服务端ip
165 Hostname=KRWWtKWg
322   UnsafeUserParameters=1      # 取消注释并修改值为1

// 启动服务
[root@nginx ~]# zabbix_agentd 
[root@nginx ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:443        0.0.0.0:*            
LISTEN 0      128          0.0.0.0:10050      0.0.0.0:*            
LISTEN 0      128          0.0.0.0:80         0.0.0.0:*            
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*      

// 编写脚本
[root@nginx ~]# mkdir scripts
[root@nginx ~]# cd scripts/
[root@nginx scripts]# vim status.sh 
[root@nginx scripts]# vi status.sh 
[root@nginx scripts]# cat status.sh 
#! /bin/bash

case $1 in
    "Reading")
    curl -s http://192.168.47.169/status | awk 'NR==4 {print $2}';;
    "Writing")
    curl -s http://192.168.47.169/status | awk 'NR==4 {print $4}';;
    "Waiting")
    curl -s http://192.168.47.169/status | awk 'NR==4 {print $6}'
esac

// 修改/usr/local/etc/zabbix_agentd.conf
[root@nginx ~]# vim /usr/local/etc/zabbix_agentd.conf重启agentd端的zabbix服务tatus.sh $1      #在配置文件末尾加上这行

// 重启agentd端的zabbix服务
[root@nginx ~]# pkill zabbix_agentd
[root@nginx ~]# zabbix_agentd 
[root@nginx ~]# ss -antl
State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process 
LISTEN 0      128          0.0.0.0:443        0.0.0.0:*            
LISTEN 0      128          0.0.0.0:10050      0.0.0.0:*            
LISTEN 0      128          0.0.0.0:80         0.0.0.0:*            
LISTEN 0      128          0.0.0.0:22         0.0.0.0:*            
LISTEN 0      128             [::]:22            [::]:*         

// 在zabbix服务器上测试key键值是否有效
[root@zabbix ~]# zabbix_get -s 192.168.47.169 -k check_status[Writing]
 0  

6.14 rewrite

语法:rewrite regex replacement flag;,如:

rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;

此处的$1用于引用(.*.jpg)匹配到的内容,又如:

rewrite ^/bbs/(.*)$ http://www.idfsoft.com/index.html redirect;

如上例所示,replacement可以是某个路径,也可以是某个URL

常见的flag

flag 作用
last 基本上都用这个flag,表示当前的匹配结束,继续下一个匹配,最多匹配10个到20个
一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理
而是由UserAgent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程
break 中止Rewrite,不再继续匹配
一旦此rewrite规则重写完成后,由UserAgent对新的URL重新发起请求,
且不再会被当前location内的任何rewrite规则所检查
redirect 以临时重定向的HTTP状态302返回新的URL
permanent 以永久重定向的HTTP状态301返回新的URL

rewrite模块的作用是用来执行URL重定向。这个机制有利于去掉恶意访问的url,也有利于搜索引擎优化(SEO)

nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:

标识符 意义
^ 必须以^后的实体开头
$ 必须以$前的实体结尾
. 匹配任意字符
[] 匹配指定字符集内的任意字符
[^] 匹配任何不包括在指定字符集内的任意字符串
匹配 之前或之后的实体
() 分组,组成一组用于匹配的实体,通常会有

捕获子表达式,可以捕获放在()之间的任何文本,比如:

^(hello|sir)$       //字符串为“hi sir”捕获的结果:$1=hi$2=sir

//这些被捕获的数据,在后面就可以当变量一样使用了

break示例
break 本条规则匹配完成即终止,不再匹配后面的任何规则

[root@nginx html]# mkdir imgs
[root@nginx html]# ls
50x.html  imgs  index.html  index.php
[root@nginx html]# cd imgs/
[root@nginx imgs]# ls
1.jpg
[root@nginx imgs]# cd
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root html;
 45             index index.html;
 46         }
 47 
 48         location /images{
 49             rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;
 50         }
 51 
[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

浏览器访问测试

redirect示例
redirect 返回302临时重定向,浏览器地址会显示跳转后的URL地址

[root@nginx html]# mkdir imgs
[root@nginx html]# ls
50x.html  imgs  index.html  index.php
[root@nginx html]# cd imgs/
[root@nginx imgs]# ls
1.jpg
[root@nginx imgs]# cd
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
 44             root html;
 45             index index.html;
 46         }
 47 
 48       location /images{
 49           rewrite ^/images/(.*\.jpg)$ 
 50 https://wx2.sinaimg.cn/mw2000/006Xtfudgy1gvsv0dcs7fj3334445e83.jpg redirect;
 51       }
[root@nginx html]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx html]#  nginx -s reload

浏览器访问测试
nginx_第16张图片
last和break组合使用示例

last 本条规则匹配完成后,继续向下匹配新的location URI规则
break 本条规则匹配完成即终止,不再匹配后面的任何规则

示例1

[root@nginx html]# mkdir imgs
[root@nginx html]# ls
50x.html  imgs  index.html  index.php
[root@nginx html]# cd imgs/
[root@nginx imgs]# ls
1.jpg
[root@nginx imgs]# cd
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root html;
 45             index index.html;
 46         }
 47 
 48         location /images {
 49             rewrite ^/images/(.*\.jpg)$ /imgs/$1 last;
 50         }
 51 
 52         location /imgs {
 53             rewrite ^/imgs/(.*\.jpg)$ http://images.baidu.com l    ast;
 54         }
 55     
[root@nginx html]#  nginx -s reload

浏览器访问192.168.47.170/imgs
发现访问到第二条规则的页面

示例2

[root@nginx html]# mkdir imgs
[root@nginx html]# ls
50x.html  imgs  index.html  index.php
[root@nginx html]# cd imgs/
[root@nginx imgs]# ls
1.jpg
[root@nginx imgs]# cd
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
 43         location / {
 44             root html;
 45             index index.html;
 46         }
 47 
 48         location /images {
 49             rewrite ^/images/(.*\.jpg)$ /imgs/$1 break;
 50         }
 51 
 52         location /imgs {
 53             rewrite ^/imgs/(.*\.jpg)$ http://images.baidu.com l    ast;
 54         }
 55     
[root@nginx html]#  nginx -s reload

浏览器访问192.168.47.170/imgs
发现访问到第二条规则的页面

6.15 if

语法:if (condition) {…}

应用场景:

  • server段
  • location段

常见的condition

  • 变量名(变量值为空串,或者以“0”开始,则为false,其它的均为true)
  • 以变量为操作数构成的比较表达式(可使用=,!=类似的比较操作符进行测试)
  • 正则表达式的模式匹配操作

~:区分大小写的模式匹配检查
~:不区分大小写的模式匹配检查
!~和 !~
:对上面两种测试取反

  • 测试指定路径为文件的可能性(-f,!-f)
  • 测试指定路径为目录的可能性(-d,!-d)
  • 测试文件的存在性(-e,!-e)
  • 检查文件是否有执行权限(-x,!-x)

6.15.1 基于浏览器实现分离案例

if ($http_user_agent ~ Firefox) {
  rewrite ^(.*)$ /firefox/$1 break;
}

if ($http_user_agent ~ MSIE) {
  rewrite ^(.*)$ /msie/$1 break;
}

if ($http_user_agent ~ Chrome) {
  rewrite ^(.*)$ /chrome/$1 break;
}

6.15.2 防盗链案例

location ~* \.(jpg|gif|jpeg|png)$ {
  valid_referers none blocked www.idfsoft.com;
  if ($invalid_referer) {
    rewrite ^/ http://www.idfsoft.com/403.html;
  }
}

6.16 反向代理与负载均衡

nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离以及负载均衡,从而大大提高服务器的处理能力。

nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,就直接从nginx发布的路径去读取,而不需要从后台服务器获取了。

但是要注意,这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync做服务端自动同步或者使用NFS、MFS分布式共享存储。

Http Proxy模块,功能很多,最常用的是proxy_pass和proxy_cache

如果要使用proxy_cache,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,如:
./configure --add-module=…/ngx_cache_purge-1.0 …

nginx通过upstream模块来实现简单的负载均衡,upstream需要定义在http段内

在upstream段内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,如:

upstream idfsoft.com {
  ip_hash;
  server 127.0.0.1:9080 weight=5;
  server 127.0.0.1:8080 weight=5;
  server 127.0.0.1:1111;
}

注意:这个方法本质还是轮询,而且由于客户端的ip可能是不断变化的,比如动态ip,代理,等,因此ip_hash并不能完全保证同一个客户端总是由同一个服务器来处理。

定义好upstream后,需要在server段内添加如下内容:

server {
  location / {
    proxy_pass http://idfsoft.com;
  }
}

你可能感兴趣的:(web服务,nginx,服务器,运维)