52:nginx负载均衡|ssl原理|生成ssl秘钥对|nginx配置ssl

一、nginx负载均衡;(使用upstream来指定多个web  server)php

注释:代理一台机器是代理,代理两台机器就是负载均衡了;html

代理服务器后面能够有多个web服务器,多个web服务器去提供服务,能够实现一个负载均衡的功能,mysql

而正常的访问,用户访问web服务器,是一台一台的去请求,要么就指定一个IP,而后把域名解析到这台IP上了;nginx

而若是配置负载均衡的话,当用户每次访问的是负载均衡地址,再由负载均衡去向后端的web1服务器去请求,而在web1服务器宕机后,则负载均衡会把用户的请求转发到web2服务器上;web

配置负载均衡,须要使用upstream模块算法

这里将qq做为演示对象;sql

dig命令查看解析到的IP地址;  yum    install   -y     bind-utilsvim

[root@localhost_001 vhost]# yum install -y bind-utils^C
[root@localhost_001 vhost]# dig qq.com

; <<>> DiG 9.9.4-RedHat-9.9.4-61.el7_5.1 <<>> qq.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25501
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;qq.com.				IN	A

;; ANSWER SECTION:
qq.com.			120	IN	A	111.161.64.48
qq.com.			120	IN	A	111.161.64.40

;; Query time: 22 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: 三 10月 31 11:04:30 CST 2018
;; MSG SIZE  rcvd: 67

注释:会看到返回两个IP,这两个IP就是域名解析到的IP地址;windows

1:添加一个配置文件;‘   /usr/local/nginx/conf/vhost/load.conf后端

