12.17 nginx负载均衡
一个代理服务器下有多个web服务器的情况即可被称为负载均衡
若没有代理,用户访问web服务器时只能一台一台的请求内容;
若不使用代理:
需要指定一个ip 或者
将域名指定到多台服务器上,用户1访问web1,用户2访问web2,此时若web1故障,则用户1无法继续访问网站
使用代理服务器时,若web1故障,则代理服务器不会继续把用户1的请求发给web1而是发给其他服务器;
代理服务器用到了upstream模块;
代理配置中的proxy pass字段不支持写多个ip;
可以使用upstream模块定义多个server(ip+端口);
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对应的3个ip
配置:
[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不支持代理https(https端口号443)
Nginx代理服务器代理https:
用户访问时必须为https,不能是http(80),此时可以让代理服务器监听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.key和tmp.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分别监听了80和443端口
测试:
[root@hyc-01-01 vhost]# cd /data/wwwroot/hyc.com
[root@hyc-01-01 hyc.com]# vim index.html
编辑hosts文件后访问:
[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.
证书是自己颁发的,是不可信任,不可信任的
如果需要正规颁发的受信任证书可以到沃通等站点购买