12.17 nginx负载均衡

 

一个代理服务器下有多个web服务器的情况即可被称为负载均衡

若没有代理,用户访问web服务器时只能一台一台的请求内容;

若不使用代理:

需要指定一个ip 或者

将域名指定到多台服务器上,用户1访问web1,用户2访问web2,此时若web1故障,则用户1无法继续访问网站

 

使用代理服务器时,若web1故障,则代理服务器不会继续把用户1的请求发给web1而是发给其他服务器;

代理服务器用到了upstream模块;

代理配置中的proxy pass字段不支持写多个ip

可以使用upstream模块定义多个serverip+端口);

dig命令:

需要安装的包:

[root@hyc-01-01 ~]# yum install -y bind-utils

[root@hyc-01-01 ~]# dig qq.com 用于域名解析

;; ANSWER SECTION:

qq.com.                   143  IN     A      59.37.96.63

qq.com.                   143  IN     A      180.163.26.39

qq.com.                   143  IN     A      58.60.9.21

使用dig命令解析出了域名qq.com对应的3ip

 

配置:

[root@hyc-01-01 vhost]# pwd

/usr/local/nginx/conf/vhost

[root@hyc-01-01 vhost]# vim load.conf

upstream qq 此处名称可以随便写

{

    ip_hash; ip哈希的目的是让同一个用户始终保持在同一台机器上(假如用户在一台服务器上已登录,此时用户刷新页面,如果不配置ip哈希,则有可能用户刷新的请求会被发到另一台服务器,而在另一台服务器上用户状态为未登录,则需要重新登录)

    server 59.37.96.63:80;

    server 180.163.26.39:80;

    server 58.60.9.21:80;

}  

server

{

    listen 80;

    server_name www.qq.com;

    location /

    {

        proxy_pass http://qq; 这里http://后的字段需要与上面upstream后跟的字段保持一致,这里qq即代表upstream模块中定义的三个server地址

        proxy_set_header Host $host;

        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    }  

}  

测试:

未重启配置:

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

hello nginx 没哟对应servername,访问默认虚拟主机

重启配置后:

[root@hyc-01-01 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@hyc-01-01 vhost]# /usr/local/nginx/sbin/nginx -s reload

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

再次访问www.qq.com返回了qq.com的页面

 

Nginx不支持代理httpshttps端口号443

 

Nginx代理服务器代理https

用户访问时必须为https,不能是http80),此时可以让代理服务器监听443端口,但代理服务器访问后端时必须访问后端的80端口,不支持访问443

 

12.18 ssl原理

 

https

通信加密,数据在网络传递时可能被截取或侦听,×××会拿到传递的数据,若使用http则对方可以很容易看到传递的信息,https对传递的数据进行加密,即使对方获取了数据也无法解密;

 

https数据传递过程:

1 浏览器发送https请求给服务端

2 服务器将数字证书中的公钥(用于加密)传递给客户端

3 浏览器判断公钥是否合法,无效会警告,有效则生成一串随机字符串

4 将随机字符串用公钥加密,将加密的随机字符串传递给服务端

5 服务端用私钥将将加密的随机字符串解密

6 将要传递的网站内容通过随机字符串加密,并传递给客户端

7 客户端使用随机字符串解密,得到网站内容

 

12.19 生成ssl密钥对

 

颁发的数字证书实际上就是公钥和私钥

 

查看一个命令用哪个包安装:

[root@hyc-01-01 conf]# which openssl

/usr/bin/openssl

[root@hyc-01-01 conf]# rpm -qf `which openssl`

openssl-1.0.2k-12.el7.x86_64

[root@hyc-01-01 conf]# yum install -y openssl-1.0.2k-12.el7.x86_64

 

生成私钥:

[root@hyc-01-01 conf]# openssl genrsa -des3 -out tmp.key 2048

genrsa:生成rsa格式的私钥

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: 将相同的密码重复输入两次

为了让用户不用在访问https网站时输入密码,需要去掉密码

转换key,取消密码:

[root@hyc-01-01 conf]# openssl rsa -in tmp.key -out hyc.key

指定要被转换的密钥为tmp.key,指定输出的密钥

