相关推荐recommended
Nginx(4)nginx的反向代理
作者:mmseoamin日期:2024-01-19

反向代理

  • 正向代理
  • 反向代理的常用指令
    • 反向代理实战
    • Nginx的安全控制
      • 使用SSL对流量进行加密
      • nginx添加SSL的支持
      • Nginx的SSL相关指令
        • 生成证书
        • 反向代理系统调优

          正向代理代理的对象是客户端,反向代理代理的是服务端,这是两者之间最大的区别。Nginx即可以实现正向代理,也可以实现反向代理。

          正向代理

          先通过一个小案例演示下Nginx正向代理的简单应用,需求如下:

          Nginx(4)nginx的反向代理,在这里插入图片描述,第1张

          (1)服务端的设置:当客户端发送请求之后,需要在指定日志文件里面输出客户端的ip地址即可

          http {
           #指定日志格式
            log_format main 'client send request=>clientIp=$remote_addr serverIp=>$host';
          	server{
          		listen 80;
          		server_name	localhost;
          		#指定日志文件位置 和格式
          		access_log logs/access.log main;
          		location {
          			root html;
          			index index.html index.htm;
          		}
          	}
          }
          

          (2)使用客户端访问服务端,打开日志查看结果

          Nginx(4)nginx的反向代理,在这里插入图片描述,第2张

          (3)代理服务器设置:获取到客户端要访问服务端的ip以及端口

          server {
                  listen  82;
                  # 设置DNS的IP,用来解析proxy_pass中的域名
                  resolver 8.8.8.8;
                  location /{
                          proxy_pass http://$host$request_uri;
                  }
              }
          

          (4)查看代理服务器的IP(192.168.200.146)和Nginx配置监听的端口(82)

          (5)在客户端配置代理服务器

          Nginx(4)nginx的反向代理,在这里插入图片描述,第3张

          (6)设置完成后,再次通过浏览器访问服务端

          Nginx(4)nginx的反向代理,在这里插入图片描述,第4张

          通过对比,上下两次的日志记录,会发现虽然我们是客户端访问服务端,但是如何使用了代理,那么服务端能看到的只是代理发送过去的请求,这样的化,就使用Nginx实现了正向代理的设置。

          但是Nginx正向代理,在实际的应用中不是特别多,所以我们简单了解下,接下来我们继续学习Nginx的反向代理,这是Nginx比较重要的一个功能。

          反向代理的常用指令

          nginx反向代理模块的指令是由ngx_http_proxy_module模块进行解析,该模块在安装Nginx的时候已经自己加装到Nginx中了,常用指令如下:

          proxy_pass: 设置被代理服务器地址,可以是主机名称、IP地址加端口号形式

          语法proxy_pass URL;
          默认值
          位置location

          URL:是要设置的被代理服务器地址,包含传输协议(http,https://)、主机名称或IP地址加端口号、URI等要素。

          举例:客户端:192.168.200.1 代理服务器192.168.221.199 服务器 192.168.221.198

          代理服务器199的nginx配置

          server {
               listen 8081;
               server_name localhost;
               location / {
               # 设置访问服务器的nginx
                 proxy_pass http://192.168.221.198;
               }
          }
          

          在192.168.200.1上访问199的8081端口

          Nginx(4)nginx的反向代理,在这里插入图片描述,第5张

          在编写proxy_pass的时候,后面的值要不要加"/"?

          接下来通过例子来说明刚才提到的问题:

          server {
               listen 8081;
               server_name localhost;
               location / {
                 #proxy_pass http://192.168.221.198;
          		proxy_pass http://192.168.221.198/;
          		#以上两个访问效果是一样的
               }
          }
          
          server {
               listen 8081;
               server_name localhost;
               location /server {
                
                 #proxy_pass http://192.168.221.198;
                 #会将server拼接到ip后面,访问的是http://192.168.221.198/server/index.html
          		
          		proxy_pass http://192.168.221.198/; 
          	    #不拼接,访问的是http://192.168.221.198/index.html
               }
          }
          

          proxy_set_header: 更改Nginx服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理的服务器

          语法proxy_set_header field value;
          默认值proxy_set_header Host $proxy_host;
          proxy_set_header Connection close;
          位置http、server、location

          需要注意的是,如果想要看到结果,必须在被代理的服务器上来获取添加的头信息。

          被代理服务器: [192.168.221.198]

          server {
             listen 8081;
             server_name localhost;
             location / {
               default_type text/plain;
               return 200 $http_username;
            }
          }
          

          代理服务器: [192.168.221.199]

          server {
                  listen  8081;
                  server_name localhost;
                  location /server {
                          proxy_pass http://192.168.221.198:8081/;
                          proxy_set_header username TOM;
                  }
              }
          

          访问测试

          Nginx(4)nginx的反向代理,在这里插入图片描述,第6张

          proxy_redirect: 重置头信息中的Location和Refresh的值。

          语法proxy_redirect redirect replacement;
          proxy_redirect default;
          proxy_redirect off;
          默认值proxy_redirect default;
          位置http、server、location

          服务端[192.168.221.198]

          server {
              listen  8081;
              server_name localhost;
              # 请求资源不存在,临时重定向到index欢迎页面
             location / {
             			root html;
          			index index.html index.htm;
            	 if (!-f $request_filename){
              	    return 302 http://192.168.221.198/;
              }
            }
          }
          

          代理服务端[192.168.221.199]

          server {
          	listen  8081;
          	server_name localhost;
          	location / {
          	   # 请求跳转到198
          		proxy_pass http://192.168.221.198:8081/;
          	}
          }
          

          请求http://192.168.221.199:8081/abc.html时,页面不存在,返回302跳转到192.168.221.198,看到了真实服务器的地址,在现实开发中是不安全的

          Nginx(4)nginx的反向代理,在这里插入图片描述,第7张

          Nginx(4)nginx的反向代理,在这里插入图片描述,第8张

          修改代理服务器[192.168.221.199]

          server {
          	listen  8081;
          	server_name localhost;
          	location / {
          		proxy_pass http://192.168.221.198:8081/;
          		# 将真实ip替换为代理服务器的ip地址
          		proxy_redirect http://192.168.221.198/  http://192.168.221.199/;
          	}
          }
          server {
          	listen  80;
          	server_name localhost;
          	location / {
          	    #将代理服务器的首页换成真实服务器的
          		proxy_pass http://192.168.221.198/;
          	}
          }
          

          Nginx(4)nginx的反向代理,在这里插入图片描述,第9张

          Nginx(4)nginx的反向代理,在这里插入图片描述,第10张

          proxy_redirect redirect replacement;

          redirect:目标Location的值
          replacement:要替换的值
          

          proxy_redirect default;

          default 有了默认选项
          将location块的uri变量作为replacement,
          将proxy_pass变量作为redirect进行替换
          

          proxy_redirect off

          关闭proxy_redirect的功能
          

          反向代理实战

          Nginx(4)nginx的反向代理,在这里插入图片描述,第11张

          服务器1,2,3存在两种情况

          第一种情况:三台服务器的内容不一样。
          第二种情况: 三台服务器的内容是一样。
          
          1. 如果服务器1、服务器2和服务器3的内容不一样,可以根据用户请求来分发到不同的服务器。(根据端口区分不同服务器)
          代理服务器 [192.168.221.199]
          server {
                  listen          8082;
                  server_name     localhost;
                  location /server1 {
                          proxy_pass http://192.168.221.198:9001/;
                  }
                  location /server2 {
                          proxy_pass http://192.168.221.198:9002/;
                  }
                  location /server3 {
                          proxy_pass http://192.168.221.198:9003/;
                  }
          }
          服务端[192.168.221.198]
          server {
                  listen          9001;
                  server_name     localhost;
                  default_type text/html;
                  return 200 '

          192.168.200.198:9001

          ' } server { listen 9002; server_name localhost; default_type text/html; return 200 '

          192.168.200.198:9002

          ' } server { listen 9003; server_name localhost; default_type text/html; return 200 '

          192.168.200.198:9003

          ' }

          Nginx(4)nginx的反向代理,在这里插入图片描述,第12张

          Nginx(4)nginx的反向代理,在这里插入图片描述,第13张

          Nginx(4)nginx的反向代理,在这里插入图片描述,第14张

          1. 如果服务器1、服务器2和服务器3的内容是一样的,该如何处理?参考nginx负载均衡

          Nginx的安全控制

          关于web服务器的安全是比较大的一个话题,里面所涉及的内容很多,Nginx反向代理是如何来提升web服务器的安全呢?

          通过代理分开了客户端到应用程序服务器端的连接,实现了安全措施。在反向代理之前设置防火墙,仅留一个入口供代理服务器访问。

          Nginx(4)nginx的反向代理,在这里插入图片描述,第15张

          使用SSL对流量进行加密

          就是将常用的http请求转变成https请求,这两个之间的区别简单的来说两个都是HTTP协议,只不过https是身披SSL外壳的http。

          HTTPS是一种通过计算机网络进行安全通信的传输协议。它经由HTTP进行通信,利用SSL/TLS建立全通信,加密数据包,确保数据的安全性。

          • SSL(Secure Sockets Layer)安全套接层
          • TLS(Transport Layer Security)传输层安全

            上述这两个是为网络通信提供安全及数据完整性的一种安全协议,TLS和SSL在传输层和应用层对网络连接进行加密。

            为什么要使用https

            http协议是明文传输数据,存在安全问题,而https是加密传输,相当于http+ssl,并且可以防止流量劫持。
            

            Nginx要想使用SSL,需要满足一个条件即需要添加一个模块--with-http_ssl_module,默认没有支持,需要自己添加,该模块在编译的过程中又需要OpenSSL的支持,需提前准备【参考nginx源码安装】。

            nginx添加SSL的支持

            完成 --with-http_ssl_module模块的增量添加

            拷贝nginx之前的配置信息

            将原有/usr/local/nginx/sbin/nginx进行备份

            Nginx(4)nginx的反向代理,在这里插入图片描述,第16张

            在nginx的安装源码进行配置指定对应模块 ./configure --with-http_ssl_module

            Nginx(4)nginx的反向代理,在这里插入图片描述,第17张

            通过make模板进行编译

            Nginx(4)nginx的反向代理,在这里插入图片描述,第18张

            将objs下面的nginx移动到/usr/local/nginx/sbin下

            在源码目录下执行 make upgrade进行升级,这个可以实现不停机添加新模块的功能

            Nginx(4)nginx的反向代理,在这里插入图片描述,第19张

            Nginx的SSL相关指令

            该模块的指令都是通过ngx_http_ssl_module模块来解析的。

            ssl: 用来在指定的服务器开启HTTPS,可以使用 listen 443 ssl,后面这种方式更通用些。

            语法ssl on | off;
            默认值ssl off;
            位置http、server
            server{
            	listen 443 ssl; #等值于 ssl on
            }
            

            ssl_certificate: 为当前这个虚拟主机指定一个带有PEM格式证书的证书。

            语法ssl_certificate file;
            默认值
            位置http、server

            ssl_certificate_key: 该指令用来指定PEM secret key文件的路径

            语法ssl_ceritificate_key file;
            默认值
            位置http、server

            ssl_session_cache: 该指令用来配置用于SSL会话的缓存

            语法ssl_sesion_cache off|none|[builtin[:size]] [shared:name:size]
            默认值ssl_session_cache none;
            位置http、server

            off:禁用会话缓存,客户端不得重复使用会话

            none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数

            builtin:内置OpenSSL缓存,仅在一个工作进程中使用。

            shared:所有工作进程之间共享缓存,缓存的相关信息用name和size来指定

            name:缓存名称

            size:缓存大小 提升缓存效率

            ssl_session_timeout: 开启SSL会话功能后,设置客户端能够反复使用储存在缓存中的会话参数时间。

            语法ssl_session_timeout time;
            默认值ssl_session_timeout 5m;
            位置http、server

            ssl_ciphers: 指出允许的密码,密码指定为OpenSSL支持的格式

            语法ssl_ciphers ciphers;
            默认值ssl_ciphers HIGH:!aNULL:!MD5;
            位置http、server

            使用openssl ciphers查看openssl支持的格式

            Nginx(4)nginx的反向代理,在这里插入图片描述,第20张

            ssl_prefer_server_ciphers: 指定是否服务器密码优先客户端密码

            语法ssl_perfer_server_ciphers on|off;
            默认值ssl_perfer_server_ciphers off;
            位置http、server

            生成证书

            需要生成带有PEM格式的证书和指定PEM secret key的证书

            方式一:使用阿里云/腾讯云等第三方服务进行购买。

            参考从阿里云上申请ssl证书,配置https

            使用域名,去掉url地址栏不安全标示

            # 地址栏访问https://www.nginx521.cn
            server {
                    listen       443 ssl;
                    server_name  www.nginx521.cn; 
                    ssl_certificate      /root/nginx_cert/www.nginx521.cn.key;
                    ssl_certificate_key  /root/nginx_cert/www.nginx521.cn.pem;
                  
                    #会话缓存 共享缓存:缓存名称:缓存大小
                    ssl_session_cache    shared:SSL:1m;
                    #超时时间 5min
                    ssl_session_timeout  5m;
                    # 允许的密码格式
                    ssl_ciphers  HIGH:!aNULL:!MD5;
                    # 是否允许服务器密码优先于客户端密码
                    ssl_prefer_server_ciphers  on;
                
                    location / {
                        root   html;
                        index  index.html index.htm;
                    }
                }
            # 不加https直接域名访问www.nginx521.cn
             server {
                    listen       80;
                    server_name  www.nginx521.cn;
                    
                    location / {
                    #root html;
                    #index index.html index.htm;
                    rewirte ^(.*) https://www.nginx521.cn;
                    }
            

            方式二:使用openssl生成证书

            确认当前系统是否有安装openssl

            openssl version
            

            Nginx(4)nginx的反向代理,在这里插入图片描述,第21张

            按照下面的命令进行生成

            mkdir /root/cert
            cd /root/cert
            #生存对应的server.key
            openssl genrsa -des3 -out server.key 1024 
            # 生存csr
            openssl req -new -key server.key -out server.csr
            cp server.key server.key.org
            openssl rsa -in server.key.org -out server.key
            openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
            

            Nginx(4)nginx的反向代理,在这里插入图片描述,第22张

            Nginx(4)nginx的反向代理,在这里插入图片描述,第23张

            Nginx(4)nginx的反向代理,在这里插入图片描述,第24张

            开启SSL实例

            server {
                    listen       443 ssl;
                    server_name  localhost; 
                    ssl_certificate      /root/cert/server.crt;
                    ssl_certificate_key  /root/cert/server.key;
                  
                    #会话缓存 共享缓存:缓存名称:缓存大小
                    ssl_session_cache    shared:SSL:1m;
                    #超时时间 5min
                    ssl_session_timeout  5m;
                    # 允许的密码格式
                    ssl_ciphers  HIGH:!aNULL:!MD5;
                    # 是否允许服务器密码优先于客户端密码
                    ssl_prefer_server_ciphers  on;
                
                    location / {
                        root   html;
                        index  index.html index.htm;
                    }
                }
            

            验证 访问https://192.168.221.199

            Nginx(4)nginx的反向代理,在这里插入图片描述,第25张

            Nginx(4)nginx的反向代理,在这里插入图片描述,第26张

            反向代理系统调优

            反向代理值Buffer和Cache,详情参考【nginx缓存】

            Buffer翻译过来是"缓冲",Cache翻译过来是"缓存"。

            Nginx(4)nginx的反向代理,在这里插入图片描述,第27张

            相同点:
            两种方式都是用来提供IO吞吐效率,都是用来提升Nginx代理的性能。
            不同点:
            缓冲主要用来解决不同设备之间数据传递速度不一致导致的性能低的问题,缓冲中的数据一旦此次操作完成后,就可以删除。
            缓存主要是备份,将被代理服务器的数据缓存一份到代理服务器,这样的话,客户端再次获取相同数据的时候,就只需要从代理服务器上获取,效率较高,缓存中的数据可以重复使用,只有满足特定条件才会删除.
            

            Proxy Buffer相关指令

            proxy_buffering : 用来开启或者关闭代理服务器的缓冲区

            语法proxy_buffering on|off;
            默认值proxy_buffering on;
            位置http、server、location

            proxy_buffers: 用来指定单个连接从代理服务器读取响应的缓存区的个数和大小

            语法proxy_buffers number size;
            默认值proxy_buffers 8 4k | 8K;(与系统平台有关)
            位置http、server、location

            number:缓冲区的个数

            size:每个缓冲区的大小,缓冲区的总大小就是number*size

            proxy_buffer_size: 用来设置从被代理服务器获取的第一部分响应数据的大小。保持与proxy_buffers中的size一致即可,当然也可以更小。

            语法proxy_buffer_size size;
            默认值proxy_buffer_size 4k | 8k;(与系统平台有关)
            位置http、server、location

            proxy_busy_buffers_size: 用来限制同时处于BUSY状态的缓冲总大小。

            语法proxy_busy_buffers_size size;
            默认值proxy_busy_buffers_size 8k|16K;
            位置http、server、location

            proxy_temp_path: 当缓冲区存满后,仍未被Nginx服务器完全接受,响应数据就会被临时存放在磁盘文件上,该指令设置文件路径

            语法proxy_temp_path path;
            默认值proxy_temp_path proxy_temp;
            位置http、server、location

            注意path最多设置三层。

            proxy_temp_file_write_size: 用来设置磁盘上缓冲文件的大小。

            语法proxy_temp_file_write_size size;
            默认值proxy_temp_file_write_size 8K|16K;
            位置http、server、location

            通用网站的配置

            proxy_buffering on;
            proxy_buffer_size 4 32k;
            proxy_busy_buffers_size 64k;
            proxy_temp_file_write_size 64k;
            

            根据项目的具体内容进行相应的调节