原创

Nginx

温馨提示:
本文最后更新于 2025年01月03日,已超过 106 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

 

1.简介

Nginx是一款广泛使用的高性能Web服务器和反向代理服务器,由Igor Sysoev开发,最初是为了应对C10K问题(即一个服务器能够同时处理超过1万个并发连接的能力)。Nginx的设计理念在于其高效、稳定和低内存消耗的特性,使其成为许多网站和互联网公司的首选服务器软件。Nginx常被用作Web服务器、反向代理和负载均衡器,在处理静态资源和高并发请求方面表现出色。

1. Web服务器

  • Nginx可以作为一个独立的Web服务器,处理HTTP请求并发送静态文件(HTML、CSS、JavaScript、图片等)给客户端。
  • 它具有优秀的静态文件处理能力和高并发连接处理能力,能够快速响应大量用户的请求。

2. 反向代理

  • Nginx可以作为反向代理服务器,接收来自客户端的请求,并将其转发到后端的服务器集群上。
  • 这种模式下,Nginx对外部用户隐藏了后端服务器的具体位置,增加了系统的安全性和灵活性。

3. 负载均衡

  • 当Nginx作为反向代理时,它可以将请求分发到多个后端服务器上,实现负载均衡。
  • 支持多种负载均衡算法,如轮询、最少连接数、IP Hash等,确保请求均匀地分布在所有可用服务器上。

2.配置

2.1配置文件

安装后的默认配置/etc/nginx/nginx.conf内容如下

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	types_hash_max_size 2048;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;
}

主要的 Nginx 配置指令及其作用:

全局指令

  • user: 指定运行 Nginx 的用户和组,确保适当的文件权限和安全性。
  • worker_processes: 设置 Nginx 工作进程的数量,通常设为 CPU 核心数或 auto 以自动检测。
  • pid: 指定 Nginx 主进程的 PID 文件位置。
  • error_log: 配置 Nginx 错误日志的路径和日志级别。
  • include: 包含其他配置文件,使配置更加模块化和可维护。

事件模块配置 (events)

  • worker_connections: 指定每个工作进程可以同时处理的最大连接数。
  • multi_accept: 允许一个工作进程同时接受多个连接请求。

HTTP 块配置 (http)

  • sendfile: 控制是否使用 sendfile 系统调用进行文件传输,提高性能。
  • tcp_nopush: 禁用 TCP 推送,减少网络延迟。
  • tcp_nodelay: 禁用 Nagle 算法,即时发送数据,适用于交互式应用。
  • keepalive_timeout: 设置长连接的超时时间。
  • gzip: 开启 GZIP 压缩,减少传输数据量,提高页面加载速度。
  • include: 包含 MIME 类型和额外的配置文件。

Server 块配置

  • listen: 指定 Nginx 监听的端口和 IP 地址。
  • server_name: 配置虚拟主机的域名。
  • root: 设置文档根目录。
  • index: 指定默认的索引文件列表。
  • access_log: 配置访问日志的路径和格式。
  • error_page: 指定错误页面。

Location 块配置

  • proxy_pass: 用于反向代理,指定后端服务器的 URL。
  • proxy_set_header: 设置转发给后端服务器的请求头。
  • proxy_read_timeout, proxy_send_timeout, proxy_connect_timeout: 设置与后端服务器通信的超时时间。
  • rewrite: 用于 URL 重写和重定向。
  • if: 条件判断,可以基于变量执行不同的配置。

SSL/TLS 配置

  • ssl_certificate: 指定 SSL 证书文件。
  • ssl_certificate_key: 指定 SSL 密钥文件。
  • ssl_protocols: 指定支持的 SSL/TLS 协议版本。
  • ssl_ciphers: 指定允许的加密算法。

Upstream 块配置

  • upstream: 定义一组后端服务器,用于负载均衡。

日志和监控配置

  • access_log: 记录访问日志。
  • error_log: 记录错误日志。
  • log_format: 自定义日志格式。
  • stub_status: 提供简单的 HTTP 服务状态接口,可用于监控。

2.2https配置

