Nginx如何反向代理、延时响应、SLL

在前端生态中,代理服务扮演着重要的角色。代理服务是指一种中间层服务,用于在前端应用程序和后端服务器之间进行请求转发和数据交互。它可以提供以下功能和优势:

  1. 跨域请求:代理服务可以解决浏览器的同源策略限制,使前端应用可以从不同的域名或端口请求数据。通过代理服务,前端应用可以将请求发送到同一域名下的代理服务器,并由代理服务器转发到目标服务器,从而避免跨域限制。
  2. 安全性和隐私保护:代理服务可以在前端和后端之间充当安全屏障,隐藏后端服务器的真实地址和细节。通过代理服务,可以实现安全的数据传输、身份验证和访问控制,保护后端服务器的安全性,并提供额外的隐私保护。
  3. 缓存和性能优化:代理服务可以缓存静态资源或响应结果,以减轻后端服务器的负载,并提高前端应用的性能。通过在代理层缓存数据,可以减少对后端的请求次数,加快响应速度,并减少对网络带宽的占用。
  4. 请求转发和路由:代理服务可以根据特定的规则和条件将请求转发到不同的后端服务器,实现请求的负载均衡、路由和分发。这使得前端应用可以灵活地根据需求将请求发送到不同的服务实例或后端集群。
  5. 日志记录和监控:代理服务可以记录请求和响应的日志,并提供监控和分析功能。通过代理服务,可以收集关于请求流量、性能指标和错误日志的信息,帮助进行故障排查、性能优化和系统监控。

总而言之,代理服务在前端生态中扮演着关键的角色,提供了跨域请求、安全性、性能优化、请求转发和监控等功能。它在构建现代前端应用中发挥着重要作用,帮助开发人员解决跨域问题、提高性能并提供更好的用户体验。

安装nginx

这里我们以 nginx/1.12.2 为例。需要获取源码:

1
2
3
$ cd /opt/
$ wget http://nginx.org/download/nginx-1.12.2.tar.gz
$ tar -zxvf nginx-1.12.2.tar.gz

编译安装

1
2
3
$ cd /opt/nginx-1.12.2/
$ sudo make -j2
$ sudo make install

make install 后,会覆盖之前安装的 NginxMac 通常会安装在 /usr/local/ 目录下。

Nginx配置反向代理

在 Nginx 中配置反向代理非常简单。下面是一个基本的反向代理配置示例:

编辑 Nginx 配置文件:

1
$ sudo vim /usr/local/nginx/conf/nginx.conf 

添加如下配置项:

1
2
3
4
5
6
7
8
server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend_server;
}
}

启动 Nginx

1
$ sudo /usr/local/nginx/sbin/nginx

如果已经启动了,执行下面命令重新加载配置文件:

1
$ sudo /usr/local/nginx/sbin/nginx -s reload

如果想要停止服务,执行下面命令:

1
$ sudo /usr/local/nginx/sbin/nginx -s stop

在上述示例中,我们创建了一个服务器块(server block),监听 example.com 的端口 80。在 location / 块中,我们使用了 proxy_pass 指令将请求代理到名为 backend_server 的后端服务器。

确保将 example.com 替换为您的域名或服务器 IP,将 backend_server 替换为实际的后端服务器地址。

Nginx配置延迟响应

echo-nginx-module 是一个用于 NGINX 的第三方模块,它允许在 NGINX 中进行自定义响应的生成和处理。该模块提供了一些指令和变量,可以用来构建自定义的响应内容。可以使用它来实现延时响应:

获取 echo-nginx-module 源代码,我们下载最新稳定版(截止到2018-12-23),并解压,不用安装

1
2
3
$ cd /opt
$ wget https://github.com/openresty/echo-nginx-module/archive/v0.61.tar.gz
$ tar zxvf v0.61.tar.gz

编译 Nginx 并添加 echo-nginx-module

1
2
$ cd /opt/nginx-1.12.2/
$ ./configure --prefix=/usr/local/nginx --add-module=/opt/echo-nginx-module-0.61

请将 /opt/echo-nginx-module-0.61 替换为您实际存放 echo-nginx-module 源代码的路径。

运行上面的 ./configure 后进行编译安装:

1
$ sudo make install

make install 后,会覆盖之前安装的Nginx

配置延时响应

在 /usr/local/nginx/conf/nginx.conf 中 server 代码块里加入如下代码:

1
2
3
4
5
6
7
location /hello_echo { 
# 延时 5 秒
set $delay 5;
echo_sleep $delay;
default_type 'text/plain';
echo "Delayed response after 5 seconds";
}

重新加载配置文件:

1
$ sudo /usr/local/nginx/sbin/nginx -s reload

Nginx配置SSL

with-http_ssl_module 是 NGINX 的一个编译选项,用于在构建 NGINX 时添加支持 SSL/TLS 的功能模块。

SSL(Secure Sockets Layer)和其继任者 TLS(Transport Layer Security)是用于加密网络通信的协议。它们允许在客户端和服务器之间建立安全的加密连接,以保护数据的机密性和完整性。

通过配置 NGINX 编译时加入 with-http_ssl_module,你可以启用 NGINX 的 SSL/TLS 功能。这样,NGINX 将能够处理加密连接、支持 HTTPS 协议以及提供 SSL/TLS 相关的配置指令。

要使用 with-http_ssl_module,你需要按照以下步骤编译 NGINX

1、配置 with-http_ssl_module 模块
Nginx 配置 SSL 需要配置 http_ssl_module 模块

1
2
3
$ cd /opt/nginx-1.12.2/
$ ./configure --prefix=/usr/local/nginx --with-http_ssl_module
$ sudo make install