此处输出的hyc.keytmp.key实际是同一个密钥,只是tmp.key有密码,hyc.key没有密码

 

生成请求文件(.csr)(用于和私钥一起作用生成公钥):

[root@hyc-01-01 conf]# openssl req -new -key hyc.key -out hyc.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]:shanxi 生成请求文件需要填写部分信息

string is too long, it needs to be less than  2 bytes long

Country Name (2 letter code) [XX]:11

State or Province Name (full name) []:shanxi                                     

Locality Name (eg, city) [Default City]:xian

Organization Name (eg, company) [Default Company Ltd]:BSAA

Organizational Unit Name (eg, section) []:1

Common Name (eg, your name or your server's hostname) []:2

Email Address []:

 

Please enter the following 'extra' attributes

to be sent with your certificate request

A challenge password []:hyc940421

An optional company name []:hanyuchen

 

用私钥与请求文件一起生成公钥(.crt):

[root@hyc-01-01 conf]# openssl x509 -req -days 365 -in hyc.csr -signkey hyc.key -out hyc.crt

Signature ok

subject=/C=11/ST=shanxi/L=xian/O=BSAA/OU=1/CN=2

Getting Private key 生成公钥

 

[root@hyc-01-01 conf]# ls hyc.*

hyc.crt  hyc.csr  hyc.key

生成了公钥、私钥、请求文件

 

12.20 nginx配置ssl

 

编译安装nginx支持ssl

[root@hyc-01-01 vhost]# vim ssl.conf

server

{

    listen 443;

    server_name hyc.com;

    index index.html index.php;

    root /data/wwwroot/hyc.com;

    ssl on;

    ssl_certificate hyc.crt

    ssl certificate_key hyc.key

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

}

检测nginx配置报错:

[root@hyc-01-01 vhost]# /usr/local/nginx/sbin/nginx -t

nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/vhost/ssl.conf:7

由于在编译nginx时没有指定支持ssl

nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed

[root@hyc-01-01 vhost]# /usr/local/nginx/sbin/nginx -V

nginx version: nginx/1.12.2

built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)

configure arguments: --prefix=/usr/local/nginx

解决:

重新编译nginx

[root@hyc-01-01 nginx-1.12.2]# ./configure --prefix=/usr/local/nginx ---with-http_ssl_module

编译时增加模块--with-http_ssl_module

 

[root@hyc-01-01 nginx-1.12.2]# make

[root@hyc-01-01 nginx-1.12.2]# make install

[root@hyc-01-01 nginx-1.12.2]# /usr/local/nginx/sbin/nginx -V

nginx version: nginx/1.12.2

built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)

built with OpenSSL 1.0.2k-fips  26 Jan 2017

TLS SNI support enabled

configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module

 

编写配置文件:

[root@hyc-01-01 vhost]# vim ssl.conf

server

{

    listen 443;

    server_name hyc.com;

    index index.html index.php;

    root /data/wwwroot/hyc.com;

    ssl on;

    ssl_certificate hyc.crt;

    ssl_certificate_key hyc.key;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 支持的ssl协议版本

}

重启nginx

[root@hyc-01-01 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@hyc-01-01 vhost]# /etc/init.d/nginx restart 重启nginx服务

Restarting nginx (via systemctl):                          [  确定  ]

[root@hyc-01-01 vhost]# netstat -lntp

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      63980/nginx: master

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      886/sshd           

tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1185/master        

tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      63980/nginx: master

tcp6       0      0 :::22                   :::*                    LISTEN      886/sshd           

tcp6       0      0 ::1:25                  :::*                    LISTEN      1185/master        

tcp6       0      0 :::3306                 :::*                    LISTEN      1155/mysqld

此时nginx分别监听了80443端口

测试:

[root@hyc-01-01 vhost]# cd /data/wwwroot/hyc.com

[root@hyc-01-01 hyc.com]# vim index.html

编辑hosts文件后访问:

blob.png

[root@hyc-01-01 hyc.com]# vim /etc/hosts

[root@hyc-01-01 hyc.com]# curl https://hyc.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.

证书是自己颁发的,是不可信任,不可信任的

如果需要正规颁发的受信任证书可以到沃通等站点购买