# 监听 8888 端口的 HTTPS 请求
server {
    listen 8888 ssl;
    server_name abc.top;

    ssl_certificate /etc/nginx/certs/fullchain.crt; # SSL 证书路径
    ssl_certificate_key /etc/nginx/certs/private.pem; # SSL 私钥路径

    # 代理到 3000 端口
    location / {
        proxy_pass http://127.0.0.1:3000; # 代理到3000端口
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 允许大文件上传
        client_max_body_size 512M;  # 设置为合适的大小
    }
}

3.常用命令

检查配置文件,测试 Nginx 的配置文件是否语法正确。如果配置有误,Nginx 将输出错误信息,否则显示 "configuration file /etc/nginx/nginx.conf test is successful"。

sudo nginx -t

显示Nginx版本

sudo nginx -v

显示完整版本和编译参数

sudo nginx -V

日志文件路径

Nginx 的日志文件位置通常可以在配置文件中找到,一般在 /var/log/nginx/access.log 和 /var/log/nginx/error.log。

4.代理

Nginx 支持两种类型的代理:HTTP 代理和 TCP/UDP 代理(有时被称为 socket 代理)。这两种代理机制用于不同的场景和目的,下面详细解释两者的区别和应用场景:

4.1正向代理 (Forward Proxy)

  • 代理方向:正向代理代表客户端进行代理,也就是说,客户端发送的请求首先到达正向代理服务器,代理服务器再将请求转发给真正的目标服务器。
  • 客户端感知:客户端是知道正向代理的存在并主动配置代理服务器的信息(如地址和端口),所有请求都通过代理服务器发出。这意味着客户端需要配置代理服务器的详细信息。
  • 用途
    • 上网权限控制:在企业或学校网络中,通过正向代理控制员工或学生的互联网访问权限,比如过滤不良内容或限制访问某些网站。
    • 缓存:正向代理可以缓存经常访问的内容,从而减少对互联网的请求,节省带宽和提高访问速度。
    • 匿名访问:客户端可以通过正向代理隐藏自己的IP地址,实现一定程度的匿名访问。

4.2反向代理 (Reverse Proxy)

  • 代理方向:反向代理代表服务器进行代理,客户端的请求直接发送到反向代理服务器,反向代理服务器再将请求转发给后端的一台或多台服务器,并将后端服务器的响应返回给客户端。
  • 客户端感知:客户端并不知道反向代理的存在,它只看到一个单一的服务器地址。客户端配置中不需要任何关于代理的信息。
  • 用途
    • 负载均衡:反向代理可以将请求分发到多台服务器上,提高系统的可用性和响应速度。
    • 安全性和隐私:反向代理可以隐藏后端服务器的真实IP地址,提供一层额外的安全防护。
    • SSL/TLS卸载:反向代理可以处理HTTPS连接,将加密的HTTPS请求转换为内部的HTTP请求,减轻后端服务器的负担。
    • 缓存和压缩:反向代理可以缓存静态内容和压缩响应数据,进一步提高性能。

4.3HTTP 代理 (http_proxy)

HTTP 代理是 Nginx 最常见的代理类型,主要用于代理 HTTP 和 HTTPS 请求。当配置为 HTTP 代理时,Nginx 将接收客户端的 HTTP 请求,然后将这些请求转发到指定的后端服务器。后端服务器处理请求后,Nginx 再将响应返回给客户端。

HTTP 代理配置通常包含以下关键元素:

  • proxy_pass 指令用于指定要代理的目标服务器。
  • proxy_set_header 可以用来修改或添加 HTTP 头部字段,比如 Host X-Real-IP
  • proxy_read_timeout proxy_send_timeout 设置读取和发送超时时间。
  • proxy_cache proxy_cache_valid 可以启用缓存功能。

HTTP 代理非常适合用于负载均衡、反向代理和缓存场景,尤其是在处理静态内容和动态内容混合的网站时。