2、生成私钥和自签名证书
创建任意名文件夹,假设为~/ssl, 在其中新建文件 sslConfigureFile.conf

1
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
[ req ]

default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only

[ subject ]

countryName = Country Name (2 letter code)
countryName_default = CN

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = JiangSu

localityName = Locality Name (eg, city)
localityName_default = Nanjing

organizationName = Organization Name (eg, company)
organizationName_default = Example, LLC

commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Example Company

emailAddress = Email Address
emailAddress_default = test@example.com

[ x509_ext ]

subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer

basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"

[ req_ext ]

subjectKeyIdentifier = hash

basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"

[ alternate_names ]

DNS.1 = local.cmsk1979.com # 此处需要改为本地域名, 如有需要可配合/etc/hosts修改

执行命令生成证书文件:

1
openssl req -config sslConfigureFile.conf -new -sha256 -newkey rsa:2048 -nodes -keyout ssl.key -x509 -days 365 -out ssl.crt

注:sslConfigureFile.conf文件路径一定要准确

按提示执行完该命令后,将生成以下文件

1
2
~/ssl/ssl.key
~/ssl/ssl.crt

3、信任证书
双击生成的证书进入“钥匙串访问”,找到对应的证书

双击,选择始终信任,浏览器访问就不会提示“不安全访问”

4、将私钥和证书文件复制到适当的位置

将生成的私钥文件 ssl.key 和证书文件 ssl.crt 复制到 Nginx 配置文件所在的目录(/usr/local/ssl)。

5、配置 Nginx 使用自签名证书
打开 Nginx 的配置文件(通常是 /usr/local/nginx/conf/nginx.conf)。

在适当的 server 块中,添加以下 SSL/TLS 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 443 ssl;
server_name local.cmsk1979.com;

ssl_certificate /usr/local/ssl/ssl.crt;
ssl_certificate_key /usr/local/ssl/ssl.key;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

# 其他 Nginx 配置...
location /hello {
default_type 'text/plain';
return 200 'hello!';
}
}

6、配置hosts

1
2
127.0.0.1    www.local.cmsk1979.com
127.0.0.1 local.cmsk1979.com

7、重新加载配置文件:

1
sudo /usr/local/nginx/sbin/nginx -s reload

注意:访问时不能开启VPN代理,不然可能出现访问失败

访问结果:

加上延时响应

将 http_ssl_module 模块和 echo-nginx-module 编译到 Nginx 中:

1
2
3
$ cd /opt/nginx-1.12.2/
$ ./configure --prefix=/usr/local/nginx --with-http_ssl_module --add-module=/opt/echo-nginx-module-0.61
$ sudo make install

在适当的 server 块中,添加 SSL/TLS 和延时响应的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 443 ssl;
server_name local.cmsk1979.com;

ssl_certificate /usr/local/ssl/ssl.crt;
ssl_certificate_key /usr/local/ssl/ssl.key;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

# 其他 Nginx 配置...
location /hello {
set $delay 5;
echo_sleep $delay;
default_type 'text/plain';
echo "Delayed response after 5 seconds";
}
}

加上反向代理

以反向代理获取 https://mstatic.cassmall.com/assets/sensors/sensorsdata1.19.4.min.js 为例,在适当的 server 块中,添加 SSL/TLS 和延时响应、反向代理的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 443 ssl;
server_name local.cmsk1979.com;

ssl_certificate /usr/local/ssl/ssl.crt;
ssl_certificate_key /usr/local/ssl/ssl.key;

ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;

# 其他 Nginx 配置...
location /assets/sensors {
set $delay 5;
echo_sleep $delay;
# 传递客户端请求的头信息给目标服务器
proxy_pass https://mstatic.cassmall.com;
}
}

可以看到代理访问是成功的,但是延时响应的配置没有生效

这是因为 echo_sleep 是 echo-nginx-module 提供的内容处理程序,而 proxy_pass 是 ngx_http_proxy_module 提供的内容处理程序,如果在单个位置中使用这两个不同的内容处理程序,它们将发生冲突(因为 Nginx 只允许单个处理程序),并且只有一个会生效(哪个会生效是不确定的)。

在 GitHub 有一个 issuehttps://github.com/openresty/echo-nginx-module/issues/5

如果我们对调一些配置的顺序:

1
2
3
4
5
6
location /assets/sensors {
# 传递客户端请求的头信息给目标服务器
proxy_pass https://mstatic.cassmall.com;
set $delay 5;
echo_sleep $delay;
}

可以看到延时响应生效,而反向代理配置没有生效

下面给出了一个解决办法,你可以使用 echo_location 来向由 proxy_pass 配置的位置发送子请求,像这样:

1
2
3
4
5
6
7
8
9
10
11
12
# 定义一个命名位置
location /proxy/ {
rewrite ^/proxy/(.*)$ /$1 break;
proxy_pass https://mstatic.cassmall.com;
}

location /assets/sensors {
set $delay 5;
echo_sleep $delay;
# 使用echo_location发送子请求到/proxy位置
echo_location /proxy/$uri;
}

返回的脚本内容呈现乱码

修改配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 定义一个命名位置
location /proxy/ {
rewrite ^/proxy/(.*)$ /$1 break;
proxy_pass https://mstatic.cassmall.com;
proxy_set_header Accept-Encoding "";
proxy_set_header Accept-Language $http_accept_language;
proxy_set_header Content-Type "text/javascript; charset=utf-8";
}

location /assets/sensors {
set $delay 5;
echo_sleep $delay;
# 使用echo_location发送子请求到/proxy位置
echo_location /proxy/$uri;
}