HTTPS 证书配置一劳永逸

HTTPS 是在 HTTP 协议基础之上加了一层 SSL/TLS 安全认证机制,原理功能概括一句即客户端和服务端在非对称密钥通讯中交换临时对称密钥进行的加密数据通信,达到防止数据传输中途被第三方窃取的目的

xg3.gif

背景

HTTPS 证书相关的体系组织是一个商业团体,商人出于利益的需要,把 HTTPS 证书分为各类等级,笼统的说分收费证书和免费证书,但是无论如何技术本质是一样的,所谓收费证书就是在证书发放流程中域名校验环节严格了一些,不过最终目的还是一样,确保你是申请域名证书的拥有者,另外有一点就是需要确认审核发放的证书的下级组织是否有一定公信度,一般来说选择大家熟知的即可,而在不久前 Let’s Encrypt 这个组织宣布支持免费申请泛域名证书了,这个组织是大家公认有可信度的,所以以后 HTTPS 证书的费用就再也不需要了,我们只需要申请免费的证书即可,需要注意的是收费证书一般有效期时间比较长(3-5年),有效期时间越长越不安全,而 Let’s Encrypt 提供的证书只有3个月有效期,也就是说你需要定期更新证书,有效期越短越安全,出于以上背景我们整合资源,给出全自动更新方案,一劳永逸让你的站点证书永不过期

原理

  1. 获取证书(调用 Let’s Encrypt 提供的 API 自动实现对自己域名的校验)
  2. 更新 Web 服务器 HTTPS 证书
  3. 更新 CDN 上相关域名证书配置(调用云服务商提供的 API 完成更新) [可选]
  4. 执行 CRONTAB 任务(每月自动执行一次上面三步骤)

实现一(小矩阵用户)

在小矩阵平台里的 Master 机器 /srv/salt/ssl/ 目录,我们默认有2个域名目录例子

  • example1.com 适用于 Qcloud DNS(dnspod.cn) 上的域名配置
  • example2.com 适用于 Aliyun DNS(net.cn) 上的域名配置

比如我们需要申请 xabcloud.com 在 dnspod.cn 上该域名的泛域名证书,流程如下步骤:(在 Master 机器操作)

1.复制一份例子

cd /srv/salt/ssl;cp -a example1.com xabcloud.com

2.编辑 /srv/salt/ssl/xabcloud.com/acme.sh 更新前面2行的 token 信息(从 dnspod.cn 站点用户中心那里获得,见下图)

export DP_Id="12345"
export DP_Key="u4io94fe08cbc67ach8888"

3.执行生成证书,默认会在 /srv/salt/ssl/CA/ 目录下生成对应的域名证书文件,其中 .pem 文件即证书 .key 文件为服务端的私钥,这两个文件将部署在 Web 服务器和 CDN 上,比如 Nginx 上 server {} 配置段里

cd /srv/salt/ssl/xabcloud.com/
./acms.sh --issue --dns dns_dp -d xabcloud.com -d *.xabcloud.com --force(2分钟左右就可以拿到信任证书)

4.配置自动执行任务(因为 xabcloud.com 域名在 dnspod.cn 上,所以下面注释了 Aliyun 相关设置,根据需要使用对应的配置),完成三件事

  • 设定每月的7号申请新的证书(申请 xabcloud.com 的证书)
  • 调用 CDN API 更新 CDN 域名证书信息(更新 src.xabcloud.com 和 s.xabcloud.com 这两个 CDN 站点域名的证书配置)
  • 执行 salt -N Nginx state.apply group.Nginx 模版管理下发更新 Web 服务器证书(更新 xabcloud.com 站点的 Nginx 分组服务器集群证书)
# cat /opt/sys/cron.sh

#!/bin/bash
#*************************************************
# Description : CA UPDATE
# Version     : 1.0
# Author      : XABCLOUD.COM
#*************************************************
#-----------------VAR-----------------------------
SSL=/srv/salt/ssl
CA=/srv/salt/ssl/CA
Qdns="xabcloud.com"
Adns="example1.com example2.com"
Qcdn="src.xabcloud.com s.xabcloud.com"
Acdn="xxx.example1.com yyy.example1.com"
#-----------------FUN-----------------------------
ACME(){
        if [ $(date +"%d") = "07" ];then

                # Qcloud DNS
                for domain in $Qdns
                do
                        cd $SSL/$domain;./acme.sh --issue --dns dns_dp -d $domain -d *.$domain --force
                done

                # Aliyun DNS
                #for domain in $Adns
                #do
                #        cd $SSL/$domain/;./acme.sh --issue --dns dns_ali -d $domain -d *.$domain --force
                #done

                # Update Qcloud CDN
                key=$(cat $CA/xabcloud.com.key|base64)
                pem=$(cat $CA/xabcloud.com.pem|base64)
                for domain in $Qcdn
                do
                        /opt/sys/qcloud-cdn.py SetHttpsInfo --host $domain --privateKey "$key" --cert "$pem" 
                done

                # Update Aliyun CDN
                #key=$(cat $CA/example1.com.key)
                #pem=$(cat $CA/example1.com.pem)
                #for domain in $Acdn
                #do
                #        /opt/sys/aliyun-cdn.py Action=SetDomainServerCertificate DomainName=$domain ServerCertificateStatus=on PrivateKey="$key" ServerCertificate="$pem"
                #done

                # Update Web Server
                salt --async -N Nginx state.apply group.Nginx

                # End
                find $CA -type f ! -name "*.pem" -a ! -name "*.key" -delete
        fi
}
main(){
        ACME
}
#-----------------PROG----------------------------
main

