Nginxの2025教程🔥🔥1.5w字

1,290 阅读46分钟

背景

image.png


前段时间换了一家新的公司,新公司使用的前后端分离部署需要使用nginx没办法只能学习了。

Nginx介绍

Nginx是一款轻量级的Web服务器、反向代理服务器,是由俄罗斯的程序设计师Igor Sysoev所开发,使用C语言开发,由于它的内存占用少,启动速度极快,具有高并发的能力,在互联网项目中被广泛地应用。 它的功能丰富,可作为HTTP服务器,静态资源服务器,也可作为反向代理服务器,邮件服务器等。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。Nginx在全球网站中的市场份额为33.5%,位居第二,仅次于Apache。

Nginx的作用与核心概念

一、作为 Web 服务器

  1. 高效处理静态资源

    • Nginx 能够非常高效地处理如 HTML、CSS、JavaScript、图片(JPEG、PNG 等)等静态文件。例如,对于一个有大量图片和样式文件的网站,Nginx 可以快速地将这些文件发送给客户端浏览器。这是因为它采用了高效的事件驱动的异步非阻塞 I/O 模型,在处理高并发的静态资源请求时,能有效减少每个请求的处理时间,从而提高服务器的整体性能。
    • 相比传统的基于进程或线程的服务器,Nginx 可以在相同的硬件资源下处理更多的静态文件请求。例如,在一个电商网站的促销活动期间,大量用户同时访问商品图片等静态资源,Nginx 可以快速响应这些请求,减少用户等待时间。
  2. 支持简单的动态内容处理(通过模块)

    • 虽然 Nginx 主要用于静态资源服务,但它也可以通过一些模块来处理动态内容。例如,它可以与 FastCGI 协议配合,将 PHP 等动态脚本的请求转发给后端的 PHP - FPM(FastCGI Process Manager)进程来处理。这样就能够在一定程度上实现对动态网页的支持,像常见的基于 WordPress 等内容管理系统构建的网站,Nginx 可以作为前端服务器来处理动态页面请求。

二、作为反向代理服务器

  1. 隐藏后端服务器真实 IP 地址

    • Nginx 作为反向代理服务器,可以将客户端的请求转发到后端真实的服务器,这样客户端看到的只是 Nginx 服务器的 IP 地址,而不是后端服务器的 IP。例如,在一个包含多个 Web 服务器的集群环境中,通过 Nginx 隐藏后端服务器 IP,可以有效避免后端服务器直接暴露在互联网上,从而提高服务器的安全性。
  2. 负载均衡

    • 当有多个后端服务器时,Nginx 可以根据配置的策略将客户端请求均匀地分配到这些后端服务器上。常见的负载均衡策略有轮询(Round - Robin)、加权轮询(Weighted Round - Robin)、IP 哈希(IP - Hash)等。
    • 轮询策略是将请求依次分配到后端服务器。比如有三个后端服务器 A、B、C,第一个请求发送到 A,第二个请求发送到 B,第三个请求发送到 C,以此类推。加权轮询则考虑了后端服务器的性能差异,性能较强的服务器可以分配更多的权重,接收更多的请求。IP 哈希策略是根据客户端的 IP 地址计算出一个哈希值,通过这个哈希值来确定将请求发送到哪一个后端服务器,这样可以保证同一客户端的请求始终被发送到同一后端服务器,适用于有状态服务的场景。
  3. 缓存功能

    • Nginx 可以缓存部分经常访问的内容,当有相同的请求再次到来时,直接从缓存中获取数据,而不需要向后端服务器请求,从而减轻后端服务器的压力。例如,对于一些更新频率较低的网页内容,如公司的介绍页面,Nginx 可以缓存这些页面内容。当有用户访问该页面时,Nginx 直接从缓存中返回页面,减少了后端服务器的处理工作量和响应时间。

三、作为邮件代理服务器(IMAP/POP3)

  1. 邮件协议代理
    • Nginx 可以作为邮件代理服务器,用于处理 IMAP(Internet Message Access Protocol)和 POP3(Post Office Protocol 3)协议的请求。它可以接收来自客户端的邮件访问请求,然后将这些请求转发到后端的邮件服务器进行处理。例如,在一个企业邮件系统中,Nginx 可以作为前端代理,对邮件客户端的访问请求进行过滤和转发,提高邮件系统的安全性和性能。

什么是代理呢?

代理,简单来说,就像是一个 “中间人”。 比如说,你想从一个商店买东西,但你不想直接和商店打交道。这时候,你找了一个朋友,让这个朋友去商店帮你买。这个朋友就是 “代理”。 在网络世界里,如果你想访问一个网站,正常情况下,你的电脑会直接向网站的服务器发送请求。但是如果使用代理,你的请求会先发送给代理服务器。代理服务器收到你的请求后,它会代替你去访问网站的服务器,然后把从网站服务器得到的内容再返回给你。

正向代理

这就好比你为了访问某些国外的网站,或者是为了隐藏自己的真实 IP 地址,你通过代理服务器去访问这些网站。对于网站服务器来说,它看到的是代理服务器的 IP 地址,而不是你的真实 IP 地址这样就很安全。

这里的 VPN 就是做正向代理的。正向代理服务器位于客户端和服务器之间,为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里客户端是要进行一些正向代理的设置的。

image.png

反向代理

反向代理,对比正向代理来说其实就是反过来了,正向代理是隐藏用户的信息,而反向代理是隐藏真实的服务器信息。

反向代理和正向代理的区别就是:正向代理代理的是客户端,反向代理代理的是服务器。

image.png

动静分离

介绍

  • 动静分离是一种优化网站性能的架构策略。在一个 Web 应用中,“动” 的部分通常是指动态生成的内容,如通过服务器端脚本(如 PHP、Python(Flask、Django)等)根据用户请求、数据库数据等来生成的网页内容。而 “静” 的部分主要是指那些不需要服务器动态生成的资源,像图片、CSS 样式文件、JavaScript 脚本文件等。
  • 动静分离的主要目的是通过将动态请求和静态请求分开处理,充分利用服务器的性能,减少服务器的负载,同时提高用户访问的响应速度。例如,静态资源可以通过专门的服务器(如 Nginx)进行缓存和快速分发,而动态请求则由应用服务器(如 Tomcat、uWSGI 等)进行处理。

动静分离的好处

  • 性能提升

    • 对于静态资源,Nginx 可以高效地提供服务。因为 Nginx 在处理静态文件时,不需要像应用服务器那样进行复杂的动态内容生成过程,如数据库查询、模板渲染等。它可以直接从磁盘或者内存缓存中读取静态资源并返回给客户端,从而大大提高了响应速度。
  • 减轻应用服务器负担

    • 应用服务器主要负责处理动态请求,如业务逻辑运算、数据库操作等复杂任务。通过动静分离,将静态资源请求从应用服务器的负载中移除,使应用服务器能够更专注于处理核心的动态业务,避免了因为大量静态资源请求占用资源而导致的性能下降。
  • 便于缓存管理

    • 可以在 Nginx 端对静态资源设置不同的缓存策略。例如,对于不经常变化的 CSS 和 JavaScript 文件,可以设置较长的缓存时间;而对于可能会经常更新的图片(如用户上传的头像等),可以设置相对较短的缓存时间。这样可以灵活地控制资源的缓存和更新,提高资源的利用效率。

Nginx的工作模式

nginx 有两种工作模式:master-worker 模式和单进程模式

在 master-worker 模式下:有一个 master 进程和至少一个的 worker 进程

单进程模式:顾名思义只有一个进程

这两种模式有各自的特点和适用场景

master-worker模式

master-worker:该模式下,nginx 启动成功后,会有一个 master 进程和至少一个的 worker 进程。 master '进程负责处理系统信号(control)',加载配置,管理 worker 进程(启动、杀死、监控、发送消息/信号等)。 worker '进程负责处理具体的业务逻辑',也就是说,对外部来说,真正提供服务的是 worker 进程

  1. 稳定性高,只要还有 worker 进程存活,就能够提供服务,并且一个 worker 进程挂掉 master 进程会立即启动一个新的 worker 进程,保证 worker 进程数量不变,降低服务中断的概率。
  2. 配合 linux 的 cpu 亲和性配置,可以充分利用'多核 cpu 的优势',提升性能
  3. 处理信号/配置重新加载/升级时可以做到尽可能少或者不中断服务(热重启-->不中断服务)!

单进程模式(了解)

单进程模式下,nginx启动后'只有一个进程','nginx 的所有工作都由这个进程负责'.由于只有一个进程, 因此可以很方便地利用 gdb 等工具进行调试。该模式'不支持 nginx 的平滑升级功能',任何的信号处理 都可能造成服务中断,并且由于是单进程,进程挂掉后,在没有外部监控的情况下,无法重启服务。 因此,该模式一般只在开发阶段和调试时使用,生产环境下不会使用'(了解)'.

Nginx的下载与安装

nginx官网

window安装

  1. 登录 nginx 官网 点击右侧downLoad image.png

  2. 找个稳定版本下载就行(按照实际需要去下载指定版本) 我这里下的是1.26.2 image.png

  3. 下载后解压安装

image.png

image.png 如何判断是否安装成功 Cmd 进入nginx同级目录输入

image.png 注意:回车确认是会出现一闪,这是正常现象: 查看任务进程是否存在,dos或打开任务管理器都行

  1. 最后一步是打开我们的浏览器访问刚才的域名及端口,nginx默认http://localhost:80或127.0.0.1:80,默认端口号是80,出现Welcome to nginx!就说明部署成功了!

