zoukankan      html  css  js  c++  java
  • HTTPS 协议

    HTTPS 协议

    推荐Blog:
    了解 HTTPS
    图解 HTTPS

    HTTPS 协议是什么?

    首先提醒读者,其实这个世界压根不存在 HTTPS 协议,只有 HTTP 协议,加上 S 的后缀只是告诉大家 HTTP 使用的是六层结构(将表示层和会话层归属到应用层),有了新的逻辑层 SSL/TLS 的安全保护,但 HTTPS 协议的说法传泛甚广,所以以下皆称 HTTPS 协议

    HTTPS (Hyper Text Transfer Protocol over SecureSocket Layer)是基于 HTTP 衍生出的可进行加密传输、身份认证的网络协议 。是以安全为目标的 HTTP 通道,HTTPS 在 HTTP 的基础下加入 SSL/TSL 层,用来对传输的内容做加密, HTTPS 的默认端口为 443,HTTPS 存在不同于 HTTP 的默认端口及一个 加密传输 / 身份验证 层(在 HTTP与 TCP 之间)。

    HTTPS 协议的组成:
    ①.HTTP 协议 + SSL(Secure Sockets Layer)层
    其中 SSL层 是一个新的逻辑层概念,不属于任意一个层,但处于应用层与传输层之间,SSL 层包含了两个协议:
    SSL 记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
    SSL 握手协议(SSL Handshake Protocol):它建立在 SSL 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

    ②.HTTP 协议 + TLS(Transport Layer Security)协议
    其中 TLS 是安全传输层协议,是基于 SSL 层衍生的;摒弃了 SSL 层,TLS 归属于传输层,顾名思义实现了传输层的安全保护措施

    为什么需要 HTTPS 协议?

    HTTP是明文传输的,那么在客户端、服务端之间传输的内容,是可以被中间的任意一个节点获取的;例如用户登陆,输入账号、密码,如果采用 HTTP 协议,在中间的代理服务器上,稍微做点手脚就可以拿到你的密码 ;同时,用户请求的服务端页面,也可以被代理服务器任意更改替换(使用 ngx_http_sub_module 模块),服务端原始的页面会被篡改,例如被迫打上“澳门皇家赌场”的广告。

    客户端----> 代理服务器(做手脚)----> 服务端

    模拟网站原始页面被篡改,首先配置服务端原始页面:

    # 服务端 nginx 配置
    [root@web01 ~]# vi /etc/nginx/conf.d/www.wqh.com.conf 
        server {
                listen 80;
                server_name www.wqh.com;
                root /website;
                index index.html;
                charset utf-8;
        }
    
    # 站点目录的索引文件
    [root@web01 ~]# vim  /website/index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>my website</title>
    </head>
    <body>
    <article>
      <header>
        <h1>一个个人网站</h1>
        <p>创建时间:<time pubdate="pubdate">2020/2/22</time></p>
      </header>
      <p>
        <b>标题:</b>我只写正经内容
      </p>
      <footer>
        <p><small>我不打广告</small></p>
      </footer>
    </article>
    </body>
    </html>
    

    中间安插一个代理服务器:

    # 代理服务器 nginx 配置
    [root@lb01 ~]# vi /etc/nginx/conf.d/test.conf
    upstream sb {
            server 10.0.0.9:80;
    }
    server {
            listen 80;
            server_name www.wqh.com;
    
            location / {
                    proxy_pass http://sb;
                    proxy_set_header Host $http_host;
                    sub_filter '<h1>一个个人网站' '<h1>一起贪玩蓝月吗';
                    sub_filter '</b>我只写正经内容' '</b>开局就神装,一刀99999';
                    sub_filter '<small>我不打广告' ' <img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1591197424430&di=22f4883b00be870cb56c796067d45962&imgtype=0&src=http%3A%2F%2Fwww.ijiandao.com%2Fwp-content%2Fuploads%2F2019%2F06%2F74dbd2451110be34e86e4c96874b9e05.jpg">';
            }
    }
    

    如何使用 HTTPS 协议?

    需要配置 SSL/TLS 证书,才可以使用 HTTPS 协议,证书类型如下,证书的选择包括 单域名证书、多域名证书、通配符证书,通配符选择的证书只支持匹配二级域名 。

    对比 域名型 DV 企业型 OV 增强型 EV
    地址栏 小锁标记+https 小锁标记+https 小锁标记+企业名称+https
    一般用途 个人站点和应用; 简单的https加密需求 电子商务站点和应用; 中小型企业站点 大型金融平台; 大型企业和政府机构站点
    审核内容 域名所有权验证 全面的企业身份验证; 域名所有权验证 最高等级的企业身份验证; 域名所有权验证
    颁发时长 10分钟-24小时 3-5个工作日 5-7个工作日
    单次申请年限 1年 1-2年 1-2年
    赔付保障金 —— 125-175万美金 150-175万美金

    不同类型的域名:

    使用 SSL 证书需要使用 ngx_http_ssl_module 模块(官方文档),正常的 SSL 证书(被浏览器承认)都需要申请,但也可以模拟生成一个证书(不被浏览器承认):

    ## ngx_http_ssl_module 语法
    # 启动 ssl 功能
    Syntax:  ssl on | off;  <----  ssl on; 或 listen 443 ssl;  
    Default: ssl off;
    Context: http,server
    # 指定证书文件
    Syntax:  ssl_certificate file;
    Default: -
    Context: http,server
    # 指定私钥文件
    Syntax:  ssl_certificate_key file;
    Default: -
    Context: http,server
    
    
    ## 模拟生成一个 SSL 证书
    # 生成私钥
    [root@lb01 ~]# mkdir /app/nginx/conf/ssl_key
    [root@lb01 ~]# cd /app/nginx/conf/ssl_key/
    [root@lb01 ssl_key]#  openssl genrsa -idea -out /app/nginx/conf/ssl_key/$(date +%Y%m%d)_wqh.com.key 2048
    Generating RSA private key, 2048 bit long modulus
    ................................+++
    .............................................................................................+++
    e is 65537 (0x10001)
    Enter pass phrase for /app/nginx/conf/ssl_key/20200603_wqh.com.key:
    Verifying - Enter pass phrase for /app/nginx/conf/ssl_key/20200603_wqh.com.key:
    # 生成证书
    [root@lb01 ssl_key]#  openssl req -days 36500 -x509 -sha256 -nodes -newkey rsa:2048 -keyout /app/nginx/conf/ssl_key/20200603_wqh.com.key -out /app/nginx/conf/ssl_key/20200603_wqh.com.crt
    Generating a 2048 bit RSA private key
    ....+++
    ................................................+++
    writing new private key to '/app/nginx/conf/ssl_key/20200603_wqh.com.key'
    -----
    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) []:Heilongjiang
    Locality Name (eg, city) [Default City]:qiqihaer
    Organization Name (eg, company) [Default Company Ltd]:none
    Organizational Unit Name (eg, section) []:none
    Common Name (eg, your name or your server's hostname) []:wqh.com
    Email Address []:123@123.com
    

    单台服务器配置 HTTPS:

    [root@lb01 ~]# vi /app/nginx/conf/conf.d/test.conf
    server {
            listen 80;
            server_name www.wqh.com;
            return 302 https://$host/$request_uri;
    }
    
    server {
            listen 443 ssl;
            server_name www.wqh.com;
            ssl_certificate /app/nginx/conf/ssl_key/20200603_wqh.com.crt;
            ssl_certificate_key /app/nginx/conf/ssl_key/20200603_wqh.com.key;
    	    root /website;
    	    index index.html;
    }
    [root@lb01 ~]# vim  /website/index.html
    <H1>THIS IS HTTPS</H1>
    

    企业案例:分布式集群架构实现 HTTPS

    部署负载均衡代理服务器,添加 SSL 安全证书;部署应用服务器,数据库服务器,NFS共享存储服务器以及备份服务器;具体环境需求如下:

    服务器 IP(WAN) 服务
    lb01 10.0.0.5 nginx + SSL证书
    web01 10.0.0.7 nginx + php-fpm
    web02 10.0.0.8 nginx + php-fpm
    web03 10.0.0.9 nginx + php-fpm
    db01 10.0.0.51 mariadb
    nfs 10.0.0.31 nfs-server,sereync
    backup 10.0.0.41 rsync

    部署数据库服务器

    # 安装 mariadb,创建数据库 wordpress、wecenter
    [root@db01 ~]# yum -y install mariadb-server
    [root@db01 ~]# systemctl start mariadb && systemctl enable mariadb
    [root@lb01 ~]# mysqladmin -uroot password 123
    [root@lb01 ~]# mysql -p123
    >create database wordpress;
    >grant all on wordpress.* to wp_user@'%' identified by '123456';
    >create database wecenter;
    >grant all on wecenter.* to wc_user@'%' identified by '123456';
    

    部署应用服务器

    # 每个应用服务器都装过 Nginx,进行以下操作
    # 编辑 nginx 配置文件
    [root@web01 ~]# cat /etc/nginx/conf.d/blog.wqh.com.conf 
    server {
    	listen 80;
    	server_name blog.wqh.com;
    	root /website/wordpress/;
    	index index.php;
    	location ~ .php$ {
    		fastcgi_pass 127.0.0.1:9000;
    		fastcgi_index index.php;
    		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    		include fastcgi_params;
    	}
    }
    [root@web01 ~]# cat /etc/nginx/conf.d/wecenter.wqh.com.conf 
    server {
    	listen 80;
    	server_name wecenter.wqh.com;
    	root /website/wecenter/;
    	index index.php;
    	location ~ .php$ {
    		fastcgi_pass 127.0.0.1:9000;
    		fastcgi_index index.php;
    		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    		include fastcgi_params;
    	}
    }
    [root@web01 ~]# cat /etc/nginx/conf.d/phpmyadmin.com.conf 
    server {
    	listen 80;
    	server_name phpmyadmin.wqh.com;
    	root /website/phpmyadmin;
    	index index.php;
    	location ~ .php$ {
    		fastcgi_pass 127.0.0.1:9000;
    		fastcgi_index index.php;
    		fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    		include fastcgi_params;
    	}
    }
    # 添加参数到 fastcgi_params 文件,开启 HTTPS(让 php-fpm 将所有 HTTP链接 转为 HTTPS链接)
    [root@web01 ~]# echo  "fastcgi_param HTTPS on;" >>  /etc/nginx/fastcgi_params
    
    # 解压 phpmyadmin、 wecenter、wordpress 到指定站点目录,指定属主属组(nginx,php-fpm 的执行用户)
    # 打开浏览器安装,phpmyadmin 需要手动创建数据库配置文件
    [root@web01 ~]# vi /website/phpmyadmin/config.inc.php
    $cfg['Servers'][$i]['host'] = '172.16.1.51';
    
    
    # 安装好后,将web01服务器的 nginx配置文件 传给web02、web03服务器
    [root@web01 ~]# rsync -avz /etc/nginx/  10.0.0.8:/etc/
    [root@web01 ~]# rsync -avz /etc/nginx/  10.0.0.9:/etc/
    

    部署NFS服务器

    # 安装 nfs-utils rpcbind,启动服务,客户端也需要安装才可以指定挂载 nfs 文件系统类型 
    [root@nfs ~]# yum -y install nfs-utils
    [root@nfs ~]# systemctl start nfs-server && systemctl enable nfs-server
    [root@web01 ~]# yum -y install nfs-utils
    [root@web02 ~]# yum -y install nfs-utils
    [root@web03 ~]# yum -y install nfs-utils
    
    # 指定共享存储目录、网段、授权,/website_data 存储站点目录下所有的内容,/phpmyadmin_session 存储 phpmyadmin 维持会话的 session 文件
    [root@nfs ~]# cat /etc/exports
    /website_data 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
    /phpmyadmin_session 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
    
    # 创建匿名用户,创建共享存储目录,指定目录授权
    [root@nfs ~]# mkdir /website_data /phpmyadmin_session
    [root@nfs ~]# useradd www -u 666 -r -s /sbin/nologin -M
    [root@nfs ~]# chown www.www /website_data && chown www.www /phpmyadmin_session
    
    # 先将 Web01 站点目录的内容同步到 nfs 服务器的 /website_data 
    [root@web01 ~]# rsync -avz /website/ 10.0.0.31:/website_data
    
    # 再将 Web01 Web02 Web03 的站点目录挂载到 nfs 服务器上,若 Web02 Web03 没有站点目录则创建,并统一属主
    [root@web01 ~]# mount -t nfs 172.16.1.31:/website_data /website
    [root@web02 ~]# mount -t nfs 172.16.1.31:/website_data /website
    [root@web03 ~]# mount -t nfs 172.16.1.31:/website_data /website
    
    # 再将 phpmyadmin 维持会话的 /var/lib/php/session 目录,挂载到 nfs 服务器上
    [root@web01 ~]# mount -t nfs 172.16.1.31:/phpmyadmin_session /var/lib/php/session/
    [root@web02 ~]# mount -t nfs 172.16.1.31:/phpmyadmin_session /var/lib/php/session/
    [root@web03 ~]# mount -t nfs 172.16.1.31:/phpmyadmin_session /var/lib/php/session/
    
    
    ##############  NFS服务端 同时也是 Rsyncd 客户端,需要部署 Sersync服务 实时备份 ###################
    # 下载 Sersync 软件包
    [root@nfs ~]# wget https://files.cnblogs.com/files/zzzwqh/sersync2.5.4_64bit_binary_stable_final.tar.gz
    [root@nfs ~]# tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz -C /usr/local/
    
    # 编辑 confxml.xml 配置文件
    [root@nfs ~]# vi /usr/local/sersync/confxml.xml
            <!-- Rsync客户端监控目录 -->
    	<localpath watch="/website_data">
                <!-- Rsync服务端IP 和 Rsync服务端模块  -->
    	    <remote ip="172.16.1.41" name="website_data"/>
    	    <!--<remote ip="192.168.8.39" name="tongbu"/>-->
    	    <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    	</localpath>
    	<rsync>
                <!-- 指定rsync命令选项   -->
    	    <commonParams params="-az"/>
                <!-- 是否开启认证模式(认证用户),指定Rrync服务端认证用户,指定密码文件路径 -->
    	    <auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/>
    	    <userDefinedPort start="false" port="874"/><!-- port=874 -->
    	    <timeout start="false" time="100"/><!-- timeout=100 -->
    	    <ssh start="false"/>
    	</rsync>
    # 创建 confxml_session.xml 配置文件(需要同时监听两个目录,所以需要两个配置文件)
    [root@nfs ~]# vi /usr/local/sersync/confxml_session.xml
            <!-- Rsync客户端监控目录 -->
    	<localpath watch="/phpmyadmin_session">
                <!-- Rsync服务端IP 和 Rsync服务端模块  -->
    	    <remote ip="172.16.1.41" name="session_data"/>
    	    <!--<remote ip="192.168.8.39" name="tongbu"/>-->
    	    <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    	</localpath>
    	<rsync>
                <!-- 指定rsync命令选项   -->
    	    <commonParams params="-az"/>
                <!-- 是否开启认证模式(认证用户),指定Rrync服务端认证用户,指定密码文件路径 -->
    	    <auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/>
    	    <userDefinedPort start="false" port="874"/><!-- port=874 -->
    	    <timeout start="false" time="100"/><!-- timeout=100 -->
    	    <ssh start="false"/>
    	</rsync>
    
    # 创建密码认证文件
    [root@nfs ~]# echo 123 > /etc/rsync.password
    [root@nfs ~]# chmod 600 /etc/rsync.password
    
    
    # 启动 Sersync服务 
    [root@nfs ~]# /usr/local/sersync/sersync2 -rdo /usr/local/sersync/confxml.xml
    [root@nfs ~]# /usr/local/sersync/sersync2 -rdo /usr/local/sersync/confxml_session.xml 
    

    部署备份服务器

    # 安装 rsync,启动服务
    [root@backup ~]# yum -y install rsync
    [root@backup ~]# systemctl start rsyncd && systemctl enable rsyncd
    
    # 1.编辑 /etc/rsyncd.conf 配置文件
    [root@backup ~]# cat /etc/rsyncd.conf 
    uid = rsync
    gid = rsync
    port = 873
    fake super = yes
    use chroot = no
    max connections = 200
    timeout = 600
    ignore errors
    read only = false
    list = false
    auth users = rsync_backup
    secrets file = /etc/rsync.passwd
    log file = /var/log/rsyncd.log
    #####################################
    [website_data]
    comment = website's data
    path = /website_bak
    [session_data]
    comment = phpmyadmin session's data
    path = /session_bak
    
    
    # 2.创建好 rsync 用户,创建 /website_bak目录、/session_bak目录,指定属主
    [root@backup ]# useradd rsync -s /sbin/nologin -M
    [root@backup ]# mkdir /backup
    [root@backup ]# chown rsync.rsync /backup
    
    # 3.编辑密码文件,服务端密码文件需要写成 `auth users:password`,客户端只需要写入 `passord`
    [root@backup ]# cat /etc/rsync.passwd 
    rsync_backup:123
    [root@backup ]# chmod 600 /etc/rsync.passwd
    
    # 4.重启服务
    [root@backup ]# systemctl restart rsyncd
    

    部署代理服务器

    ## 模拟生成一个 SSL 证书
    # 生成私钥
    [root@lb01 ~]# mkdir /app/nginx/conf/ssl_key
    [root@lb01 ~]# cd /app/nginx/conf/ssl_key/
    [root@lb01 ssl_key]#  openssl genrsa -idea -out /app/nginx/conf/ssl_key/$(date +%Y%m%d)_wqh.com.key 2048
    Generating RSA private key, 2048 bit long modulus
    ................................+++
    .............................................................................................+++
    e is 65537 (0x10001)
    Enter pass phrase for /app/nginx/conf/ssl_key/20200603_wqh.com.key:
    Verifying - Enter pass phrase for /app/nginx/conf/ssl_key/20200603_wqh.com.key:
    # 生成证书
    [root@lb01 ssl_key]#  openssl req -days 36500 -x509 -sha256 -nodes -newkey rsa:2048 -keyout /app/nginx/conf/ssl_key/20200603_wqh.com.key -out /app/nginx/conf/ssl_key/20200603_wqh.com.crt
    Generating a 2048 bit RSA private key
    ....+++
    ................................................+++
    writing new private key to '/app/nginx/conf/ssl_key/20200603_wqh.com.key'
    -----
    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) []:Heilongjiang
    Locality Name (eg, city) [Default City]:qiqihaer
    Organization Name (eg, company) [Default Company Ltd]:none
    Organizational Unit Name (eg, section) []:none
    Common Name (eg, your name or your server's hostname) []:wqh.com
    Email Address []:123@123.com
    
    # 编辑 nginx 配置文件
    [root@lb01 ~]# cat /app/nginx/conf/conf.d/lb.conf 
    upstream wqh {
    	server 172.16.1.7;
    	server 172.16.1.8;
    	server 172.16.1.9;
    }
    server {
    	listen 80;
    	server_name blog.wqh.com wecenter.wqh.com phpmyadmin.wqh.com;
    	return 302 https://$host/$request_uri;
    }
    server {
    	listen 443 ssl;
    	server_name blog.wqh.com wecenter.wqh.com phpmyadmin.wqh.com;
    	ssl_certificate /app/nginx/conf/ssl_key/20200603_wqh.com.crt;
    	ssl_certificate_key /app/nginx/conf/ssl_key/20200603_wqh.com.key;
    	location / {
    		proxy_pass http://wqh;
    		proxy_set_header HOST $host;
    	}
    }
    
    

    番外:SSL 优化参数

    server {
        listen 443 ssl;
        server_name blog.wqh.com;
        root /var/website/wordpress;
        index index.php index.html index.htm;
        ssl_certificate   ssl/123456_blog.wqh.com.pem;
        ssl_certificate_key  ssl/123456_blog.wqh.com.key;
        
        ssl_session_cache shared:SSL:10m; # 在建立完 ssl 握手后如果断开连接,在 session_timeout 时间内再次连接,是不需要再次获取公钥建立握手的,可以服用之前的连接
        ssl_session_timeout 1440m;  # ssl 连接断开后的超时时间
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  # 配置加密套接协议
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  # 使用 TLS 版本协议
        ssl_prefer_server_ciphers on;  # nginx决定使用哪些协议与浏览器通信
    }
    
  • 相关阅读:
    Python元类
    Python接口与归一化设计
    如何使用yum下载rpm包
    浅谈Python的with语句
    搞懂了这几点,你就学会了Web编程
    网络虚拟化技术大观
    Python装饰器
    Kubernetes配置Ceph RBD StorageClass
    编译Kubelet二进制文件
    记一次虚拟机无法挂载volume的怪异问题排查
  • 原文地址:https://www.cnblogs.com/zzzwqh/p/13040532.html
Copyright © 2011-2022 走看看