[root@localhost_001 vhost]# cat /usr/local/nginx/conf/vhost/load.conf 
upstream qq_com                     #upstream后的名称自定义
{
    ip_hash;                        #目的是为了让同一个用户始终保持在同一个机器上
    server 111.161.64.40:80;        #若是域名解析端口是80,这段配置上的指定端口80是能够省略的
    server 111.161.64.48:80;
}
server
{
    listen 80;                      #定义监听端口
    server_name www.qq.com;         #域名

    location /
    {
        proxy_pass      http://qq_com;         #这里填写的是upstream 的名字
                                               #即“http://upstream”,由于做为一个模块,代理访问的是经过解析后的IP访问;
        proxy_set_header Host   $host;
        proxy_set_header X-Real-IP      $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

注释:须要用upstream来指定多个后端的web  server;

注释:当后端有多个web  server提供服务时,当咱们长时间访问一个域名时,在必定的时效内,会出现须要从新登陆或者跳转到了另外一台服务器的地址上,而图例中的ip_hash,就是保证同一个IP访问域名时,始终经过这台web服务的地址访问;

2:在未加载配置时,本机去访问时,默认是访问的默认主机;

[root@localhost_001 vhost]# curl -x127.0.0.1:80 www.qq.com
This is a default site.

3:检测nginx是否有错误,并从新加载配置文件;

[root@localhost_001 vhost]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost_001 vhost]# /usr/local/nginx/sbin/nginx -s reload

4:再次访问时,则显示QQ源码;说明能够正常代理;

[root@localhost_001 vhost]# curl -x127.0.0.1:80 www.qq.com -I

注释:知识点:nginx不支持https的代理,也就是针对端口443的,只能代理http,tcp等;

若想要实现代理https,nginx监听443端口,但web必须是80端口;

ssl原理:好比咱们访问一些网站时,会自动加上了https;

http和https的区别:https的通讯是加密的,若是不加密,中间的数据会被截取,会被旁听,致使信息泄露,https就是对这个数据的通讯进行加密;

SSL的工做原理;

1:浏览器发送一个https的请求给服务器;

2:服务器有一套本身数字证书,能够本身制做,也能够向组织申请(每一年多少钱),而区别在于本身制做的证书要客户经过验证才能继续访问,而使用受信任的的公司申请的证书则不会弹出,提示页面,这套证书其实就是一对公钥(加密)加一对私钥(解密);

3:首先服务会把公钥发送给客户端(也就是浏览器);

4:客户端(浏览器)收到公钥后,会验证其是否合法有效(这个过程是浏览器来判断),无效则会警告提醒,有效则会生成一端随机字符串,并用收到的公钥加密;

5:客户端(浏览器)把加密后的随机字符串传送给服务器;

6:服务器收到加密字符串后,先用私钥解密(以前用公钥加密),获取这一串随机字符串,在用这段随机字符串加密要传输的数据,(该加密为对称加密,所谓对称加密,就是将数据和私钥也就是这个随机字符串>经过某种算法混合在一块儿,这样除非知道私钥,不然没法获取数据内容);

7:服务器端把加密后的数据传输给客户端;

8:客户端收到数据后,再用本身的私钥也就是那个随机字符串解密;

一、生成ssl秘钥对;

注释:颁发一套证书,须要用到openssl工具,  给nginx里;

切换到/usr/local/nginx/conf目录下;

[root@localhost_001 ~]# cd /usr/local/nginx/conf/

若没有openssl这个工具,能够手动安装一下;   yum    install   -y    openssl

如何查看这个包是否已经安装;

[root@localhost_001 conf]# rpm -qf `which openssl`
openssl-1.0.2k-12.el7.x86_64

2:生成一个秘钥;     openssl      genrsa    -des3   -out    tmp.key  2048

genrsa     表示生成rsa的秘钥

2048       表示长度为2048

tmp.key      表示名称为tmp.key

生成这个秘钥必需要有密码才能够;

[root@localhost_001 conf]# rpm -qf `which openssl`
openssl-1.0.2k-12.el7.x86_64
[root@localhost_001 conf]# openssl genrsa  -des3 -out tmp.key 2048
Generating RSA private key, 2048 bit long modulus
.....+++
...........................+++
e is 65537 (0x10001)
Enter pass phrase for tmp.key:
Verifying - Enter pass phrase for tmp.key:

注释:(可是在生成秘钥后比较麻烦,在nginx的配置文件里指定密码,每次访问浏览器都须要输入密码,在https输入密码很不方便,因此须要去掉这个密码;)以下;   

转换key,取消密码;  转换后两个私钥是相同的,一个有密码,一个没有密码;openssl   rsa   -in tmp.key  -out fenye.key

[root@localhost_001 conf]# openssl rsa -in tmp.key -out fenye.key 
Enter pass phrase for tmp.key:
writing RSA key
[root@localhost_001 conf]# rm -fr tmp.key

-in    表示指定那一个秘钥要被转换;         -out   表示转换后的秘钥输出是什么;

注释:而这个时候tmp.key和fenye.key实际上是同一个,前者有密码,后这没有密码;

二、生成证书请求文件;还须要拿这个请求和私钥一块儿生成公钥文件;

[root@localhost_001 conf]# openssl req -new -key  fenye.key -out fenye.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:china           ## //国家,2个字母
State or Province Name (full name) []:beijing      ##省或者州       
Locality Name (eg, city) [Default City]:beijing    ##城市
Organization Name (eg, company) [Default Company Ltd]:fenye      ##公司
Organizational Unit Name (eg, section) []:fenye                  ##组织 
Common Name (eg, your name or your server's hostname) []:fenye   ##主机名
Email Address []:beijing                                         ##邮箱
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:12345                                    #密码
An optional company name []:fenye                                一个可选的公司名称

注释:正式颁发的证书,须要填写其对应的信息;

2:使用请求文件和私钥生成公钥文件;     -day  表示365天;  

[root@localhost_001 conf]# openssl x509 -req -days 365 -in fenye.csr -signkey fenye.key -out fenye.crt
Signature ok
subject=/C=11/ST=beijing/L=beijing/O=fenye/OU=fenye/CN=fenye/emailAddress=beijing
Getting Private key
[root@localhost_001 conf]# ls fenye.*
fenye.crt  fenye.csr  fenye.key

注释:   fenye.crt    是公钥          fenye.key    是公钥;

3:将openssl证书和nginx相结合;

编辑新建文件  /usr/local/nginx/conf/vhost/ssl.conf

[root@localhost_001 vhost]# cat ssl.conf 
server
{
    listen 443;                                             #监听端口;
    server_name www.test.com  bbs.test.com  www.test1.com;  #域名及别名;
    index index.html index.php;
    root /data/wwwroot/test.com;                            #根目录;
    ssl on;                                            #打开ssl开关;
    ssl_certificate fenye.crt;                         #指定公钥;
    ssl_certificate_key fenye.key;                     #指定私钥;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;               #支持协议;
}


server
{
    listen 443;
    server_name www.aaa.com;
    index index.html index.php;
    root /data/wwwroot/default;
    ssl on;
    ssl_certificate fenye.crt;
    ssl_certificate_key fenye.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}

而后重启nginx;  -s  reload   会报错以下

[root@localhost_001 vhost]# /usr/local/nginx/sbin/nginx -s reload
nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/vhost/ssl.conf:7

注释:这是由于咱们在编译是nginx,没有加入ssl模块,会显示识别不到的;因此须要从新编译nginx并加上 --with-https_ssl_module

查看相关ssl的参数;

[root@localhost_001 nginx-1.4.7]# ./configure --help |grep -i ssl
  --with-http_ssl_module             enable ngx_http_ssl_module
  --with-mail_ssl_module             enable ngx_mail_ssl_module
  --with-openssl=DIR                 set path to OpenSSL library sources
  --with-openssl-opt=OPTIONS         set additional build options for OpenSSL

开始从新编译nginx,并加上  --with-https_ssl_module

[root@localhost_001 nginx-1.4.7]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module
[root@localhost_001 nginx-1.4.7]# make
[root@localhost_001 nginx-1.4.7]# make install
[root@localhost_001 nginx-1.4.7]# echo $?
0

而后查看是否已经加载 http_ssl_module

[root@localhost_001 nginx-1.4.7]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.4.7
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module

而后检测并重启nginx服务;   -t    -s   reload

[root@localhost_001 nginx-1.4.7]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost_001 nginx-1.4.7]# /usr/local/nginx/sbin/nginx -s reload

三、查看监听端口,发现多出来的443端口;

[root@localhost_001 vhost]# netstat -lnpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3663/nginx: master  
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      808/sshd            
tcp        0      0 0.0.0.0:56888           0.0.0.0:*               LISTEN      808/sshd            
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      962/master          
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      3663/nginx: master  
tcp6       0      0 :::22                   :::*                    LISTEN      808/sshd            
tcp6       0      0 :::56888                :::*                    LISTEN      808/sshd            
tcp6       0      0 ::1:25                  :::*                    LISTEN      962/master          
tcp6       0      0 :::3306                 :::*                    LISTEN      1071/mysqld

四、切换路径,并新建一个测试文件;   /data/wwwroot/test.com

[root@localhost_001 vhost]# cd /data/wwwroot/test.com/
[root@localhost_001 test.com]# vim index.html 
The is ssl;

五、测试,若直接用curl命令访问,须要添加/etc/hosts;

[root@localhost_001 vhost]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 www.test.com
[root@localhost_001 vhost]# curl https://www.test.com/
curl: (60) Peer's certificate issuer has been marked as not trusted by the user.
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.

注释:意思说这个证书被标记为不能够信任,由于使咱们本身颁发的,实际上已经配置成功了的;

而后咱们在windows的C:/windows/system32/drivers/etc/hosts下添加hosts;

192.168.149.129  www.test.com

四、而后在浏览器里来访问;   https://www.test.com

注释:由于是咱们本身颁发的证书,会显示不受浏览器信任,点击继续前往www.test.com

显示不安全的链接;这个是本身颁发的证书,浏览器不被信任,会显示红色,不安全,正常的样子应该是绿色的;

注释:之后若想访问https的网站,能够去沃通买证书;

注释:访问是要看下防火墙是否开启,若是开启,能够临时使用iptables  -F来清空规则,或者能够添加一条容许443端口通的规则,以下;

iptables   -I    INPUT    -p    tcp   --dport   443   -j    ACCEPT

相关文章
相关标签/搜索