LNMP架构之负载均衡及HTTPS相关配置

Wesley13
• 阅读 707

本文索引:

  • Nginx负载均衡
  • ssl原理
  • 生成ssl密钥对
  • Nginx配置ssl

Nginx负载均衡

负载均衡原理上就是代理,只不过通过设置多个代理服务器来实现多用户访问时的负载均衡。同时也可以在某个代理服务器无法访问时,切换到另外的代理服务器,从而实现访问不间断的目的。

下面以qq.com为例,配置负载均衡

  1. 先通过dig命令查看域名及其ip

    dig命令由bind-utils包安装

    [root@localhost ~]# yum install -y bind-utils [root@localhost ~]# dig qq.com

    ; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7_4.1 <<>> qq.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65328 ;; 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. 404 IN A 61.135.157.156 qq.com. 404 IN A 125.39.240.113

    ;; Query time: 40 msec ;; SERVER: 119.29.29.29#53(119.29.29.29) ;; WHEN: 四 1月 04 22:02:25 CST 2018 ;; MSG SIZE rcvd: 67

  2. 配置虚拟主机配置文件

    [root@localhost ~]# mv /usr/local/nginx/conf/vhost/load.conf

    通过upstream来指定多个web服务器

    upstream qq_com { # ip_hash的目的是让同一个用户始终保持在同一个机器上 ip_hash; # 这里是负载均衡时使用的多个server的ip # server http://61.135.157.157:80; # 上述表示也行,对应的server块内的proxy_pass内直接写qq_com即可,不需要写http:// server 61.135.157.157:80; server 125.39.240.113:80; } server { listen 80; server_name www.qq.com; location / { # 这里使用的是upstream名即qq_com proxy_pass http://qq_com; proxy_set_header Host $host; proxy_set_header X_Real_IP $remote_addr; proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for; } }

验证效果

配置未生效时,本地访问www.qq.com,得到的将是默认主机的内容

[root@localhost ~]# curl -x127.0.0.1:80 www.qq.com
this is default web server

重启服务后,获取到了www.qq.com网页的源码

[root@localhost ~]# /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 ~]# /usr/local/nginx/sbin/nginx -s reload
[root@localhost ~]# curl -x127.0.0.1:80 www.qq.com
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta content="text/html; charset=gb2312" http-equiv="Content-Type">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="baidu-site-verification" content="cNitg6enc2">
<title><CC><DA>Ѷ<CA><D7>ҳ</title>
<script type="text/javascript">
if(window.location.toString().indexOf('pref=padindex') != -1){
}else{
        if(/AppleWebKit.*Mobile/i.test(navigator.userAgent) || /\(Android.*Mobile.+\).+Gecko.+Firefox/i.test(navigator.userAgent) || (/MIDP|SymbianOS|NOKIA|SAMSUNG|LG|NEC|TCL|Alcatel|BIRD|DBTEL|Dopod|PHILIPS|HAIER|LENOVO|MOT-|Nokia|SonyEricsson|SIE-|Amoi|ZTE/.test(navigator.userAgent))){  
      if(window.location.href.indexOf("?mobile")<0){
                try{
                        if(/Android|Windows Phone|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)){
                                window.location.href="http://xw.qq.com/index.htm";
                        }else if(/iPad/i.test(navigator.userAgent)){
              //window.location.href="http://www.qq.com/pad/"
                        }else{
...

nginx不支持代理https,即server语句内的端口无法使用443。


ssl原理

LNMP架构之负载均衡及HTTPS相关配置

  1. 客户端向服务器发送https请求;
  2. 服务器上存储了一套数字证书,其实质为一对公私钥。数字证书可以自己制作,也可以向组织申请。前者在客户端访问时需要验证才能继续访问;后者不会弹出验证提示;
  3. 服务器将公钥传输给客户端;
  4. 客户端验证公钥是否合法:无效(自己制作的)会弹出警告,有效的则生成一串随机数,用此随机数加密公钥;
  5. 客户端将加密后的字符串传输给服务器
  6. 服务器收到字符串后,先使用私钥进行解密,获取加密使用的随机数,并以此随机数加密传输的数据(对称机密);
  7. 服务器将加密后的数据传输给客户端;
  8. 客户端收到数据后,使用自己的私钥(即随机字符串)进行解密。

对称加密:将数据和私钥(随机字符串)通过某种算法混合在一起,除非知道私钥,否则无法解密。


生成SSL密钥对

  • 创建私钥key

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

    创建私钥key文件,必须输入密码,否则无法生成key文件

    [root@localhost 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:

  • 转换key,取消密码

    [root@localhost conf]# openssl rsa -in tmp.key -out test.key Enter pass phrase for tmp.key: writing RSA key

    [root@localhost conf]# rm -f tmp.key

  • 生成证书

    [root@localhost conf]# openssl req -new -key test.key -out test.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]:CN
    State or Province Name (full name) []:ZheJiang Locality Name (eg, city) [Default City]:QuZhou Organization Name (eg, company) [Default Company Ltd]: Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []: Email Address []:

    Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:

    需要使用csr文件与私钥一起生成.crt文件

    [root@localhost conf]# openssl x509 -req -days 365 -in test.csr -signkey test.key -out test.crt Signature ok subject=/C=CN/ST=ZheJiang/L=QuZhou/O=Default Company Ltd Getting Private key


Nginx配置SSL

  • 创建新虚拟主机配置文件

    [root@localhost conf]#vim /usr/local/nginx/conf/vhost/ssl.conf server { listen 443; server_name test.com; index index.html index.php; root /data/www/test.com; ssl on; ssl_certificate test.crt; ssl_certificate_key test.key; ssl_protocols TLSv1 TLS1.1 TLS1.2; }

  • 创建对应目录及文件

    [root@localhost conf]# mkdir -p /data/www/test.com [root@localhost conf]# vim /data/www/test.com/index.php ssl test page.

  • 重启服务

    /usr/local/nginx/sbin/nginx -t /usr/local/nginx/sbin/nginx -s reload

设置时报错 -- unknown directive “ssl”

这时由于一开始编译时未将http_ssl_module模块编译进nginx,需要重新编译安装

[root@localhost conf]# cd /usr/local/src/nginx-1.12.2/
[root@localhost nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --with-http_ssl_module
[root@localhost nginx-1.12.2]# make && make install

重新编译后将导致之前配置的虚拟主机配置文件丢失,最后在重新编译前对有用的nginx虚拟主机文件进行备份


  • 编译完成后查看

    [root@localhost conf]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.12.2 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (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

  • 重启nginx服务

    重新编译后的nginx必须使用/etc/init.d/nginx脚本进行重启

    [root@localhost conf]# /etc/init.d/nginx restart Restarting nginx (via systemctl): [ 确定 ]

    查看443端口是否开放

    [root@localhost conf]# 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:22 0.0.0.0:* LISTEN 1354/sshd
    tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2116/master
    tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 4953/nginx: master
    tcp6 0 0 :::3306 :::* LISTEN 2156/mysqld
    tcp6 0 0 :::22 :::* LISTEN 1354/sshd
    tcp6 0 0 ::1:25 :::* LISTEN 2116/master

  • 效果验证

  1. curl验证

    如果不想使用-x指定ip,可以在/etc/hosts内添加如下代码

    [root@localhost conf]# vim /etc/hosts 127.0.0.1 test.com

    curl测试

    [root@localhost conf]# curl https://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.

  2. 浏览器验证 同样的要修改客户端上的hosts文件,添加一行代码如下:

    192.168.65.133 test.com

同时要检查服务器端的防火墙是否开放443端口,这里为了测试方便,直接清空了iptables规则表

[root@localhost conf]# iptables -F

在浏览器内输入https://test.com,测试效果如下:

LNMP架构之负载均衡及HTTPS相关配置

点击“仍要继续”,页面内容显示如下:

LNMP架构之负载均衡及HTTPS相关配置

网页说明描述,证书不合法

LNMP架构之负载均衡及HTTPS相关配置


点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
2星期前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
6个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这