1、nginx负载均衡;(使用upstream来指定多个web server)
注释:代理一台机器是代理,代理两台机器就是负载均衡了;
代理服务器后面可以有多个web服务器,多个web服务器去提供服务,可以实现一个负载均衡的功能,
而正常的访问,用户访问web服务器,是一台一台的去请求,要么就指定一个IP,然后把域名解析到这台IP上了;
而如果配置负载均衡的话,当用户每次访问的是负载均衡地址,再由负载均衡去向后端的web1服务器去请求,而在web1服务器宕机后,则负载均衡会把用户的请求转发到web2服务器上;
配置负载均衡,需要使用upstream模块;
这里将qq作为演示对象;
dig命令查看解析到的IP地址; yum install -y bind-utils
[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.48qq.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地址;
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.comThis is a default site.
3:检测nginx是否有错误,并重新加载配置文件;
[root@localhost_001 vhost]# /usr/local/nginx/sbin/nginx -tnginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is oknginx: 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:客户端收到数据后,再用自己的私钥也就是那个随机字符串解密;
1、生成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 2048Generating 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其实是同一个,前者有密码,后这没有密码;
2、生成证书请求文件;还需要拿这个请求和私钥一起生成公钥文件;
[root@localhost_001 conf]# openssl req -new -key fenye.key -out fenye.csrYou are about to be asked to enter information that will be incorporatedinto 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 blankFor 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' attributesto be sent with your certificate requestA 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.crtSignature oksubject=/C=11/ST=beijing/L=beijing/O=fenye/OU=fenye/CN=fenye/emailAddress=beijingGetting 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 reloadnginx: [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 -Vnginx version: nginx/1.4.7built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) TLS SNI support enabledconfigure 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 -tnginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is oknginx: 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
3、查看监听端口,发现多出来的443端口;
[root@localhost_001 vhost]# netstat -lnptActive 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
4、切换路径,并新建一个测试文件; /data/wwwroot/test.com
[root@localhost_001 vhost]# cd /data/wwwroot/test.com/[root@localhost_001 test.com]# vim index.html The is ssl;
5、测试,若直接用curl命令访问,需要添加/etc/hosts;
[root@localhost_001 vhost]# cat /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6127.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.htmlcurl 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
4、然后在浏览器里来访问; https://www.test.com
注释:因为是我们自己颁发的证书,会显示不受浏览器信任,点击继续前往www.test.com
显示不安全的连接;这个是自己颁发的证书,浏览器不被信任,会显示红色,不安全,正常的样子应该是绿色的;
注释:以后若想访问https的网站,可以去沃通买证书;
注释:访问是要看下防火墙是否开启,如果开启,可以临时使用iptables -F来清空规则,或者可以添加一条允许443端口通的规则,如下;
iptables -I INPUT -p tcp --dport 443 -j ACCEPT