!> 请留意腾讯云 API 证书私钥内容以 Base64 编码后传输,而阿里云 API 是直接原内容传输(网络交换数据时,比如从A地到B地,一般要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,一些不可见字符有可能被处理错误,导致数据失真,先把数据 Base64 编码,统一为可见字符,可以减少错误概率)

5.添加 crontab 每月7号夜里执行的任务,完成 HTTPS 证书永不过期一劳永逸的目的

#crontab -e 

* 3 7 * * /opt/sys/cron.sh &>/dev/null

实现二(非小矩阵用户)

以我们官网 xabcloud.com 举例子,我们官网部署在一台 CentOS 7 机器一个普通用户目录下,部署结构规划如下:

  • Web Server ( OpenResty 部署在 /home/xabc/0/ )
  • App Server ( 文档部署在 /home/xabc/1/ )
  • DB Server ( Redis 部署在 /home/xabc/2/ )
  • 工具 ( /home/xabc/bin/ )
  • 配置 ( /home/xabc/etc/ )
  • 日志 ( /home/xabc/log/ )
  • 证书生成 ( /home/xabc/ssl/ )

官网 nginx.conf

server{
        listen 80;
        server_name xabcloud.com www.xabcloud.com;
        return 301 https://$host$request_uri;
}
server{
        listen 443 ssl http2;
        server_name xabcloud.com www.xabcloud.com;
        ssl_certificate /home/xabc/etc/openresty/ssl/xabcloud.com.pem;
        ssl_certificate_key /home/xabc/etc/openresty/ssl/xabcloud.com.key;
        ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256::!MD5;
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        location /{
                root /home/xabc/1/docs;
        }
}

每天夜里 /home/xabc/bin/cron.sh 任务执行一次(每月7号申请证书,更新本地 Web Server 证书,更新 CDN 域名证书配置)

#!/bin/bash
#*************************************************
# Description : CRON
# Version     : 1.0
# Author      : XABCLOUD.COM
#*************************************************
#-----------------VAR-----------------------------
HOME=/home/xabc
BIN=$HOME/bin
SSL=$HOME/ssl
CA=$HOME/etc/openresty/ssl
LOG=$HOME/0/openresty/nginx/logs
#-----------------FUN-----------------------------
LOG(){
        if [ $(date +"%H") = "00" ];then
                mv $HOME/log/access.log $HOME/log/$(date -d "yesterday" +"%Y-%m-%d").log
                kill -USR1 $(cat $LOG/nginx.pid)
        fi
}
ACME(){
        if [ $(date +"%d") = "07" ];then
                for domain in xabcloud.com
                do
                        cd $SSL/$domain;./acme.sh --issue --dns dns_dp -d $domain -d *.$domain --force
                done
                $HOME/0/openresty/nginx/sbin/nginx -s reload
                key=$(cat $CA/xabcloud.com.key|base64)
                pem=$(cat $CA/xabcloud.com.pem|base64)
                for domain in src.xabcloud.com s.xabcloud.com
                do
                        $BIN/qcloud-cdn.py SetHttpsInfo --host $domain --privateKey "$key" --cert "$pem"
                done
                find $CA -type f ! -name "*.pem" -a ! -name "*.key" -delete
        fi
}
main(){
        LOG
        ACME
}
#-----------------PROG----------------------------
main

资源

上面自动化更新所依赖的相关资源如下:

参考 Let’s Encrypt Acme.sh 腾讯云 API 阿里云 API

原文链接:https://xabcloud.com/#/ssl

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java后端技术栈

前后端分离后API交互如何保证数据安全性?

前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合。无论是开发原生的APP还是webapp还是PC端的软件,只要...

3721
来自专栏流媒体

Https详解+wireshark抓包演示

在说HTTPS之前先说说什么是HTTP,HTTP就是我们平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传...

5855
来自专栏Web行业观察

关于搭建HTTPS服务...

关于 HTTPS 的基本原理大家都已经不再陌生,今天和大家说说如何搭建一个支持 HTTPS 的服务端。

4144
来自专栏大魏分享(微信公众号:david-share)

如何为微服务做安全加密? | 微服务系列第十一篇

在微服务架构中实现可靠且强大的安全实现非常重要。微服务的体系结构向应用程序公开了多个入口点,并且通信可能需要多个网络跃点,因此未授权访问的风险很高。这需要比传统...

3488
来自专栏Java3y

HTTP2和HTTPS来不来了解一下?

试想一下:请求一张图片,新开一个连接,请求一个CSS文件,新开一个连接,请求一个JS文件,新开一个连接。HTTP协议是基于TCP的,TCP每次都要经过三次握...

960
来自专栏吴伟祥

聊一聊HTTPS和SSL/TLS 转

HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)简单的讲就是HTTP的安全版本。即HTT...

591
来自专栏一名合格java开发的自我修养

HTTP协议下保证密码不被获取更健壮方式

说到在http协议下用户登录如何保证密码安全这个问题:     小白可能第一想法就是,用户在登录页面输入密码进行登录时,前台页面对用户输入的密码进行加密,然后把...

1272
来自专栏james大数据架构

Android 程序打包及签名

为什么要签名???     开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同样的名字,这时候如何区分?签名这时候就是起区分作用的。    ...

2306
来自专栏魏艾斯博客www.vpsss.net

腾讯云 CDN 续期 Let’s Encrypt 证书的操作过程

今天要说的是腾讯云 CDN 续期 Let’s Encrypt 证书的操作过程,常来的朋友都知道魏艾斯博客放在腾讯云了(点我打开抢 3 折特惠),同时还用了腾讯云...

4631

在 CentOS 7 上使用 Apache 的 SSL 证书

本指南将向你演示如何启用 SSL 来保护由 CentOS 或者 Fedora 上的 Apache 提供服务的网站。

2312

扫码关注云+社区

领取腾讯云代金券