Nginx反向代理和正向代理
# 1. 正向代理
我们常说的代理服务器(多指 VPN),翻墙等,⼀般就是正向代理。它的特点有:
- 隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都由代理 服务器代替来请求
- 「正向代理」指⼀对⼀或多对⼀,Server 不知道请求的 Client 都是哪些⼈。
- 正向代理的对象是客户端
# 2. 反向代理
反向代理跟正向代理相反,同时反向代理⼀般是负载均衡的⼀个原理。反向代理是⼀对多、多对 多,特点:
- 反向代理隐藏了真实的服务端!当我们请求 http://www.baidu.com 的时候,背后可能有成千 上万台服务器为我们服务,但具体是哪⼀台,谁也不知道,你只需知道反向代理服务器是谁就好了
- http://www.baidu.com 就是反向代理服务器,反向代理服务器会帮我们把请求转发到真实的 服务器那⾥去。
- 反向代理的对象是服务端
# 3. 配置反向代理
# 3.1 proxy_pass 命令
该指令⽤来设置被代理服务器地址,可以是主机名称、IP 地址 + 端⼝号形式
语法: proxy_pass 'URL'
; 默认值:⽆;可放在 location块
提示
URL--> 要设置的被代理服务器地址。包含 htpp [s]😕/、主机名称或 IP 地址 + 端⼝号、URI 等要素
# 项⽬实战案例(nginx反向代理http和websocket)
server {
listen 80;
server_name localhost;
root /home/jiayuan/iis2000web;
location /inspection {
proxy_pass http://192.168.110.158:10010;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Host $http_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;
proxy_read_timeout 1800s;
}
}
# Nginx反向代理(在浏览器中输⼊ http://127.0.0.1:3333 后,会访问到 http://127.0.0.1:4444 返回的内容)
# 代理服务器
server {
listen 3333;
server_name 127.0.0.1;
location / {
# 注意:proxy_pass后⾯的请求地址没有'/',会拼接location /*{...} 中*的内容; 有'/',不会拼接!
proxy_pass http://127.0.0.1:4444/;
# proxy_pass http://127.0.0.1:4444;
}
}
# 源服务器
server {
listen 4444;
server_name 127.0.0.1;
location / {
default_type application/json;
return 200 "{'name':'反向代理'}";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 3.2 proxy_set_header 命令
该指令可更改 Nginx 服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理服务器
语法:proxy_set_header file value; 默认值:⽆ 可放在 http、server、location 块
提示
注意:若想看到结果,必须在被代理的服务器上来获取添加的头信息。
# Nginx反向代理(在浏览器中输⼊ http://127.0.0.1:3333 后,会访问到 http://127.0.0.1:4444 返回的内容 'ZLS')
# 代理服务器
server {
listen 3333;
server_name 127.0.0.1;
location / {
proxy_pass http://127.0.0.1:4444;
proxy_set_header username ZLS;
proxy_set_header serverName $server_name;
proxy_set_header serverPort $server_port;
}
}
# 源服务器
server {
listen 4444;
server_name 127.0.0.1;
location / {
default_type application/json;
return 200 $http_username——$http_serverName——$http_serverPort;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 3.3 proxy_redirect 命令
该指令⽤来重置响应头信息中的 "Location" 和 "Refresh" 的值。
语法:proxy_redirect redirect replacement | default | off; 默认值:default 可放在 http、 server、location 块
# 4. 安全隔离
Nginx 使⽤安全隔离来提升 Web 服务器的安全。通过代理分开了客户端到应⽤程序服务器端的连接,实现了安全措施。
在反向代理之前设置防 ⽕墙,仅留⼀个⼊⼝供代理服务器访问。
使⽤ SSL 对流量进⾏加密,也就是将 HTTP 变为 HTTPS
(Nginx 使⽤ SSL,需要的模块是 --with-http_ssl_module,默认已安装。)
# 4.1 常用 SSL 配置命令
该指令⽤来在指定的服务器开启 HTTPS,可以使⽤ listen 443 ssl。后⾯这种⽅式更通⽤。
语法:ssl on | off; 默认值:off 可放在 http、server 块
ssl_certificate
该指令为当前虚拟主机指定⼀个带有 PEM 格式证书的证书。语法:ssl_certificate file; 默认值:⽆ 可放在 http、server 块
ssl_certificate_key
该指令⽤来指定 PEM secret key ⽂件的路径。语法:ssl_certificate_key file; 默认值:⽆ 可放在 http、server 块
ssl_session_cache
该指令⽤来配置⽤于 SSL 会话的存储。语法:ssl_session_cache off | none | [builtin [:size]] [shared:name:size]; 默认值:none 可放在 http、server 块
- off--> 禁⽤会话缓存,客户端不可重复使⽤会话
- none--> 禁⽤会话缓存,客户端可以重复使⽤,但是并没有在缓存中存储会话参数
- builtin--> 内置 OpenSSl 缓存,仅在⼀个⼯作进程中使⽤
- shared--> 所有进程间共享缓存,缓存的相关信息⽤ name 和 size 来指定
ssl_session_timeout
该指令⽤来开启 SSL 会话功能后,设置客户端能够反复使⽤存储在缓存中的会话参数时间语法:ssl_session_timeout time; 默认值:⽆ 可放在 http、server 块
ssl_ciphers
该指令⽤来指出允许的密码,密码指定为 OpenSSL ⽀持的格式语法:ssl_ciphers cilphers; 默认值: HIGH:!aNULL:!MD5; 可放在 http、server 块
ssl_prefer_server_ciphers
该指令⽤来指定是否服务器密码优先客户端密码语法:ssl_prefer_server_ciphers on | off; 默认值:off 可放在 http、server 块
# 4.2 生成证书 配置 HTTPS
# 4.2.1 利用 openssl 工具生成证书 (免费 / 未认证)
- cd /nginx
- mkdir ssl
- cd ssl
- openssl genrsa -des3 -out server.key 2048
提示
- openssl: OpenSSL 工具的命令行工具。
- genrsa: 生成 RSA 密钥对的子命令。
- -des3: 使用 DES3 加密算法对生成的私钥进行加密。这会要求输入密码以保护私钥文件。
- -out server.key: 将生成的私钥保存到名为 server.key 的文件中。
- 2048: 指定生成的 RSA 密钥长度为 2048 比特。密钥长度越长,通常越安全,但也会增加计算成本。
这个命令的作用是生成一个使用 RSA 加密算法的密钥对,包括一个加密过的私钥文件(server.key,由 DES3 加密)和一个相关的公钥。密钥长度为 2048 比特,私钥文件受密码保护。在实际使用中,生成的私钥文件将用于配置 Nginx 服务器的 SSL/TLS 设置。
- openssl req -new -key server.key -out server.csr (执⾏完这⾏命令后,会再次让你输⼊密码(照着上⾯的密码输)和很多其他信息(随便输))
提示
- req: 此子命令表示使用 CSR 相关的功能。
- -new: 创建新的 CSR。
- -key server.key: 指定用于生成 CSR 的私钥文件。在这里,server.key 是一个已经存在的私钥文件。
- -out server.csr: 指定生成的 CSR 的输出文件名。在这里,server.csr 是新生成的 CSR 文件。
执行这个命令后,系统将使用指定的私钥文件 (server.key) 生成一个新的 CSR 文件 (server.csr)。CSR 包含了你的公钥以及你希望包含在证书中的信息,如组织名称、组织单位、城市、州、国家等。
通常,你会将 CSR 提交给一个证书颁发机构 (CA - Certificate Authority),以便获取一个签名的证书。这个证书将包含你的公钥,并由 CA 的私钥签名,以证明你的身份和公钥的合法性
- cp server.key server.key.org
提示
- cp: 复制命令,用于复制文件或目录。
- server.key: 源文件名,即要复制的文件。
- server.key.org: 目标文件名,即复制后的文件的新名称。
这个命令的作用是将名为 server.key 的文件复制一份,并将新文件命名为 server.key.org。这样,server.key.org 就成为了 server.key 的副本。通常,这种命名方式表明 .org 文件是原始文件的备份或原始版本,以备不时之需。
openssl rsa -in server.key.org -out server.key
提示
- rsa: 表示执行 RSA 相关的操作。
- -in server.key.org: 指定输入文件的路径和文件名,即原始的 RSA 密钥文件的路径和文件名。
- -out server.key: 指定输出文件的路径和文件名,即将执行操作后的 RSA 密钥保存到的文件路径和文件名。
这个命令的作用是将原始的经过 DES3 加密的 RSA 私钥文件 server.key.org 进行解密,然后保存为未加密的 RSA 私钥文件 server.key。解密后的私钥文件通常不再需要密码保护,这样在 Nginx 或其他服务中使用时就不需要每次启动都输入密码了。
- openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
提示
- x509: 表示执行 X.509 相关的操作。
- -req: 表示该证书是由证书请求 (CSR) 生成的。
- -days 365: 指定证书的有效期,这里设置为 365 天,即一年。
- -in server.csr: 指定证书请求文件的路径和文件名,即之前生成的证书请求文件的路径和文件名。
- -signkey server.key: 指定用于签署证书的私钥文件的路径和文件名,即之前生成的私钥文件的路径和文件名。
- -out server.crt: 指定输出文件的路径和文件名,即生成的 X.509 证书的保存路径和文件名。
这个命令的作用是使用私钥 server.key 对证书请求 server.csr 进行签名,生成一个自签名的 X.509 证书,并将其保存为 server.crt 文件。这个证书可以用于配置安全的 HTTPS 服务。
- 上⾯ 8 个步骤配置完之后,直接在浏览器中访问 https://192.168.79.128/ ,地址栏会出现下⾯这种 情况。这是 因为这个证书没有经过验证。(正常开发还是要⽤第三⽅认证的 SSL)
- 当然前提需要 Nginx 已经配置了 https 服务,示例代码如下:
# 输⼊ https://127.0.0.1 即可访问 https://127.0.0.1:444的内容
# 使⽤openssl⽣成的SSL证书(仅供练习使⽤)
server {
listen 443 ssl;
server_name localhost;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass https://192.168.79.128:444;
}
}
server {
listen 80
listen [::]:80; # 表示监听可以用的 ipv6 端口
listen 443 ssl;
listen [::]:443;
server_name localhost;
ssl_certificate /nginx/ssl/server.crt;
ssl_certificate_key /nginx/ssl/server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# HTTP 的重定向到 HTTPS
if ($scheme = http) {
return 301 https://$host$request_uri;
}
location / {
root static/test2;
index index.html index.htm;
try_files $uri $uri/ @router;
}
# 重写路径 解决 vue 刷新404页面问题
location @router {
rewrite ^.*$ /index.html last;
}
# 代理后端端口
location /exam {
proxy_pass http://localhost:9999/exam;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Host $http_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;
proxy_read_timeout 1800s;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 修改 nginx.conf 文件之后 需要重启
nginx -s reload # 重新加载配置
systemctl restart nginx # 重启 Nginx
2
3
4
# 4.2.2 第三方认证证书使用 (必须要有域名)
阿里云 / 腾讯云平台,都可以申请免费的 SSL 证书,申请完成后,证书下载上传至服务器
Nginx 开启 https 的实例配置,并实现反向代理
# HTTPS server
# 使⽤第三⽅认证
server {
listen 443 ssl;
server_name www.utuai.com;
ssl_certificate /nginx/ssl/ca_bundle.pem; # 证书路径
ssl_certificate_key /nginx/ssl/ca_bundle.key; # 证书秘钥
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass https://192.168.79.128:444;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 5. 反向代理系统调优
反向代理值有: Buffer 和 Cache 两个,Buffer 理解为缓冲,Cache 理解为缓存
相同点:
- 两种方式都是用来提供 IO 吞吐效率,都是用来提升 Nginx 代理性能
不同点:
- 缓存主要用来解决不同设备之间数据传递速度不一致导致的性能低问题,缓冲中的数据一旦此次操作完成后,就可以删除
- 缓存主要是备份,将被代理服务器的数据缓存备份一份到代理服务器,这样的话,客户端再次获取相同数据的时候,就只需要从代理服务器上获取,效率较高,缓存中的数据可以重复使用,只有满足特定条件才会删除
# 5.1 相关指令
proxy_buffering指令
该指令⽤来开启或者关闭代理服务器的缓冲区
语法:proxy_buffering off | on; 默认值:on 可放在 http、server、location 块
proxy_buffers指令
该指令⽤来指定单个连接从代理服务器读取响应的缓存区的个数和⼤⼩(与系统平台有关)
语法:proxy_buffers number size; 默认值:8 4K | 8K 可放在 http、server、location 块
proxy_buffer_size指令
该指令⽤来设置从被代理服务器获取的第⼀部分响应数据的⼤⼩。(保持与 proxy_buffers 中的 size ⼀致即可,当然也可以更⼩)
语法:proxy_busy_buffers_size size; 默认值:8K | 16K 可放在 http、server、location 块
proxy_busy_buffers_size指令
该指令⽤来限制同时处于 BUSY 状态的缓冲总⼤⼩
语法:proxy_busy_buffers_size size; 默认值:8K | 16K 可放在 http、server、location 块
proxy_temp_path指令
该指令⽤来设置⽂件路径:当缓冲区存满后,仍未被 Nginx 服务器完全接受,响应数据就会被临时 存放在磁盘⽂件上 (注意:path 最多设置 3 层)
语法:proxy_temp_path path; 默认值:proxy_temp 可放在 http、server、location 块
proxy_temp_file_write_size指令
该指令⽤来设置磁盘上缓冲⽂件的⼤⼩
语法:proxy_temp_file_write_size size; 默认值:8K | 16K 可放在 http、server、location 块