http {
    # 上游服务器池
    upstream backend {
        server backend1.example.com;
        server backend2.example.com;
    }

    # 限制客户端请求中允许的最大 body 大小
    client_max_body_size 1024m;
    server {
        listen 80;
        # 域名
        server_name example.com;

        # 根目录/下的所有请求都会被代理
        location / {
            # 请求被代理到上游backend服务器池
            proxy_pass http://backend;
            # 设置 Host 请求头为客户端请求中的 Host 字段,确保后端服务器能够正确解析请求的主机名
            proxy_set_header Host $host;
            # 设置 X-Real-IP 请求头为客户端的真实 IP 地址
            proxy_set_header X-Real-IP $remote_addr;
            # 设置 X-Forwarded-For 请求头,通常用于记录客户端的 IP 地址和经过的代理列表
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            # 设置 X-Forwarded-Proto 请求头为请求的协议(HTTP 或 HTTPS)
            proxy_set_header X-Forwarded-Proto $scheme;
            # 此指令关闭了 Nginx 的自动重定向功能。默认情况下,如果后端服务器返回一个重定向响应,Nginx 会自动进行重定向。设置 off 则意味着 Nginx 会直接将重定向响应传递给客户端,让客户端自行处理重定向。
            proxy_redirect off;
            # 此指令开启 Nginx 的响应缓冲功能。当缓冲开启时,Nginx 会先接收完整的后端响应,然后将其发送给客户端。这有助于提高性能,尤其是在响应较大的文件时,可以减少网络延迟的影响
            proxy_buffering on;
            # 设置 Nginx 从后端服务器读取响应的超时时间为 60 秒。如果在此时间内未读取完响应,Nginx 将返回错误。
            proxy_read_timeout 60s;
            # 设置 Nginx 发送响应到客户端的超时时间为 60 秒。如果在此时间内未能完成发送,Nginx 将停止发送并返回错误
            proxy_send_timeout 60s;
            # 设置 Nginx 连接到后端服务器的超时时间为 60 秒。如果在此时间内未能成功建立连接,Nginx 将返回错误
            proxy_connect_timeout 60s;
        }
    }
}

4.4TCP/UDP 代理 (stream_proxy)

TCP/UDP 代理(也称为 socket 代理)是 Nginx 在 1.9.0 版本之后引入的功能,用于代理非 HTTP 协议的流量,如 MySQL、PostgreSQL、Redis、SMTP、IMAP、POP3 等。Nginx 的 TCP/UDP 代理机制是在流模块(stream 模块)中实现的,该模块专注于处理二进制协议的数据流。

TCP/UDP 代理配置通常包括:

  • proxy_pass 指令同样用于指定目标服务器。
  • proxy_connect_timeout 设置连接超时时间。
  • proxy_read_timeout proxy_send_timeout 分别设置读取和发送数据的超时时间。

TCP/UDP 代理非常适合用于数据库、邮件服务和其他非 Web 协议的负载均衡和故障切换。

stream {
    # 上游服务器池
    upstream backend {
        server backend1.example.com:3306;
        server backend2.example.com:3306;
    }

    server {
        # 使用8080端口转发
        listen 8080;
        proxy_pass backend;
        # Nginx 尝试与后端服务器建立连接的最大等待时间。如果在 5 秒内连接未能建立,Nginx 将超时并可能采取错误处理措施
        proxy_connect_timeout 5s;
        # 在读取后端服务器数据时的超时时间。如果在 60 秒内没有读取到足够的数据,Nginx 将超时并可能中断读取过程
        proxy_read_timeout 60s;
        # 在向后端服务器发送数据时的超时时间。如果在 60 秒内数据发送未能完成,Nginx 将超时并可能停止发送数据
        proxy_send_timeout 60s;
    }
}

普通在线安装Nginx,不带stream模块。通过添加 Nginx 的官方仓库来安装包含 Stream 模块的 Nginx。以下是详细的步骤:

添加 Nginx 的官方仓库

首先,添加 Nginx 的官方 GPG 密钥:

curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg

然后,添加 Nginx 的 APT 存储库信息:

echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

更新包列表

sudo apt update

安装 Nginx

使用以下命令来安装 Nginx:

sudo apt install nginx

这将安装 Nginx 的最新稳定版本,该版本通常会包含 Stream 模块。

确认 Stream 模块

你可以在 Nginx 的配置文件中尝试使用 Stream 模块的指令,然后运行 nginx -t 来检查配置的语法是否正确。如果 Stream 模块被正确安装,你应该不会收到任何关于未知指令的错误。

另外,你也可以直接查看 Nginx 的版本信息和模块列表来确认 Stream 模块的存在:

