Nginx应用案例篇二(反向代理,负载均衡,SSL安全控制)

发布于 2021-09-10  7.47k 次阅读


一,Nginx反向代理

一,nginx反向代理的配置指令

Nginx反向代理的指令是由ngx_http_proxy_module模块进行解析的,该模块在安装nginx的时候已经内置了

反向代理常用指令有三个:

  • proxy_pass
  • proxy_set_header
  • proxy_redirect

一,proxy_pass指令

该指令用来设置被代理服务器地址,可以是主机名,IP地址:端口,域名等形式

语法 proxy_pass URL
默认值 -
配置位置 location块

URL:设置被代理服务器地址,包含传输协议(http,https://),主机名或IP地址或域名等

二,proxy_set_header指令

该指令可以更改nginx服务器接收到的客户端的请求头信息,然后可以重新修改请求头转发给被代理服务器

语法 proxy_set_header field value
默认值 proxy_set_header Host $proxy_host

proxy_set_header Connection close

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

注:如果需要看结果必须在被代理服务器上来获取添加的头信息

三,proxy_redirect指令

该指令用来重置头信息中的"Location"和"Refresh",主要用于当使用rewrite重写了代理服务器跳转到被代理服务器,浏览器输入代理服务器地址会暴露真实的被代理服务器地址,这个指令可以做隐藏

语法 proxy_redirect cedirect replacement

proxy_redirect default

proxy_redirect off

默认值 -
配置位置 location块
  • cedirect:真实的服务器地址
  • replacement:需要被隐藏成什么地址

二,nginx反向代理演示案例

前提准备:准备两台虚拟机,分别安装有nginx

机器一:192.168.68.133

机器二:192.168.68.153

机器一做为代理服务器,机器二作为被代理服务器

1,配置服务器

server {

        listen 8888;
        server_name localhost;

        location /{
        default_type text/html;
        return "<h1>192.168.68.153:8888<h1>"
}}

  server {

        listen 8889;
        server_name localhost;
        location /{
        default_type text/html;
        return "<h1>192.168.68.153:8889<h1>"
        }
        }
  server {

        listen 8890;
        server_name localhost;
        location /{  
        default_type text/html;
        return "<h1>192.168.68.153:8890<h1>"
}}

2,配置反向代理服务器

server {

        listen 8033;
        server_name localhost;

        locat /server1 {
        proxy_pass http://192.168.68.153:8888;
        }

        locat /server2 {
        proxy_pass http://192.168.68.153:8889;
        }

        locat /server3 {
        proxy_pass http://192.168.68.153:8890;
        }}

3,访问

二,Nginx负载均衡

一,nginx负载均衡的原理和流程

系统拓展可以分为纵向拓展和横向拓展

  • 纵向拓展:从单机的角度出发,通过增加系统的硬件处理能力来提示服务器的处理能力
  • 横向拓展:通过添加机器满足大型互联网服务处理能力

负载均衡就是横向拓展的结果,横向拓展机器,如何协调多台机器和请求的合理分发就成了负载均衡需要解决的问题

负载均衡主要有两个重要角色:

  • 应用集群:将同一应用部署到多台机器上,组成处理集群,接收负载均衡设备分发的请求,进行处理和返回数据
  • 负载均衡器:将用户访问的请求根据对应的负载均衡算法,分发到集群中的某一台主机上

通过负载均衡器来协调应用集群

二,四层负载均衡和七层负载均衡

四层/七层负载均衡是OSI网络模型来进行区别的

1,四层负载均衡指的是OSI七层模型中的传输层,主要基于IP+PORT实现负载

实现四层负载均衡的方式:

  • 硬件:F5,BIN-IP,Radware等
  • 软件:LVS,Nginx,Hayproxy等

2,七层负载均衡指的是应用层上的负载,主要基于URL和IP实现

实现七层负载均衡的方式:

  • 软件:Nginx,hayproxy

3,四层和七层负载均衡的区别

  1. 四层负载均衡数据包在底层进行分发,而七层负载均衡数据包在最顶端进行分发,所有四层负载均衡的效率比七层要高
  2. 四层负载均衡不识别域名,而七层负载均衡识别域名

注:除了四层和七层还有二层,三层负载均衡,二层是在数据链路层基于mac地址来实现负载均衡,三层是在网络层采用虚拟IP地址的方式实现负载均衡

生成环境中我们采用:四层负载(LVS)+七层负载(Nginx)

三,Nginx七层负载均衡的配置命令

Nginx要实现七层负载均衡要用到proxy_pass代理模块配置,Nginx默认安装支持这个模块,我们不需要再做任何处理,Nginx的负载均衡是在Nginx的反向代理基础上把请求根据指定的策略分发到一组upstream虚拟服务池

一,upstream指令

该指令用来定义一组服务器,它们可以是监听不同端口的服务器,并且也可以是同时监听TCP和Unix socket服务器,服务器可以指定不同的权重,默认为1

语法 upstream name{……}
默认值 -
配置位置 http块

二,server指令

该指令用来指定后端服务器的名称和一些参数,可以使用域名,IP,端口或者unix socket

语法 server name [paramerters]
默认值 -
配置位置 upstream

三,配置演示

#把需要做负载的集群机器的IP或者域名放入upstream服务器池中(演示通过端口号来区分)
upstream wql{

    server 192.168.68.53:9001;
    srever 192.168.68.53:9002;
    server 192.168.68.53:9003
}

#通过proxy_pass代理服务器池
server {
    listen 8033;
    server_name localhost;
#proxy_pass后面接upstream名称
    proxy_pass http://wql;
}

四,Nginx负载均衡的状态

代理服务器在负责均衡调度的状态有以下几个:

状态 解释
down 当前的server暂时不参与负载均衡
backup 预留备份服务器
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后,服务器暂停时间
max_conns 限制最大的接收连接数

1,down:将该服务标记成永久不可用,那么该代理服务器将不参与负载均衡

upstream wql{
    server 192.168.68.53:9001 down;
    srever 192.168.68.53:9002;
    server 192.168.68.53:9003
}

注:该状态一般会对需要停机维护的服务器进行设置

2,backup:将该服务器标记为备份服务器,当主服务器不可用时,将用来传递请求

upstream wql{

    server 192.168.68.53:9001 down;
    srever 192.168.68.53:9002 backup;
    server 192.168.68.53:9003
}

只需要将9001的端口的访问禁止掉模拟下唯一能对外访问的服务器,backup的备份服务器就会对外提供服务

五,Nginx支持的负载均衡策略

Nginx的upstream支持如下六种方式的分配算法:

  • 轮询:默认方式
  • weight:权重方式
  • ip_hash:依据ip分配方式
  • least_conn:依据最少连接方式
  • url_hash:依据URL分配方式
  • fair:依据响应时间方式

1,轮询

轮询是upstream模块负载均衡默认的策略,每一个请求都会按照时间顺序逐个分配到不同的后端服务器(它不需要额外配置)

轮询是一个固定策略,它依次将请求分配到集群上的不同机器中,如果服务器的配置都相对一致的话还好,如果服务器高低配置不一样,高配置和低配置都是通用的访问量,不能动态调整

upstream wql{

    server 192.168.68.53:9001;
    srever 192.168.68.53:9002;
    server 192.168.68.53:9003;

}

2,加权轮询(weight加权)

weight=number:用来设置服务器的权重,默认1,权重数据越大,被分配到请求的机率越大,权重主要针对实际工作环境中不同的后端服务器硬件配置进行调整的,此策略比较适合服务器的硬件配置差别较大的情况

upstream wql{

    server 192.168.68.53:9001 weight=50;
    srever 192.168.68.53:9002 weight=100;
    server 192.168.68.53:9003 weight=150;
}

3,ip_hash3

session不共享问题:在不同的web服务器中session是不能共享的,如果用户访问访问一个网站需要登录账号和密码,那么它轮询访问不同的服务器都必须输入多次账号和密码

解决session不共享问题:

  1. 根本解决:使用中间缓存服务器(如:redis,memcache),将多台web服务器的session放入缓存,使用一个共有的缓存容器来实现共享
  2. 直接解决:使用ip_hash或者url_hash对访问的ip和url进行hash,让访问用户请求定位到某一台web服务器

ip_hash:当对后端的多台动态应用做负载均衡时,ip_hash指令能够将某个客户端IP的请求通过哈希算法定位到同一台后端服务器上,这样,当来自于IP的用户在服务器A登录后,那么之后的访问请求也会由服务器A就行处理

语法 ip_hash
默认值 -
配置位置 upstream
upstream wql{

    #直接写即可
        ip_hash;
    server 192.168.68.53:9001 weight=50;
    srever 192.168.68.53:9002 weight=100;
    server 192.168.68.53:9003 weight=150;
}

ip_hash的弊端:ip_hash无法保证服务器的负载均衡,可能导致一些后端服务器接收的请求多,一些后端服务器请求少,而且设置后端服务器权重等方法将不起作用

4,url_hash

url_hash和ip_hash的区别:

  • ip_hash:对访问的客户端IP地址就行hash,对同一个ip指定同一个web服务器
  • url_hash:对访问的url就行hash,对同一个url地址指定同一个web服务器

注:url_hash主要针对静态资源的访问,同一个静态资源的url可以用同一个web服务器处理,可以增加效率

url_hash:按照访问url的hash结果来分配请求,使每一个url定向由同一个后端服务器

url_hash要配合缓存命中来使用,同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源的多次下载,而url_hash可以使得同一个url(也就是同一个资源)会到达同一台服务器,一台服务器对访问的资源进行缓存,之后的就可以直接从服务器缓存中取

命令:hash &request_uri;

upstream wql{

    #直接写即可
    hash &request_uri;
    server 192.168.68.53:9001 weight=50;
    srever 192.168.68.53:9002 weight=100;
    server 192.168.68.53:9003 weight=150;
}

5,least_conn

最少连接,把请求转发给连接数较少的后端服务器,轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同,但是有些请求占用的时间很长,会导致所在的后端负载较高,这种情况下,least_conn这种方式就可以达到更好的负载均衡效果

适应场景:它适合请求处理时间长短不一造成服务器过载的情况

命令:least_conn

upstream wql{

    #直接写即可
    least_conn;
    server 192.168.68.53:9001 weight=50;
    srever 192.168.68.53:9002 weight=100;
    server 192.168.68.53:9003 weight=150;
}

6,fair(第三方模块进行负载均衡)

fair采用的不是nginx内置负载均衡算法,它是第三方提供的负载策略(需要单独安装)

fair可以根据页面的大小,加载时间长短智能进行负载均衡

使用fair需要添加nginx-upstream-fair模块(步骤):

① 下载nginx-upstream-fair模块

下载地址:https://github.com/gnosek/nginx-upstream-fair

② 将下载的安装包上传进服务器并解压

unzip nginx-upstream-fair-master.zip

③ 方便操作对解压文件进行重命名

mv nginx-upstream-fair-master fair

④ 使用./configure命令将资源添加到nginx模块中(模块添加都需要使用./configure)

./configure --add-module=fire的安装目录

⑤ make编译(源码目录下编译)

make

如果编译出现错误:

解决方法:

找到Nginx的源码目录src/http/ngx_http_upstream.h文件,在ngx_http_upstream_srv_conf_s模块位置添加default_port属性

in_port_t             default_port

⑥ 将sbin目录的nginx进行备份

mv nginx nginxwql

⑦ 拷贝make编译后的objs下的nginx文件到/usr/local/nginx/sbin目录中

#/home/nginx-1.18.0/objs/nginx是我安装的源码目录
cp /home/nginx-1.18.0/objs/nginx /usr/local/nginx/sbin

⑧ 对nginx进行更新(进入源码目录才能更新)

make upgrade

六,nginx负载均衡小案例

案例一:对所有请求实现一般轮询规则的负载均衡

upstream wql{

    server 192.168.68.53:9001;
    srever 192.168.68.53:9002;
    server 192.168.68.53:9003;
}

server {
    listen 8033;
    server_name localhost;
    location /{
        proxy_pass http://wql
}}

案例二:对所有请求实现加权轮询规则的负载均衡(5:3:2)

upstream wql{

    server 192.168.68.53:9001 weight=5;
    srever 192.168.68.53:9002 weight=3;
    server 192.168.68.53:9003 weight=2;
}

server {
    listen 8033;
    server_name localhost;
    location /{
        proxy_pass http://wql
}}

案例三:对特定资源实现负载均衡

upstream wql{
    server 192.168.68.53:9001;
    srever 192.168.68.53:9002;
}

upstream fq{
    server 192.168.68.9003;
    server 192.168.68.9004;
}

server {

    listen 8033;
    server_name localhost;
    location /view{
        proxy_pass http://wql
    }

    location /molude{
        proxy_pass http://fq
    }}

案例四:对不同域名进行负载均衡

upstream wql{

    server 192.168.68.53:9001;
    srever 192.168.68.53:9002;
}
upstream fq{

    server 192.168.68.9003;
    server 192.168.68.9004;
}

server {

    listen 8033;
    server_name www.wql.com;
    location /{
        proxy_pass http://wql
    }}

server {
    listen 80;
    server_name wql.luoqin.ltd
    location /{
        proxy_pass http://fq
    }
}

三,SSL安全控制

一,nginx实现安全的方式

web服务器对于安全一直是一个比较大的话题,这里涉及的内容有很多(主要为网络安全),nginx也能做一些安全内容来提示web服务器的安全性

nginx主要通过两种方式:

  • 安全隔离
  • SSL数据加密

一,安全隔离

安全隔离依赖于反向代理,通过代理服务器把浏览器和真实服务器进行隔离,避免浏览器直接访问真实服务器

使用代理进行安全隔离的好处:

  1. 浏览器不能直接访问web服务器,无法直接对服务器进行攻击
  2. 黑客通过代理服务器攻击真实web,只需要对代理服务器进行安全管理进行,保证代理服务器不被攻破
  3. 代理服务器可以代理多台web服务器,节省了安全成本

安全隔离的配置(其实就是反向代理的配置):

1,web服务器关闭防火墙,只对代理服务器开发端口

2,代理服务器,反向代理web服务器,对请求进行拦截分发

二,SSL数据加密

SSL是一个安全套接层,它可以对网络传输的数据进行加密

我们常见的http协议转化成https协议就用到了SSL,https本质上就是用SSL做了外壳的http

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

SSL/TLS:

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

使用https的原因:http协议是明文传输数据,存在安全隐患,而https是加密传输,相当于http+ssl并且可以防止流量劫持

nginx就是通过配置SSL(将http转化为https)对数据进行加密传输,保证数据的安全性,但nginx想要使用SSL,需要满足一个条件即需要添加一个模块--with-http_ssl_module,而该模块在编译的过程中需要OpenSSL的支持

二,nginx进行SSL加密

一,nginx添加SSL的支持

一,安装OpenSSL软件,这个一般在安装nginx就要求安装(不详细说)

二,添加--with-http_ssl_module模块

步骤:

1,查看nginx的配置信息(nginx -V)并将内容进行临时保存

2,将原有/usr/local/nginx/sbin/nginx进行备份(作用:主要防止更新失败后对nginx进行恢复)

mv nginx nginxold

3,在nginx的安装源码目录中进行配置指定对应模块

cd nginx源码安装目录(自定义)
./config --with-http_ssl_module

4,通过make命令进行重新编译

make

5,将objs目录下的nginx可执行文件移动或拷贝到/usr/local/nginx/sbin目录下

cp ./nginx /usr/local/nginx/sbin

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

make upgrade

二,SSL证书

SSL加密必须要有SSL证书文件,通过证书文件完成加密

生成证书的方式:主要有两种

  • 使用阿里云/腾讯云等第三方进行购买(生产环境)
  • 使用openssl本地自动生成证书(测试环境)

一,阿里云第三方购买

1,在阿里云搜索框中搜索ssl

2,选购ssl

3,创建ssl证书(ssl购买后需要在本地控制台进行创建和申请才能使用)

4,申请ssl证书

5,申请成功下载证书

6,下载后的内容(两文件)

二,使用openssl本地生成证书

openssl可以生成本地证书,但主要是在测试学习时使用,生产环境不能使用

通过命令查看本地是否安装了openssl:

  • openssl version
  • rpm -qa |grep openssl

通过openssl生成证书的步骤:

     1,创建一个文件方便管理证书文件:/home/ceat

     2,进入文件目录:cd /home/ceat

     3,创建key(需要输入自定义密码):openssl genrsa -des3 -out server.key 1024

  • -des3:加密的算法
  • -out:输出到文件
  • 1024:加密的长度

     4,按照key生成对应的csr文件:openssl req -new -key server.key -out server.csr

  • -key:选择之前生成的.key文件
  • -out:内容输出到文件

这个指定需要填写基本信息才能通过(随便写即可它不会进行信息效验)

5,拷贝server.key文件:cp server.key server.key.org

6,再次加密.key文件:openssl rsa -in server.key.org -out server.key

7,生成crt文件:openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

8,证书生成成功查看证书文件

三,Nginx的SSL相关指令

SSL指令是通过ngx_http_ssl_module模块提供并解析的

一,ssl指令

该指令用来在指定的服务器开启HTTPS,可以使用listen 443 ssl,这样方式指定较为通用

注:https默认监听的是443端口

语法 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_session_cache off | none | [builtin[:size]] [shared:name:size] 
默认值 ssl off
配置位置 http块,server块
  • off:禁用会话缓存
  • none:禁止使用会话缓存,客户端可以重复使用,但是并没有在缓存中存储会话参数
  • builtin:内置OpenSSL缓存,仅在一个工作进程中使用
  • shared:所有工作进程之间共享缓存,缓存的信息有name和size来指定

五,ssl_session_timeout

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

语法 ssl on | off
默认值 ssl off
配置位置 http块,server块

六,ssl_ciphers

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

语法 ssl_ciphers ciphers
默认值 ssl_ciphers HIGH:!aNULL:!MD5
配置位置 http块,server块

注:可以在命令行中输入openssl ciphers查看OpenSSL支持的格式

七,ssl_prefer_server_ciphers

该指令指定是否服务器密码优先客户端密码

语法 ssl_prefer_server_ciphers on|off
默认值 ssl_prefer_server_ciphers off
配置位置 http块,server块

四,nginx配置SSL

server {

    listen 443 ssl;#https默认是443端口
    #ssl on;这个和listen 443 ssl作用是一样的
    server_name localhost;#监听的主机名

    #指定ssl证书的位置(需要先生成证书)
    ssl_certificate /home/ceat/server.crt; #证书的.crt文件
    ssl_certificate_key /home/ceat/server.key; #证书的.key文件

    #shared多进程之间共享缓存,SSL缓存的名称(自定义),1m表示缓存的大小
    ssl_session_cache shared:SSL:1m;   
    #指定缓存的超时时间
    ssl_session_timeout 5m;

    #允许的密码格式(采取默认的就行)
    ssl_ciphers HIGH:!aNULL:!MD5;

    #是否服务器密码优先于客户端密码
    ssl_prefer_server_ciphers on;

    location / {
        root html;
        index index.html index.htm;
}}

在使用本地的ssl没有就行ssl授权,https是能访问的,但浏览器也会显示不安全(需要使用购买的授权的ssl)