image.png

Ubuntu安装

  • 步骤一:更新软件包索引

     在 Ubuntu 系统中,软件包的安装和管理主要通过`apt-get`工具完成。在安装 Nginx 之前,首先要更新软件包索引,这样可以确保获取到最新版本的 Nginx 以及它所依赖的软件包。打开终端(可以通过快捷键`Ctrl + Alt + T`),输入以下命令:
    
          `sudo apt-get update`
           这个命令会从 Ubuntu 软件源服务器获取最新的软件包列表信息。`sudo`是用于以管理员(root)权限运行命令,因为更新软件包索引需要管理员权限。
    
  • 步骤二:安装 Nginx

     更新完软件包索引后,就可以安装 Nginx 了。在终端中输入以下命令:
    
         `sudo apt-get install nginx`
         这个命令会自动下载 Nginx 软件包以及它所依赖的其他软件包,并进行安装。在安装过程中,系统可能会提示你输入管理员密码,以确认安装操作。
    
  • 步骤三:验证安装是否成功

    方法一:查看 Nginx 服务状态

      -   安装完成后,可以使用以下命令来查看 Nginx 服务的状态:
    
          -   `sudo service nginx status`
          -   如果 Nginx 安装成功并且正在运行,你会看到类似 “active (running)” 的状态信息。如果显示 “inactive (dead)”,则可能是安装过程出现了问题,或者 Nginx 没有正常启动。
    

    方法二:通过浏览器访问

      -   打开浏览器,在地址栏中输入服务器的 IP 地址(如果是在本地测试,也可以输入`localhost`)。如果看到 Nginx 的默认欢迎页面(通常是 “Welcome to nginx!”),就说明 Nginx 安装成功了。
    

Nginx命令

image.png nginx -h 显示 NGINX 帮助菜单

配置环境变量与bat命令

前面服务虽然启动成功了但是只能去nginx.exe同级目录去学习很不方便,这里需要配置一下环境变了

环境变量配置

  1. Win+r 打开命令行窗口输入sysdm.cpl
  2. 点击环境变量配置

image.png 3. 在系统环境变了/用户环境变量里面选择一个进行新建

image.png image.png

4.在选择的系统/用户环境变量里找到path进行编辑

image.png 5. 新建一个名为 %NGINX_HOME%这个是与前面编辑系统变量的变量名称保持一致 image.png

  1. CMD输入NGINX出现这个错误就代表环境变量配置成功了 image.png

bat命令配置

前面报错信息主要是因为nginx 找不到配置文件,因此可以去nginx的安装目录去启动

image.png

image.png 这个8520端口的html已经展示出来了但是这样每次都需要命令启动有点不舒服所以这里可以bat写好命令在启动。

注意:nginx默认读取启动目录下的conf/nginx.conf文件,这个可能不同版本不一致。

启动命令

在文件夹中创建start.bat

@echo off
@title nginx service start ...
@title starting nginx service ...

start nginx

start "" "http://localhost:8520"
pause

注意前面提到过ngixn 启动时候读取的是同级目录下的conf/nginx.conf文件 这里的bat必须创建在conf的同级 然后这个文件直接双击就启动了这样会自动打开网址

关闭命令

在文件夹中创建shutdown.bat

@echo off
@title ngix service stop...
nginx -s stop
pause

同样也是双击关闭nginx服务

nginx 的变量与全局变量

变量名描述
$arg_PARAMETERGET请求中变量名PARAMETER参数的值。
$args这个变量等于GET请求中的参数。例如,foo=123&bar=blahblah;这个变量只可以被修改
$binary_remote_addr二进制码形式的客户端地址。
$body_bytes_sent传送页面的字节数
$content_length请求头中的Content-length字段。
$content_type请求头中的Content-Type字段。
$cookie_COOKIEcookie COOKIE的值。
$document_root当前请求在root指令中指定的值。
$document_uri与$uri相同。
$host请求中的主机头(Host)字段,如果请求中的主机头不可用或者空,则为处理请求的server名称(处理请求的server的server_name指令的值)。值为小写,不包含端口。
$hostname机器名使用 gethostname系统调用的值
$http_HEADERHTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写,-变为_(破折号变为下划线),例如:$http_user_agent(Uaer-Agent的值);
$sent_http_HEADERHTTP响应头中的内容,HEADER为HTTP响应中的内容转为小写,-变为_(破折号变为下划线),例如: senthttpcachecontrol,sent_http_cache_control, sent_http_content_type…;
$is_args如果$args设置,值为"?",否则为""。
$limit_rate这个变量可以限制连接速率。
$nginx_version当前运行的nginx版本号。
$query_string与$args相同。
$remote_addr客户端的IP地址。
$remote_port客户端的端口。
$remote_user已经经过Auth Basic Module验证的用户名。
$request_filename当前连接请求的文件路径,由root或alias指令与URI请求生成。
$request_body这个变量(0.7.58+)包含请求的主要信息。在使用proxy_pass或fastcgi_pass指令的location中比较有意义。
$request_body_file客户端请求主体信息的临时文件名。
$request_completion如果请求成功,设为"OK";如果请求未完成或者不是一系列请求中最后一部分则设为空。
$request_method这个变量是客户端请求的动作,通常为GET或POST。包括0.8.20及之前的版本中,这个变量总为main request中的动作,如果当前请求是一个子请求,并不使用这个当前请求的动作。
$request_uri这个变量等于包含一些客户端请求参数的原始URI,它无法修改,请查看$uri更改或重写URI。
$scheme所用的协议,比如http或者是https,比如rewrite ^(.+) scheme://example.com$1 redirect;
$server_addr服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在listen中指定地址并且使用bind参数。
$server_name服务器名称。
$server_port请求到达服务器的端口号。
$server_protocol请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$uri请求中的当前URI(不带请求参数,参数位于a r g s ) , 不 同 于 浏 览 器 传 递 的 args),不同于浏览器传递的args),不同于浏览器传递的request_uri的值,它可以通过内部重定向,或者使用index指令进行修改。不包括协议和主机名,例如/foo/bar.html

自定义变量

可以在sever,http,location等标签中使用set命令(非唯一)声明变量,语法如下

set $变量名 变量值

注意nginx中的变量必须都以$开头。

使用变量

location a/ { 
 return 200 $a 
}

Nginx的模块化

语法 include file;

该指令主要用于将其他的Nginx配置或者第三方模块的配置引用到当前的主配置文件中

Nginx 当配置很多时候很不好管理 这里可以使用include导入其它配置 image.png

include 指令中只包含一个参数,它可以是文件的路径或是与许多文件匹配的掩码。该 指令在任何上下文中都有效。

Nginx配置文件结构与模块配置

nginx目录说明

 1 nginx/
 3 |-- client_body_temp
 4 |-- conf                               #这是Nginx所有配置文件的目录,极其重要
 5 |   |-- fastcgi.conf                    'fastcgi相关参数的配置文件'
 6 |   |-- fastcgi.conf.default               #fastcgi.conf的原始备份
 7 |   |-- fastcgi_params                   #fastcgi的参数文件
 8 |   |-- fastcgi_params.default
 9 |   |-- koi-utf