nginx -V 2>&1 | grep stream

如果 Stream 模块已安装,你将看到类似以下的输出:

--with-stream

通过上述步骤,你可以在 Ubuntu 22.04 上安装一个包含 Stream 模块的 Nginx 版本,无需从源代码进行编译。这将使你能够利用 Stream 模块的功能来代理非 HTTP/TCP 服务,如 MySQL、Redis 等。

5.使用场景

5.1场景1

Nginx 作为反向代理服务器时,可以接收 HTTPS 请求(加密的),然后将请求转发至后端使用 HTTP 协议(未加密的)的服务器。这种配置在实践中是非常常见的,特别是当后端服务器不需要 SSL 加密,或者在后端服务器上处理 SSL 加密成本较高时。

这种配置的好处包括:

  • 性能提升:后端服务器不需要处理 SSL 加密/解密过程,可以节省 CPU 资源,提高性能。
  • 简化配置:后端服务器可以使用标准的 HTTP 端口(80),无需 SSL 配置和证书管理。
  • 集中管理 SSL:SSL 证书和密钥可以集中在 Nginx 层面管理,简化了整个系统的 SSL 管理。

然而,也有一些潜在的问题需要注意:

  • 安全风险:如果后端服务器与 Nginx 之间的连接未加密,那么在网络中传输的数据可能会被截获。因此,确保这一部分网络是可信的非常重要。
  • 中间人攻击:理论上,如果 Nginx 和后端服务器之间的连接未加密,存在中间人攻击的风险。但在实际部署中,通常这一段网络是在受控的局域网内,风险较低。

5.2场景2

模拟使用域名和https进行代理

安装Nginx

sudo apt update
sudo apt install nginx

使用 OpenSSL 来生成自签名证书

sudo apt install openssl
sudo mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
# 生成私钥和自签名证书
openssl req -newkey rsa:2048 -nodes -keyout example.com.key -x509 -days 365 -out example.com.crt

Nginx配置

修改/etc/nginx/nginx.conf配置

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    # 指定此服务器块响应哪些域名
    server_name example.com www.example.com;

    # 指定服务器使用的SSL/TLS证书文件路径
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    # 指定服务器私钥文件路径
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    # 指定允许的TLS协议版本
    ssl_protocols TLSv1.2 TLSv1.3;
    # 设置加密算法套件。这里的设置意味着使用强度高的加密算法,排除不安全的aNULL和MD5算法
    ssl_ciphers HIGH:!aNULL:!MD5;
    # 指示服务器在与客户端协商时优先使用服务器端的加密算法套件
    ssl_prefer_server_ciphers on;
    # 配置会话缓存,可以提高性能和安全性。这里设置了名为SSL的共享内存区,存储10分钟的会话记录。
    ssl_session_cache shared:SSL:10m;
    # 设置TLS会话超时时间
    ssl_session_timeout 10m;

    # 设置HTTP Strict Transport Security (HSTS)头部,告知浏览器仅通过HTTPS访问网站,并将该策略应用于所有子域,并加入HSTS预加载列表。
    add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";

    location /wzhhy/ {
        proxy_pass http://192.168.1.15:30000/;
        proxy_http_version 1.1;
        # 将重定向从http://变为当前的$scheme(即HTTPS)
        proxy_redirect http:// $scheme://;
        # 传递客户端的真实IP地址给后端服务器
        proxy_set_header X-Real-Ip $remote_addr;
        # 记录经过的代理服务器
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 设置Cookie的路径和属性
        proxy_cookie_path / "/; HttpOnly;Secure;SameSite=Lax";
        # 设置X-Content-Type-Options头,防止浏览器进行MIME类型嗅探
        add_header X-Content-Type-0ptions "nosniff";
        # 定义了内容安全策略,其中包括升级不安全的请求和允许从任何源发起连接
        add_header Content-Security-Policy "upgrade-insecure-requests;,connect-src *";
    }
}

修改hosts文件

Windows电脑在C:\Windows\System32\drivers\etc\hosts,Linux电脑在/etc/hosts,添加以下一行配置。注意hosts文件修改后即生效,不用重启服务器。

192.168.1.7 abcd.com
正文到此结束