10 |   |-- koi-win
11 |   |-- mime.types                     '媒体类型'
12 |   |-- mime.types.default
13 |   |-- nginx.conf                     '这是nginx默认的主配置文件'
14 |   |-- nginx.conf.default                      #default结尾的都是备份文件
15 |   |-- scgi_params                    #scgi相关参数文件,一般用不到
16 |   |-- scgi_params.default
17 |   |-- uwsgi_params                       #uwsgi相关参数文件,一般用不到
18 |   |-- uwsgi_params.default
19 |   `-- win-utf
20 |-- fastcgi_temp                         #fastcgi临时数据目录
21 |-- html                          这是编译安装时'nginx的默认站点目录',类似Apache的默认站点/var/www/html目录
23 |   |--50x.html                                 #错误页面优雅替代显示文件,例如:出现502错误时会调用此页面
24                                                 #error_page   500502503504  /50x.html;
25 |   `-- index.html                              #默认的首页文件,首页文件名字是在nginx.conf中事先定义好的。
26 |-- logs                                        这是'nginx默认的日志路径',包括错误日志及访问日志
27 |   |-- access.log                              这是nginx的默认'访问日志文件',使用tail -f access.log,可以实时观看网站用户访问情况信息
28 |   |-- error.log                               这是nginx的'错误日志文件',如果nginx出现启动故障等问题,一定要看看这个错误日志
29 |   `-- nginx.pid                               'nginx的pid文件',Nginx进程启动后,会把所有进程的ID号写到此文件
30 |-- proxy_temp                                  #临时目录
31 |-- sbin                                        这是'nginx命令的目录',如Nginx的启动命令nginx
32 |   `-- nginx                                   #Nginx的启动命令nginx
33 |-- scgi_temp                                   #临时目录
34 `-- uwsgi_temp                                  #临时目录

nginx config配置文件说明

main        # 全局配置,对全局生效
|-- events  # 配置Nginx服务器与客户端的网络连接相关指令。例如每个worker进程可以同时支持的最大连接数
|-- http    # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
│   |-- upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
│   |-- server   # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
│   |-- server
│   │   |-- location  # server 块可以包含多个 location 块,location 指令用于匹配 uri
│   │   |-- location
│   │   |-- ...
│   |-- ...
|-- ...

如上述配置文件所示,主要由6个部分组成:

1、main:用于进行nginx全局信息的配置

2、events:用于nginx工作模式的配置

3、http:用于进行http协议信息的一些配置

4、server:用于进行服务器访问信息的配置

5、location:用于进行访问路由的配置

6、upstream:用于进行负载均衡的配置 一个 Nginx 配置文件的结构就像 nginx.conf 显示的那样,配置文件的语法规则:


nginx 配置语法规则

配置文件由指令与指令块构成;
每条指令以 ; 分号结尾,指令与参数间以空格符号分隔;
指令块以 {} 大括号将多条指令组织在一起;
include 语句允许组合多个配置文件以提升可维护性;
使用 # 符号添加注释,提高可读性;
使用 $ 符号使用变量;
部分指令的参数支持正则表达式;

main模块

main块也就是全局块,主要设置一些影响nginx服务器整体运行的配置指令。例如:worker进程数量,master进程pid存放位置等

user用来指定nginx worker进程运行用户以及用户组,默认nobody账号运行

worker_processes指定nginx要开启的子进程数量,运行过程中监控每个进程消耗内存(一般几M~几十M不等)根据实际情况进行调整,通常数量是CPU内核数量的整数倍

error_log定义错误日志文件的位置及输出级别debug / info / notice / warn / error / crit

pid用来指定进程id的存储文件的位置

worker_rlimit_nofile用于指定一个进程可以打开最多文件数量的描述

配置是否以守护进程方式运行nginx

守护进程是指在Linux操作系统中,以独立于控制终端的方式运行的后台服务进程。这种进程通常用于执行长期运行的任务或提供系统级的服务。

  • 守护进程的特点:

    • 脱离终端:守护进程不会依赖于任何用户交互界面,如命令行窗口或图形界面。
    • 持久性:它们通常从系统启动时开始运行,并持续到系统关闭。
    • 独立性:这些进程不受父进程或控制终端的影响,即使父进程结束或终端关闭,守护进程仍会继续运行。
    • 非交互性:守护进程通常不与用户直接交互,而是通过配置文件接收指令或通过网络接口提供服务。
  • 在Nginx中的应用:

    • Nginx可以通过设置daemon on;来启用守护进程模式。这意味着Nginx将以守护进程的形式运行,即它将作为一个独立的后台进程,不受用户登录状态的影响。
    • 设置worker_processes number | auto可以指定工作进程的数量,这有助于优化性能和资源利用。
    • 使用pid file配置项可以指定主进程PID文件的位置,这对于监控和管理Nginx进程非常重要。

通过这种方式,Nginx能够以高效且稳定的方式提供Web服务,而不需要用户的持续干预。 语法

作用域:main
语法:daemon on 开| off 关
默认值daemon on;

配置工作进程的数量

作用域:main
语法:worker_processes number | auto
默认值worker_processes 1;

worker_ processes的值通常不会大于服务器中cpu的核心数量,
换句话说就是,worker进程的数通常与服务器有多少
cpu核心有关。

比如,nginx所在主机拥有4核cpu,那么worker_ processes的值通常不会大于4,这样做的原因是为了尽力让每个worker进程都有一个cpu可以使用,尽量避免了多个worker进程抢占同一个cpu的情况,我们也可以将worker_ processes的值设置为"auto"

配置主进程pid存放位置

作用域:main
语法:pid file
默认值pid logs/nginx.pid

PID全称是Process Identification。
PID是进程的代号,每个进程有唯一的PID编号。它是进程运行时系统随机分配的,并不代表专门的进程。在运行时PID是不会改变标识符的,但是你终止程序后再运行PID标识符就会被系统回收,就可能会被继续分配给新运行的程序。

event模块

events块主要配置Nginx服务器与客户端的网络连接相关指令。例如每个worker进程可以同时支持的最大连接数。

worker_connections 指定最大可以同时接收的连接数量,这里一定要注意,最大连接数量是和worker processes共同决定的。

multi_accept 配置指定nginx在收到一个新连接通知后尽可能多的接受更多的连接
use epoll 配置指定了线程轮询的方法,如果是linux2.6+,使用epoll,如果是BSD如Mac请使Kqueue

配置有新连接时工作进程的唤醒方式

作用域:events
语法:accept_mutex on | off
默认值accept_mutex off;
作用:如果启用accept_mutex,有新连接时,工作进程将依次接受。否则,所有工作进程将被通知,如果新连接的数量低,就会造成工作进程资源浪费。

这里有一个“惊群”的问题,大致意思是:在某一时刻只接收到一个新的网络连接,多个睡眠的进程会被同时唤醒,但只有一个进程可以获得连接,这就回造成一部分系统资源的浪费。在Nginx服务中,如果存在多个工作进程,就有可能出现“惊群”问题。

配置是否允许同时接收多个连接

作用域:events
语法:multi_accept on | off
默认值multi_accept off;
作用:如果禁用multi_accept,工作进程将一次接受一个新连接。否则,工作进程将一次接受所有新连接。

配置每个工作进程最大连接数

作用域:events
语法:worker_connections number
默认值worker_connections 512;
作用:设置工作进程可以同时打开的最大连接数。

# 配置以守护进程方式运行
daemon on;
# 配置工作进程数量
worker_processess 2;
# 配置主进程pid存放位置
pid logs/nginx.pid;

events {
    # 配置有新连接时,唤醒工作进程的方式
    accept_mutex on;
    # 配置每个工作进程是否可以同时接收连接
    multi_accept on;
    # 配置每个工作进程的最大连接数
    worker_connections 1024;
}

http模块

http块是Nginx服务器配置中的重要部分,代理、缓存、第三方模块的配置都放在这个模块。http块中可以包含多个server块,server块也可以包含多个location块。

注意:很多的配置指令可以同时存在于http,server,location块中,如果同时配置,生效的原则为就近原则

配置mime-type

作用域:http,server,location
语法:default_type mime-type
默认值default_type text/plain;
作用:定义响应的mime类型
在浏览器中,可以显示文本,图片等资源,浏览器为了区分这些资源,需要使用mime-type(网络资源的媒体类型)。Nginx作为web服务器,也需要识别客户端请求的资源类型。因此,Nginx定义了mime.types文件,其中定义了很多的资源类型。我们在定义default_type时,参照这个文件配置即可。

cd /usr/local/nginx
cat mime.types
# 输出内容,省略绝大部分
types {
    text/html                                        html htm shtml;
    text/css                                         css;
    text/xml                                         xml;
    image/gif                                        gif;
    image/jpeg                                       jpeg jpg;
    application/json                                 json;
    application/octet-stream                         bin exe dll;
    application/octet-stream                         deb;
    application/octet-stream                         dmg;
    application/octet-stream                         iso img;
    application/octet-stream                         msi msp msm;
    ......
}

配置错误页面

作用域:http,server,location,if in location
语法:error_page code ... [=[response]] uri;
作用:定义错误对应的响应

events {
    worker_connections  1024;
}

http {    
    server {# 服务器主机配置     
        listen 8520; #监听端口
        server_name localhost; #服务器名称   
        # proxy_intercept_errors on;

        location / {                    
            root html; #指定静态资源根目录
            index index.html; #指默认首页
        }
         # 定义错误页面码,如果出现相应的错误页面码,转发到那里。
        error_page  404 /404.html;  
        # 承接上面的location。                    
        location = /404.html {
        # 放错误页面的目录路径。当然默认可以在网站目录下,也可以定义放置错误页面的位置。
            root html;
        }
    }
}

文件目录如下

image.png

配置每个连接的最大请求数

作用域:http,server,location
语法:keepalive_requests number
默认值keepalive_requests 1000;
作用:设置一个连接能提供服务的最大请求数。在发出最大数量的请求后,连接将关闭。定期关闭连接有利于内存的释放。

配置每个连接处理请求的最长时间

作用域:http,server,location
语法:keepalive_time time
默认值keepalive_time 1h;
作用:设置一个连接处理请求的最长时间。到达该时间后,连接将在随后的请求处理之后关闭。

配置连接超时时间

作用域:http,server,location
语法:keepalive_timeout timeout [header_timeout]
默认值keepalive_timeout 75s;
作用:设置长连接的超时时间,在此期间,连接将保持打开状态。零值将禁用长连接

配置文件高效传输模式

作用域:http,server,location,if in location
语法:sendfile on | off
默认值sendfile off;
作用:如果开启此选项,可以提升文件传输的速度

包含其他文件

作用域:any
语法:include file
示例include mime.types;
作用:将另一个文件包含到配置中

# 配置以守护进程方式运行
daemon on;
# 配置工作进程数量
worker_processess 2;
# 配置主进程pid存放位置
pid logs/nginx.pid;
​
events {
    # 配置有新连接时,唤醒工作进程的方式
    accept_mutex on;
    # 配置每个工作进程是否可以同时接收连接
    multi_accept on;
    # 配置每个工作进程的最大连接数
    worker_connections 1024;
}
​
http {
    # 配置引入资源的媒体类型文件
    include mime.types;
    # 配置默认的响应类型
    default_type text/plain;
    # 配置每个连接能处理的最大请求数
    keepalive_requests 1000;
    # 配置每个连接处理请求的最长时间
    keepalive_time 1h;
    # 配置每个连接的超时时间
    keepalive_timeout 75s;
    # 配置开启文件高效传输模式
    sendfile on;
}

server模块

server块包含在http块中,在server块里,我们可以配置虚拟主机,虚拟主机技术将一台服务器划分为多个服务单位,对外表现为多个服务器,从而充分利用服务器硬件资源。这和可以http块中定义多个server块契合。

server:一个虚拟主机的配置,一个http中可以配置多个server

server_name:用来指定ip地址或者域名,多个配置之间用空格分隔

root:表示整个server虚拟主机内的根目录,所有当前主机中web项目的根目录,可以用来做静态服务器

index:用户访问web网站时的全局首页

charset:用于设置www/路径中配置的网页的默认编码格式

access_log:用于指定该虚拟主机服务器中的访问记录日志存放路径

error_log:用于指定该虚拟主机服务器中访问错误日志的存放路径

配置网络监听端口

listen指令的配置相对复杂,我们这里只看最简单且常用的一种方式:listen port

在nginx中有个概念:default_serer,如果没有显式指定,则配置文件中定义的第一个server为默认server

作用域:server
语法listen 8080
作用:监听指定端口上的所有的连接

配置虚拟主机的名称

作用域:server
语法:server_name name ...
默认值:server_name ""
作用:设置虚拟主机的名称 erver_name的语法看上去比较简单,支持同时配置多个名称,第一个为主名称。

Nginx为我们提供了多种配置形式:使用具体名称使用通配符以及使用正则表达式

使用具体名称

server_name myserver.com www.server.com;

使用通配符

可以使用*替换名称的开头部分和结尾部分。

server_name *.myserver.com www.myserver.*;

使用正则表达式

使用正则表达式,在Nginx中使用正则表达式需要以~开头。

server_name ~^www.\d+.com$;

该正则表达式的含义是:以www开头,紧跟..在正则表达式中有特殊含义,因此需要使用转义)再紧跟一个或多个0-9的数字(`\d`代表0-9的任意一个数字,`+`代表其前面的字符出现一次或多次),再紧跟.com

示例:www.4399.com

既然可以通过多种形式来配置server_name,因此在包含多个虚拟主机的配置中,可能会出现一个请求被多个虚拟主机的server_name匹配成功,Nginx做了规定,按照以下优先级匹配虚拟主机:

1)完全匹配server_name成功
2)通配符在开头部分时匹配server_name成功
3)通配符在结尾部分时匹配server_name成功
4)第一个正则表达式匹配server_name成功

注意: 如果server_name被处于同一优先级的匹配方式多次匹配成功,则首次匹配成功的虚拟主机处理请求。

location模块

location模块是nginx配置中出现最多的一个配置,主要用于配置路由访问信息 在路由访问信息配置中关联到反向代理、负载均衡等等各项功能。 location /:表示匹配访问根目录
root:用于指定访问根目录时,访问虚拟主机的web目录
index:在不指定访问具体资源时,默认展示的资源文件列表

作用域:server,location
语法:location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
作用:对请求的URI进行匹配

同样的location的配置也存在多种方式:

匹配规则:

  1. 先使用不含正则表达式的location进行匹配,找到匹配度最高的一个
  2. 再通过包含正则表达式的配置进行匹配,如果能匹配到则停止向下匹配并立即处理请求,否则使用第一步的匹配度最高的location来处理请求。

精准匹配,如果匹配成功,则停止向下匹配并立即处理请求

# 精准匹配
location = /test {
	...
}

匹配以/test开头

# 匹配以/test开头的URI
location /test {
	...
}

匹配以/test开头,如果匹配成功,则停止向下匹配并立即处理请求

# 匹配以/test开头的URI,如果匹配成功,则停止向下匹配并立即处理请求
location ^~ /test {
	...
}

正则匹配,区分大小写

# 匹配以/test开头的URI,区分大小写
location ~ /test {
	...
}

正则匹配,不区分大小写

# 匹配以/test开头的URI,不区分大小写
location ~* /test {
	...
}
  • =:精确匹配。如果匹配成功,立即停止搜索并处理此请求。

  • ~:执行正则匹配,区分大小写。

  • ~*:执行正则匹配,不区分大小写。

  • !~:正则匹配,区分大小写不匹配。

  • !~*:正则匹配,不区分大小写不匹配。

  • ^~:前缀匹配。如果匹配成功,不再匹配其他location,且不查询正则表达式。

  • @:指定命名的location,主要用于内部重定向请求,如 error_pagetry_files

  • uri:待匹配的请求字符串。可以是普通字符串或包含正则表达式。

注意优先级顺序:无特定标识 < ^~ < = < 正则匹配 (~~*!~!~*)

alias别名

如果你的静态文件不在项目的主目录下,你可以使用alias来指定静态文件的实际路径。

  • 确保你的静态文件路径配置正确,避免404错误。

  • 使用expires指令为静态内容设置缓存,这可以减少服务器的负载并提高页面加载速度。

  • 动静分离不仅可以提高服务器的响应速度,还可以减少后端服务器的压力,因为静态文件通常由Nginx直接处理,而不需要代理到后端服务器。

反向代理配置方式

通过反向代理代理服务器访问模式,通过proxy_set配置让客户端访问透明化 这个对于前端用处很大,比如webpack的反向代理配置

location /static/ {
    alias /path/to/static/files/;
}

在这个配置中,URL中的/static/会映射到文件系统的/path/to/static/files/

image.png

作用域:location
语法:proxy_pass 主机地址
作用:进行反向代理

events {
    worker_connections  1024;
}


http {    
    server {# 服务器主机配置     
        listen 8520; #监听端口
        server_name localhost; #服务器名称   
        # proxy_intercept_errors on;

        location / {                    
            root html; #指定静态资源根目录
            index index.html; #指默认首页
            proxy_pass https://www.bilibili.com/;
        }
         # 定义错误页面码,如果出现相应的错误页面码,转发到那里。
        error_page  404 /404.html;  
        # 承接上面的location。                    
        location = /404.html {
        # 放错误页面的目录路径。当然默认可以在网站目录下,也可以定义放置错误页面的位置。
            root html;
        }
    }
}

这样打开就会进入哔哩哔哩

gzip

gzip 是一种文件压缩格式和相关的压缩工具。它通过使用无损数据压缩算法,把文件(如文本文件、HTML 文件、CSS 文件、JavaScript 文件等)进行压缩,以减小文件的大小。这样在网络传输或者存储时,可以节省带宽和存储空间。

gzip网页检测工具 网页Gzip压缩检测_在线网站Gzip压缩检测工具 - 站长工具网

Nginx 配置 gzip

  1. 请求阶段

    • 浏览器在向服务器发起请求时,会在请求头(Request Header)中通过Accept - Encoding字段表明自己支持的压缩格式。例如,浏览器可能会发送Accept - Encoding: gzip, deflate,这表示浏览器支持 gzip 和 deflate 两种压缩格式。
    • 当请求到达配置了 gzip 的 Nginx 服务器时,Nginx 会检查请求头中的Accept - Encoding字段,以确定浏览器是否支持 gzip 压缩。
  2. 响应阶段

    • 如果浏览器支持 gzip 压缩,并且 Nginx 服务器已经配置好 gzip(如gzip on;开启了 gzip 功能),Nginx 会对符合条件(如文件类型、文件大小等满足配置要求)的响应内容进行 gzip 压缩。
    • Nginx 在发送响应时,会在响应头(Response Header)中添加Content - Encoding: gzip字段,告知浏览器发送的内容是经过 gzip 压缩的。同时,响应头还会包含其他相关信息,如Content - Length(压缩后的内容长度)等。
    • 浏览器收到带有Content - Encoding: gzip的响应后,会知道内容是经过压缩的。浏览器会使用自己内置的解压功能对收到的 gzip 压缩内容进行解压,然后按照正常的方式解析和显示网页内容(如 HTML、CSS、JavaScript 文件等)。
  3. 缓存相关的交互(如果有缓存)

    • 当涉及缓存时,情况会稍微复杂一些。Nginx 可能会根据配置和请求头中的相关信息(如Cache - ControlVary等字段)来决定是否缓存内容。
    • 如果配置了gzip_vary on;,Nginx 会在响应头中添加Vary: Accept - Encoding。这对于缓存服务器(如代理服务器)很重要,因为它表示缓存的内容是根据浏览器的Accept - Encoding字段而变化的。例如,对于一个不支持 gzip 的浏览器和一个支持 gzip 的浏览器,代理服务器需要分别缓存未压缩和压缩后的内容。
    • 当浏览器再次请求相同的资源时,如果缓存有效(如Cache - Control允许且资源未过期),缓存服务器会直接返回缓存中的内容,而不是再次向 Nginx 服务器请求。如果缓存无效,会重新发起请求,整个交互过程又会从请求阶段开始。

events {
    worker_connections  1024;
}
http {    
    gzip on; # 默认off,是否开启gzip
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    gzip_static on;
    gzip_proxied any;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    # gzip_min_length 1k;
    gzip_http_version 1.1;

    server {# 服务器主机配置     
        listen 8520; #监听端口
        server_name localhost; #服务器名称   
        # proxy_intercept_errors on;

        location / {                    
            root html; #指定静态资源根目录
            index index.html; #指默认首页
            proxy_pass https://www.bilibili.com/;
        }
        error_page  404 /404.html;# 定义错误页面码,如果出现相应的错误页面码,转发到那里。
        location = /404.html {# 承接上面的location。       
            root html;        # 放错误页面的目录路径。当然默认可以在网站目录下,也可以定义放置错误页面的位置。
        }
    }
}
  1. gzip_types:要采用 gzip 压缩的 MIME 文件类型,其中 text/html 被系统强制启用;
  • 语法:gzip_types mime-type
  • 默认值:gzip_types text/html
  • 配置位置:http块,server块,location块
  • 示例:gzip_types application/javascript
  1. gzip_static:默认 off,该模块启用后,Nginx 首先检查是否存在请求静态文件的 gz 结尾的文件,如果有则直接返回该 .gz 文件内容;

  2. gzip_proxied:默认 off,nginx做为反向代理时启用,用于设置启用或禁用从代理服务器上收到相应内容 gzip 压缩;

  • 语法:gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any

  • 默认值:gzip_proxied off

  • 配置位置:http块,server块, location块

  1. gzip_vary:用于在响应消息头中添加 Vary:Accept-Encoding,使代理服务器根据请求头中的 Accept-Encoding 识别是否启用 gzip 压缩;
  • 语法:gzip_vary on|off
  • 默认值:gzip_vary off
  • 配置位置:http块,server块,location块
  1. gzip_comp_level:gzip 压缩比,压缩级别是 1-9,1 压缩级别最低,9 最高,级别越高压缩率越大,压缩时间越长,建议 4-6;
  • 语法:gzip_comp_level level
  • 默认值:gzip_comp_level 1
  • 配置位置:http块,server块,location块
  1. gzip_buffers:获取多少内存用于缓存压缩结果,16 8k 表示以 8k*16 为单位获得;
  • 语法:gzip buffers number size
  • 默认值:gzip_buffer 32 4k | 16 8K
  • 配置位置:http块,server块,location块
  1. gzip_min_length:允许压缩的页面最小字节数,页面字节数从header头中的 Content-Length 中进行获取。默认值是 0,不管页面多大都压缩。建议设置成大于 1k 的字节数,小于 1k 可能会越压越大;
  • 语法:gzip_min_length length
  • 默认值:gzip_min_length 20
  • 配置位置:http块,server块, location块
  1. gzip_http_version:默认 1.1,启用 gzip 所需的 HTTP 最低版本;
  • 语法:gzip_http_version 1.0 | 1.1
  • 默认值:gzip_http_version 1.1
  • 配置位置:http块,server块,location块
  1. gzip_disable

选择性地开启和关闭gzip功能,基于客户端的浏览器标志。

  • 语法:gzip_disable regex
  • 默认值:gzip_disable -
  • 配置位置:http块,server块,location块
  • 示例:gzip_disable "MSIE [1-6]."

这个配置可以插入到 http 模块整个服务器的配置里,也可以插入到需要使用的虚拟主机的 server 或者下面的 location 模块中,当然像上面我们这样写的话就是被 include 到 http 模块中了。

其他更全的配置信息可以查看 <官网文档ngx_http_gzip_module>, 注意了,一般 gzip 的配置建议加上 gzip_min_length 1k,不加的话可能文件会被压缩的更大

Webpack 的 gzip 配置

  • npm install compression-webpack-plugin --save - dev
const CompressionWebpackPlugin = require('compression-webpack-plugin')

module.exports = {
  // 其他配置项...
  plugins: [
    new CompressionPlugin({
      test: /.(js|css|html)$/, // 要压缩的文件类型,可以根据实际需求修改
      threshold: 10240, // 只有大于这个大小(单位是字节)的文件才会被压缩,这里是10KB
      minRatio: 0.8 // 压缩后的文件大小与原文件大小的比率,小于这个比率才会被存储
    })
  ]
};

通常都不在nginx 配置gzip 而是 直接前端打包时候直接打成gzip

构建工具gzip 和nginx gzip区别

压缩阶段
Webpack gzip:在前端构建的时候就进行压缩,是构建流程的一部分。
Nginx gzip:在服务器收到浏览器请求,要返回文件时才压缩。

配置方式
Webpack gzip:在 Webpack 配置文件中,通过安装插件并配置参数来实现,和前端构建紧密相关。 Nginx gzip:在 Nginx 配置文件里,用特定指令来设置,和服务器运维联系紧密。

适用场景
Webpack gzip:适合在构建阶段就处理好压缩文件,减少服务器计算压力,对前端项目细节优化较好。 Nginx gzip:适合在服务器端统一处理不同来源请求,方便根据服务器情况动态调整。

配置负载均衡

负载均衡在之前已经介绍了相关概念了,主要思想就是把负载均匀合理地分发到多个服务器上,实现压力分流的目的。

http负载均衡

Nginx 提供了好几种分配方式,默认为轮询,就是轮流来。有以下几种分配方式:

  1. 轮询,默认方式,每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务挂了,能自动剔除;
http {
  upstream backend_pool{
    server 127.0.0.1:8081;  # 负载均衡目的服务地址
    server 127.0.0.1:8080;
  }
  server {
    location / {
      listen 80;
      server_name  yourdomain.com;
      proxy_pass http://backend_pool;
      proxy_connect_timeout 10;
    }
  }
}

2. weight加权轮询,权重分配,指定轮询几率,权重越高,在被访问的概率越大,用于后端服务器性能不均的情况;

http {
  upstream backend_pool{
    server 127.0.0.1:8081 weight = 2;
    server 127.0.0.1:8080 weight = 3;
  }
  server {
    location / {
      listen 80;
      server_name  yourdomain.com;
      proxy_pass http://backend_pool;
      proxy_connect_timeout 10;
    }
  }
}

请求惠安权重去调用, 调用808端口的服务器几率会比8081几率大

  1. ip_hash,每个请求按访问 IP 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决动态网页 session 共享问题。负载均衡每次请求都会重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的;

工作原理

当客户端发起请求时,Nginx 会获取客户端的 IP 地址,通过哈希算法(通常是一致性哈希算法)计算出一个哈希值。然后根据这个哈希值在后端服务器列表中选择一台服务器来处理请求。只要客户端的 IP 地址不变,计算出的哈希值就不变,请求就会始终被分配到同一台后端服务器。

http {
  upstream backend_pool{
    ip_hash;
    server 127.0.0.1:8081;
    server 127.0.0.1:8080;
  }
  server {
    location / {
      listen 80;
      server_name  yourdomain.com;
      proxy_pass http://backend_pool;
      proxy_connect_timeout 10;
    }
  }
}

4. fair(第三方),按后端服务器的响应时间分配,响应时间短的优先分配,依赖第三方插件 nginx-upstream-fair,需要先安装; fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。

首先需要下载fair插件 github.com/gnosek/ngin… github主页里面有教程这里就不额外写了

TCP负载均衡

您希望将负载分发到两台或多台 TCP 服务器。

stream { 
    upstream mysql_read { 
        server read1.example.com:3306 weight=5; 
        server read2.example.com:3306; 
        server 10.10.12.34:3306 backup; 
    } 
    server { 
        listen 3306; proxy_pass mysql_read; 
    } 
}

http 和 stream 上下文之间的主要区别在于它们在 OSI 模型的不同层上运行。http 上 下文在应用层(七层)运行,stream 在传输层(四层)运行。这并不意味着 stream 上 下文不能通过一些巧妙的脚本获得应用感知能力,而是说 http 上下文是专门为了完全 理解 HTTP 协议而设计的,stream 上下文默认情况下只能对数据包进行路由和负载 均衡。 TCP 负载均衡由 NGINX 的 stream 模块定义。stream 模块与 HTTP 模块一样,允许您 定义上游(upstream)服务器池并配置侦听服务器。在配置服务器侦听给定端口时, 您必须定义待侦听的端口或者地址加端口(可选)。然后您必须配置目标服务,无论这 是连接另一个地址的直接反向代理还是上游资源池。 配置中有许多选项可以改变 TCP 连接反向代理的属性,包括 SSL/TLS 验证限制、超时 和 keepalive 等。这些代理选项的一些值可以是(或者包含)变量,例如下载速率、验 证 SSL/TLS 证书时使用的名称等。

TCP 与 HTTP 负载均衡中的 upstream 指令非常相似,它们均将上游资源定义为服务 器,配置格式同样为 Unix 套接字、IP 或 FQDN,此外服务器 weight 参数、最大连接 数、DNS 解析器、连接数缓增期以及判断服务器是激活状态、故障状态还是备用模式 的参数也都相似。 NGINX Plus 甚至提供了更多 TCP 负载均衡特性。

UDP 负载均衡

在 NGINX 的 stream 模块内使用 upstream 代码块(定义为 udp)对 UDP 服务器实施

stream { 
    upstream ntp{ 
        server ntp1.example.com:123 weight=2; 
        server ntp2.example.com:123;
    } 
    server { 
        listen 123 udp; proxy_pass ntp; 
    } 
}

配置动静分离

动静分离是指将动态内容(如由服务器端脚本语言生成的内容,像 PHP、Python 等动态生成的网页部分)和静态内容(如 HTML 文件、CSS 样式文件、JavaScript 脚本文件、图片、视频等)分别处理。这样做的好处是可以提高服务器的性能和效率,因为静态资源可以被更高效地缓存和分发。

方案一: 纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案。

方案二: 动态跟静态文件混合在一起发布, 通过 Nginx 配置来分开。

通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。

具体 expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可。此种方法非常适合不经常变动的资源。我这里设置 30d,表示在这 30 天之内访问这个URL,发送一个请求,比对服务器该文件最后更新时间没有变化。则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200。

server {
    listen 80;
    server_name  example.com;

    location /static {
        root   /var/www/html;
        expires 30d;
    }
}

动态适配 PC/移动设备

根据用户设备不同返回不同样式的站点,以前经常使用的是纯前端的自适应布局,但无论是复杂性和易用性上面还是不如分开编写的好,比如我们常见的淘宝、京东......这些大型网站就都没有采用自适应,而是用分开制作的方式,根据用户请求的 user-agent 来判断是返回 PC 还是 H5 站点。

比如京东

pc端访问

image.png . 手机端访问

image.png

server {
    listen       80;
    server_name  example.com;

    location / {
        if ($http_user_agent ~* "(Mobile|Android|iPhone|iPad)") {
            root   /var/www/html/mobile;
        }
        else {
            root   /var/www/html/pc;
        }
    }
}

配置 HTTPS

下载证书的压缩文件,里面有个 nginx 文件夹,把 xxx.crt 和 xxx.key 文件拷贝到服务器目录,再配置下:

server {
  listen 443 ssl http2 default_server;   # SSL 访问端口号为 443
  server_name sherlocked93.club;         # 填写绑定证书的域名

  ssl_certificate /etc/nginx/https/1_sherlocked93.club_bundle.crt;   # 证书文件地址
  ssl_certificate_key /etc/nginx/https/2_sherlocked93.club.key;      # 私钥文件地址
  ssl_session_timeout 10m;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;      #请按照以下协议配置
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
  ssl_prefer_server_ciphers on;
  
  location / {
    root         /usr/share/nginx/html;
    index        index.html index.htm;
  }
}

写完 nginx -t -q 校验一下,没问题就 nginx -s reload,现在去访问 https://sherlocked93.club/ 就能访问 HTTPS 版的网站了。 一般还可以加上几个增强安全性的命令:

add_header X-Frame-Options DENY;           # 减少点击劫持
add_header X-Content-Type-Options nosniff; # 禁止服务器自动解析资源类型
add_header X-Xss-Protection 1;             # 防XSS攻击

其它

静态资源优化

为了提高静态资源的传输效率,Nginx提供了以下三个主要的优化指令:

  • sendfile
  • tcp_nopush
  • tcp_nodelay

sendfile 指令

sendfile 用于开启高效的文件传输模式。它通过调用系统内核的 sendfile 函数来实现,从而避免了文件的多次拷贝,同时减少了用户态和内核态之间的切换,从而提高了静态文件的传输效率。

传统的静态资源请求过程:

  1. 客户端通过网络接口向服务端发送请求。

  2. 操作系统将这些请求传递给服务器端应用程序。

  3. 服务器应用程序处理请求。

  4. 处理完成后,操作系统将处理得到的结果通过网络适配器传递给客户端。

作用域:http,server,location
语法:sendfile on / off
默认值:sendfile off
作用:定义响应的mime类型

tcp_nopush 和 tcp_nodelay指令

当 sendfile 开启时,tcp_nopush 也可以被启用。它的主要目的是提高网络数据包的传输效率。

作用域:http,server,location
语法:tcp_nopush on / off
默认值:tcp_nopush off
作用:提高网络数据包的传输效率

tcp_nodelay 只有在 keep-alive 连接开启时,tcp_nodelay 才能生效。它的目的是提高网络数据包的实时性。

作用域:http,server,location
语法:tcp_nodelay on / off
默认值:tcp_nodelay on
作用:提高网络数据包的实时性

tcp_nopush 的工作原理是设置一个缓冲区,当缓冲区满时才进行数据发送,这样可以大大减少网络开销。

静态服务

server {
  listen       80;
  server_name  static.sherlocked93.club;
  charset utf-8;    # 防止中文文件名乱码

  location /download {
    alias	          /usr/share/nginx/html/static;  # 静态资源目录
    
    autoindex               on;    # 开启静态资源列目录
    autoindex_exact_size    off;   # on(默认)显示文件的确切大小,单位是byteoff显示文件大概大小,单位KB、MB、GB
    autoindex_localtime     off;   # off(默认)时显示的文件时间为GMT时间;on显示的文件时间为服务器时间
  }
}

图片防盗链

盗链就是'盗用'别的网站的'链接'

比如我部署了一个网站中的图片,是http请求的链接,你直接把他复制粘贴到你的网站展示 盗链: 盗用你的下载地址',挂在我自己的网站上,并且最主要的是'未经过你同意',这就是盗链

盗链影响:额外消费流量

Referer理解 HTTP 协议中有一个用来表示'页面或资源'来源的'请求头',这个请求头叫做 'Referer'

补充:Referer是表示请求是从'哪个网址'跳转过来的 ​ '防盗链'功能基于'HTTP协议'的Referer机制,通过Referer'跟踪来源',对来源进行'识别和判断'这样只有自家网站能访问其它网站就不能访问我服务器上的图片等资源了

nginx有三种防盗链方法

  1. 对Nginx 下所有项目的制定资源类型进行防盗链 如: fig png jpg等等

  2. 对制定目录或者制定项目目录进行防盗链

  3. 使用第三方模块ngx_http_accesskey_module 来实现

通过'浏览器直接'打开img的url,这时候是'没有referer的',如果'容许'这一类,那么配置valid_referers'可以包括none'

如果'referer不为空',但是里面的内容被'防火墙或者代理服务器'删除了,'也容许'这一类的话,可以通过

server {
  listen       80;        
  server_name  *.sherlocked93.club;
  
  # 图片防盗链
  location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
    valid_referers none blocked server_names ~\.google\. ~\.baidu\. *.qq.com;  # 只允许本机 IP 外链引用,感谢 @木法传 的提醒,将百度和谷歌也加入白名单
    if ($invalid_referer){
      return 403;
    }
  }
}

请求过滤

指定ip
# 非指定请求全返回 403
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
  return 403;
}

location / {
  # IP访问限制(只允许IP是 192.168.1.100 机器访问)
  allow 192.168.1.100;
  deny all;
  
  root   html;
  index  index.html index.htm;
}
ip段

要禁止192.168.1.0/24这个网段的访问

server {
    listen       80;
    server_name  example.com;

    location / {
        deny 192.168.1.0/24;
        allow all;
    }
}
基于请求方法的过滤

只允许GETPOST请求方法访问,禁止其他方法

server {
    listen       80;
    server_name  example.com;

    location / {
        if ($request_method!~ ^(GET|POST)$) {
            return 405;
        }
        # 正常访问的配置
    }
}
基于请求路径的过滤
server {
    listen       80;
    server_name  example.com;

    location /admin {
        return 403;
    }
    # 其他正常访问路径的配置
}

配置图片、字体等静态文件缓存

由于图片、字体、音频、视频等静态文件在打包的时候通常会增加了 hash,所以缓存可以设置的长一点,先设置强制缓存,再设置协商缓存;如果存在没有 hash 值的静态文件,建议不设置强制缓存,仅通过协商缓存判断是否需要使用缓存。

图片
# 图片缓存时间设置
location ~* .(jpg|png|gif)$ {
    expires 30d;
    access_log off;
}

# 如果不希望缓存
expires -1;

文字

add_header Cache - Control "public"用于添加一个Cache - Control头信息,告诉浏览器和中间缓存服务器(如代理服务器)这个资源是可以被公共缓存的,这有助于提高缓存的效率。

location ~* .(woff|woff2|ttf|otf)$ {
    expires 30d;
    add_header Cache - Control "public";
}

单页面项目 history 路由配置

server {
  listen       80;
  server_name  fe.sherlocked93.club;
  
  location / {
    root       /usr/share/nginx/html/dist;  # vue 打包后的文件夹
    index      index.html index.htm;
    try_files  $uri $uri/ /index.html @rewrites;  
    
    expires -1;                          # 首页一般没有强制缓存
    add_header Cache-Control no-cache;
  }
  
  # 接口转发,如果需要的话
  #location ~ ^/api {
  #  proxy_pass http://be.sherlocked93.club;
  #}
  
  location @rewrites {
    rewrite ^(.+)$ /index.html break;
  }
}

HTTP 请求转发到 HTTPS

配置完 HTTPS 后,浏览器还是可以访问 HTTP 的地址 http://sherlocked93.club/ 的,可以做一个 301 跳转,把对应域名的 HTTP 请求重定向到 HTTPS 上

单域名重定向
server {
    listen      80;
    server_name  yourdomain.com;

    # 单域名重定向
    if ($host = 'yourdomain.com'){
        return 301 https://$server_name$request_uri;
    }
}

非https协议重定向
server {
    listen      80;
    server_name  yourdomain.com;
    # 全局非 https 协议时重定向
    if ($scheme != 'https') {
        return 301 https://$server_name$request_uri;
    }
}

全部重定向
server {
    listen      80;
    server_name  yourdomain.com;
    # 或者全部重定向
    return 301 https://$server_name$request_uri;
}

安全漏洞修复

在Web应用中,安全漏洞可能导致严重的后果,包括数据泄露、系统瘫痪和声誉损失。本文将介绍十二个常见的Web安全漏洞,并提供相应的防范措施。这些漏洞包括:跨站请求伪造(CSRF)、点击劫持(Clickjacking)、拒绝服务攻击(DoS)、注入攻击、跨站脚本攻击(XSS)、信息泄露、安全配置错误、不安全的加密存储、SSL/TLS配置错误、认证和授权漏洞、敏感数据泄露和弱密码策略。

以下是实际在项目中解决的。

在前端项目项目的deploy/hsiar_see/template/nginx.conf

注意不同项目可能位置不同,也可能咱们打包的nginx 和现场用的nginx是不同文件的情况注意询问现场人员

pdfjs 反射型xss漏洞

首先需要一台自己的vps服务器部署有正常的https服务,并且配置cors策略,然后将构造好的url连接发送给受害者让其点击即可触发弹框

xxxx.xxx.com/static/pdfj…

可以通过右上角的上传按钮加载,从而触发xss漏洞

1 升级版本

目前这些漏洞已经修复,受影响用户可更新到PDF.js/pdfjs-dist版本4.2.67、react-pdf 7.7.3或8.0.2。

2 临时措施

可通过将isEvalSupported设置为false来缓解这两个漏洞。对于 PDF.js,该设置是全局配置的;而在React-PDF中,需在Document组件的options属性中指定options.isEvalSupported为false。

缺失Referrer-Policy头

Web服务器对于HTTP请求的响应头中可能会缺少某些安全相关的头部信息,导致浏览器提供的安全特性失效。其中,Referrer-Policy响应头是一个重要的安全头部,用于控制浏览器在页面跳转时是否发送引用信息。如果Referrer-Policy响应头缺失,将给网站带来一定的安全隐患。

什么是Referrer-Policy响应头?

Referrer-Policy响应头是用于指示浏览器在页面跳转时是否发送引用信息(即Referrer信息)的头部信息。Referrer信息包含当前页面的URL和HTTP方法,常被用于分析用户来源、广告点击量等数据。通过设置Referrer-Policy响应头,可以控制浏览器在页面跳转时是否发送Referrer信息,从而保护用户隐私和网站数据安全

为什么Referrer-Policy响应头缺失会导致安全问题?

如果Web服务器缺少Referrer-Policy响应头,浏览器在页面跳转时可能会默认发送Referrer信息,暴露用户的浏览行为和数据隐私。这可能导致以下问题:

  1. 数据泄露:攻击者可以利用这一漏洞获取用户的敏感信息,如用户名、密码等。
  2. 恶意广告点击:攻击者可以通过控制页面跳转来诱导用户点击恶意广告,增加广告费用消耗。
  3. 流量劫持:攻击者可以利用Referrer信息进行流量劫持,将用户重定向到恶意网站或强制用户观看广告。
  4. 找到Web服务器的配置文件:根据所使用的Web服务器类型(如Apache、Nginx等),找到对应的配置文件。常见的配置文件位置包括httpd.conf(Apache)和nginx.conf(Nginx)。
  5. 添加Referrer-Policy响应头:在配置文件中找到与HTTP头部相关的位置,添加Referrer-Policy响应头。根据需要设置合适的策略,例如Referrer-Policy: no-referrer表示禁止发送Referrer信息。
  6. 保存并重启Web服务器:保存配置文件的更改,并重新启动Web服务器以使更改生效。

修复

http {  
 # same-origin 只在同源请求时发送Referer信息  no-referrer不发送Referer 信息
  add_header Referror-Policy same-origin;
  ...
}
   

缺失X-Content-Type-Options头

技术原因:未设置此header时,会加载所有script文件,即使它的MIME不是text/javascript等。运行潜在的脚本文件,会存在丢失数据的风险。简单理解为:通过设置”X-Content-Type-Options:nosniff”响应标头,对script和 styleSheet 在执行是通过MIME 类型来过滤掉不安全的文件。X-Content-Type-Options: nosniff如果响应中接收到 “nosniff” 指令,则浏览器不会加载“script”文件,除非 MIME 类型匹配以下值之一:

“application/ecmascript”

“application/javascript”

“application/x-javascript”

“text/ecmascript”

“text/javascript”

“text/jscript”

“text/x-javascript”

“text/vbs”

“text/vbscript”

解决

http{
    # 阻止浏览器嗅探,确保浏览器正确处理内容类型
    add_header X-Content-Type-Options nosniff;
    ...
}

缺失X-Download-Options头【远程原理检测(应用)】

解决

http{
    # 阻止 下载完成后自动打开
    add_header X-Download-Options noopen;
    ...
}

缺失X-XSS-Protection头

"X-XSS-Protection":这个头可以告诉浏览器启用或禁用 XSS 保护机制。当设置为 "1; mode=block" 时,浏览器会阻止恶意脚本的执行并通知用户。这有助于防止跨站脚本攻击(XSS)。

如果你在扫描网站的安全性时发现 "X-XSS-Protection" ,"Content-Security-Policy","X-Content-Type-Options"头缺失或不安全,那么这可能是一个安全风险,攻击者可能会利用 XSS 漏洞来注入恶意代码,如果用户访问了被攻击的页面,恶意代码可能会在用户的浏览器上执行。"X-XSS-Protection"、"Content-Security-Policy"
和 "X-Content-Type-Options" 都是 HTTP 响应头,用增强网站的安全性。"X-XSS-Protection" 用于启用浏览器的 XSS 保护机制,"Content-Security-Policy" 用于限制浏览器加载哪些资源,"X-Content-Type-Options" 用于指定响应内容的
MIME 类型。

  1. "X-XSS-Protection":这个头可以告诉浏览器启用或禁用
    XSS 保护机制。当设置为 "1; mode=block" 时,浏览器会阻止恶意脚本的执行并通知用户。这有助于防止跨站脚本攻击(XSS)。
  2. ."Content-Security-Policy"(CSP):CSP 是一个安全措施,用于限制浏览器加载哪些资源。通过定义白名单,CSP 可以防止恶意内容的加载和脚本的执行。它有助于防止跨站脚本攻击(XSS)和其他类型的攻击。
  3. "X-Content-Type-Options":这个头用于指定响应内容的
    MIME 类型。设置为 "nosniff" 可以防止浏览器在响应的 MIME 类型与实际内容不匹配时进行嗅探。这有助于防止潜在的攻击,例如跨站请求伪造(CSRF)。

解决

http{
    # 开启浏览器的 XSS 防护功能,并且在检测到 XSS 攻击时,浏览器会警告并直接阻止页面加载。
    add_header X-Xss-Protection "1; mode=block";
    ...
}

缺失Strict-Transport-Security头【远程原理检测(应用)】

HTTP Strict Transport Security (HSTS) 是一个安全功能,它告诉浏览器只能通过HTTPS访问当前网站。如果一个网站已经通过HTTPS进行访问,并且服务器在响应头中包含了Strict-Transport-Security
字段,那么浏览器会强制所有后续的请求都必须通过HTTPS发起,即使用户手动输入了HTTP URL。

如果你的网站没有设置Strict-Transport-Security响应头,那么用户可能可以通过HTTP访问你的网站,这样的话,即使你的网站应当只通过HTTPS访问,用户也可能会通过HTTP访问,可能会泄露敏感信息。

解决

http{
    # 1.99年即使用户手动输入 HTTP 网址,浏览器也会自动将其转换为 HTTPS,从而保障数据传输的安全性。
    # “preload” 指令表示希望将该域名加入到浏览器的 HSTS 预加载列表中。浏览器在启动时会预先加载一份包含众多域名的 HSTS 列表,对于列表中的域名,浏览器从一开始就会强制使用 HTTPS 连接,无需等待首次访问时从网站获取到 HSTS 响应头。
    # always 它表示无论响应的状态如何(比如成功、失败、重定向等),都要添加这个 Strict-Transport-Security 响应头。这样做的目的是确保在所有可能的情况下,浏览器都能够接收到这个至关重要的安全策略信息,从而能够正确无误地执行 HSTS 策略
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    ...
}

缺失X-Permitted-Cross-Domain-Policies头【远程原理检测(应用)】

Web 服务器对于 HTTP 请求的响应头中缺少 X-Permitted-Cross-Domain-Policies,这将导致浏览器提供的安全特性失效。 当一些在线的 Web Flash 需要加载其他域的内容时,很多 Web 会通过设置一个 crossdomain.xml 文件的方式来控制其跨域方式。很有可能有些开发者并没有修改 crossdomain.xml 文件的权限,但是又有和跨域的 Flash 共享数据的需求,这时候可以通过设置 X-Permitted-Cross-Domain-Policies 头的方式来替代
crossdomain.xml 文件,其可选的值有: none master-only
by-content-type by-ftp-filename all 漏洞危害: Web 服务器对于 HTTP 请求的响应头中缺少
X-Permitted-Cross-Domain-Policies,这将导致浏览器提供的安全特性失效,更容易遭受 Web 前端黑客攻击的影响。

解决

http{
    # 1.99年即使用户手动输入 HTTP 网址,浏览器也会自动将其转换为 HTTPS,从而保障数据传输的安全性。
    # “preload” 指令表示希望将该域名加入到浏览器的 HSTS 预加载列表中。浏览器在启动时会预先加载一份包含众多域名的 HSTS 列表,对于列表中的域名,浏览器从一开始就会强制使用 HTTPS 连接,无需等待首次访问时从网站获取到 HSTS 响应头。
    # always 它表示无论响应的状态如何(比如成功、失败、重定向等),都要添加这个 Strict-Transport-Security 响应头。这样做的目的是确保在所有可能的情况下,浏览器都能够接收到这个至关重要的安全策略信息,从而能够正确无误地执行 HSTS 策略
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    ...
}

ip 泄露问题

解决

代码中写死的ip 需要进行手动删除, 包括注释的ip地址也要手动删除

点击劫持风险

点击劫持(Clickjacking)是一种恶意技术,攻击者通过诱使用户在看似无害的网页上点击隐藏的恶意元素,从而在用户不知情的情况下执行有害操作,给用户带来诸多风险,以下是具体介绍:

  • 账号被盗用 :攻击者可能会在被劫持的页面中嵌入恶意的登录框或密码输入框,当用户在不知情的情况下输入账号和密码时,这些信息就会被攻击者获取,导致账号被盗用。
  • 隐私信息被窃取 :点击劫持可用于诱导用户点击授权按钮,从而获取用户的敏感信息,如地理位置、联系人列表、浏览历史等,这些信息可能会被用于进一步的恶意行为,如精准广告投放、诈骗等。
  • 恶意转账或支付 :攻击者可以在劫持页面中伪装成正规的银行或支付平台界面,诱导用户进行转账或支付操作,导致用户的资金被盗取。
  • 虚假交易 :通过点击劫持,攻击者可以在用户不知情的情况下发起虚假交易,使受害者遭受经济损失。
  • 恶意软件安装 :点击劫持可能会诱导用户点击下载链接或安装按钮,从而在用户设备上安装恶意软件,如病毒、木马、间谍软件等。这些恶意软件可能会窃取用户数据、控制用户设备,甚至进一步传播恶意代码。
  • 系统漏洞利用 :攻击者可能利用点击劫持来触发浏览器或操作系统的漏洞,从而执行任意代码,获取设备的最高权限,对设备进行完全控制。
  • 企业数据泄露 :员工在企业网络环境中遭遇点击劫持攻击,可能导致企业敏感数据泄露,如商业机密、客户信息等,给企业带来巨大的经济损失和声誉损害。
  • 内部系统被攻击 :攻击者通过点击劫持获取员工的企业系统登录凭证后,可能进一步攻击企业内部系统,如篡改数据、破坏业务流程、发起勒索攻击等。

解决

在nginx 配置 X-FRAME-OPTIONS

DENY :该值表示浏览器应完全拒绝将当前页面加载到任何框架或 iframe 中,无论该框架或 iframe 的来源是哪里,都不允许进行嵌入操作。对于一些极其敏感的页面,如银行账户登录页面、在线支付页面等,通常会将X-Frame-Options设置为DENY,以确保这些页面不会被任何其他网站嵌入并进行恶意利用,从而最大程度地保护用户的安全和隐私。

SAMEORIGIN: 此值规定页面只能在与自身同源的框架或 iframe 中加载。同源是指协议、域名和端口都相同。企业内部的管理系统,其中不同部门的子系统可能存在相互引用页面的情况,但为了防止外部网站嵌入内部页面进行攻击,会将X-Frame-Options设置为SAMEORIGIN,这样既允许内部系统之间的正常页面嵌入,又能阻止外部恶意网站的嵌入。

ALLOW-FROM uri : 该值允许页面在指定的 uri 所对应的框架或 iframe 中加载,而对于其他来源的框架或 iframe 则不允许加载。

在一些合作的跨域场景中,网站 A 与网站 B 存在合作关系,网站 A 的某些页面需要在网站 B 的特定页面中以 iframe 的形式展示,此时网站 A 可以将X-Frame-Options设置为ALLOW-FROM websiteb.com/pageB.html,… B 的该特定页面嵌入网站 A 的相关页面。

http{
    add_header X-Frame-Options SAMEORIGIN;
    ...
}

正常配置之后使用iframe 打开网站会直接访问异常

但是在生产上遇到一个奇怪问题 明明配置了但是被安全漏洞扫描出来了

原因是没配置always

完整配置示例

# 定义Nginx运行的用户和用户组,通常可以设置为 'www-data'(在Ubuntu、Debian等系统中)或 'nginx'(在CentOS等系统中)
user  www-data;

# 启动的进程数量,通常设置为和CPU核心数相同或者根据服务器负载情况适当调整
worker_processes  auto;

# 错误日志文件的路径和日志级别,日志级别从低到高有 'debug'、'info'、'notice'、'warn'、'error'、'crit' 等,可按需选择
error_log  /var/log/nginx/error.log notice;

# 进程文件的路径,用于保存Nginx主进程的PID(进程标识符)
pid        /var/run/nginx.pid;

# 配置事件驱动模型相关的参数,这里使用 'epoll'(适用于Linux系统),它在处理大量并发连接时效率较高
events {
    use epoll;
    # 每个 worker 进程允许的最大连接数,根据服务器资源和预期负载合理设置
    worker_connections  1024;
}

# HTTP配置块,包含了对HTTP相关功能的设置
http {
    # 包含 mime.types 文件,用于定义不同文件扩展名对应的MIME类型,这样Nginx能正确识别并处理各种文件
    include       /etc/nginx/mime.types;
    # 默认的MIME类型,如果文件扩展名未在mime.types中定义,则使用此类型,一般设置为 'application/octet-stream'
    default_type  application/octet-stream;

    # 日志格式的定义,这里定义了一个名为'main' 的日志格式,记录了客户端IP、请求时间、请求方法、请求URL、协议、响应状态码、发送的字节数等信息
    log_format  main  '$remote_addr - $time_local [$time_zone] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    # 访问日志文件的路径和使用的日志格式,这里使用前面定义的'main' 格式,记录所有访问请求的信息
    access_log  /var/log/nginx/access.log main;

    # 开启发送文件功能,它允许Nginx在处理文件传输时直接从内核缓存中发送文件,提高效率
    sendfile        on;

    # TCP连接的超时时间,单位是秒,超过此时间没有数据传输则关闭连接,避免占用过多资源
    keepalive_timeout  65;

    # 开启gzip压缩功能,用于对响应的文本类文件(如HTML、CSS、JavaScript等)进行压缩,减少网络传输量
    gzip  on;
    # gzip压缩的级别,从1到9,数字越大压缩比越高,但也更消耗CPU资源,一般建议使用4 - 6之间的值
    gzip_comp_level  4;
    # 指定要进行gzip压缩的文件类型,用空格分隔不同类型
    gzip_types text/html text/css application/javascript text/plain text/xml application/xml application/json;
    # 设置gzip压缩的最小文件大小,小于此大小的文件将不进行压缩,避免浪费CPU资源压缩过小的文件
    gzip_min_length  1024;
    # 配置gzip压缩的浏览器支持情况,指定使用gzip压缩的HTTP协议版本为1.1
    gzip_http_version  1.1;
    # 开启此功能后,会在响应头中添加 'Vary: Accept-Encoding',让代理服务器根据浏览器的 'Accept-Encoding' 头信息正确地缓存内容
    gzip_vary  on;

    # 配置服务器块,可针对不同的域名或IP地址进行不同的配置
    server {
        # 监听的端口,这里是80端口,用于接收HTTP请求
        listen       80;
        # 服务器的域名,可配置多个,用空格分隔,这里以示例域名为例
        server_name  example.com www.example.com;

        # 配置根路径('/')的请求处理,这里假设静态文件存放在 '/var/www/html' 目录下
        location / {
            root   /var/www/html;
            # 尝试查找请求的文件,如果不存在则查找对应的目录下的 'index.html' 文件,如果还不存在则返回404错误
            try_files $uri $uri/ /index.html;
        }

        # 配置对静态资源(如图片、CSS、JavaScript等)的缓存,以图片文件为例
        location ~* .(jpg|png|gif)$ {
            expires 30d;
            access_log off;
        }

        # 配置对动态资源(如.php文件,这里以PHP为例,实际根据后端语言调整)的处理,通过反向代理转发到后端服务器
        location ~ .php$ {
            # 后端服务器的地址,这里假设后端PHP - FPM服务监听在127.0.0.1:9000端口
            proxy_pass http://127.0.0.1:9000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 配置错误页面的处理,当出现404错误时,重定向到自定义的404页面(这里假设404页面为 '/404.html')
        error_page  404 /404.html;
        location = /404.html {
            root   /var/www/html;
        }
    }

    # 以下是另一个服务器块示例,用于将HTTP请求重定向到HTTPS(假设已配置好SSL证书)
    server {
        listen       80;
        server_name  example.com www.example.com;

        location / {
            rewrite ^(.*)$ https://$server_name$1 permanent;
        }
    }

    # 配置HTTPS服务器块(假设已获取并配置好SSL证书)
    server {
        listen       443 ssl;
        server_name  example.com www.example.com;

        # SSL证书文件的路径,根据实际证书情况填写
        ssl_certificate      /etc/nginx/ssl/example.com.crt;
        # SSL证书私钥文件的路径,与证书对应
        ssl_certificate_key  /etc/nginx/ssl/example.com.key;

        # SSL协议版本的配置,建议使用较新且安全的版本,这里列出了一些常用的安全配置选项
        ssl_protocols TLSv1.2 TLSv1.3;
        # 加密套件的选择,优先使用安全强度高的加密算法
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-ECDSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-ECDSA-AES256-GCM-SHA384;
        # 启用SSL会话缓存,提高SSL连接的处理效率
        ssl_session_cache shared:SSL:10m;
        # SSL会话的超时时间,单位是秒
        ssl_session_timeout  5m;

        # 配置根路径('/')的请求处理,与HTTP服务器块中的类似,这里假设静态文件存放在 '/var/www/html' 目录下
        location / {
            root   /var/www/html;
            try_files $uri $uri/ /index.html;
        }

        # 配置对静态资源(如图片、CSS、JavaScript等)的缓存,以图片文件为例
        location ~* .(jpg|png|gif)$ {
            expires 30d;
            access_log off;
        }

        # 配置对动态资源(如.php文件,这里以PHP为例,实际根据后端语言调整)的处理,通过反向代理转发到后端服务器
        location ~ .php$ {
            proxy_pass http://127.0.0.1:9000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 配置错误页面的处理,当出现404错误时,重定向到自定义的404页面(这里假设404页面为 '/404.html')
        error_page  404 /404.html;
        location = /404.html {
            root   /var/www/html;
        }
    }
}