200 lines
7.3 KiB
Python
200 lines
7.3 KiB
Python
|
#!/usr/bin/env python
|
|||
|
# -*- coding: utf-8 -*-
|
|||
|
# author: 'zfb'
|
|||
|
# time: 2020-12-02 15:56
|
|||
|
from api import cdn, ecdn, ssl, tools
|
|||
|
import config
|
|||
|
|
|||
|
def run_config_ssl(id, key, cer_file, key_file):
|
|||
|
'''上传SSl证书到腾讯云SSL证书管理,返回新证书的id
|
|||
|
'''
|
|||
|
cert_info = {
|
|||
|
# Let's Encrypt 是通过中级 CA 机构颁发的证书,拿到的证书文件包含
|
|||
|
# whuzfb.cn.cer ca.cer
|
|||
|
# 需要人为地将服务器证书与中间证书拼接在一起(acme.sh已经进行拼接)
|
|||
|
# fullchain.cer
|
|||
|
"cer": tools.read_file(cer_file),
|
|||
|
"key": tools.read_file(key_file),
|
|||
|
"type": "CA"
|
|||
|
}
|
|||
|
ssl_client = ssl.get_ssl_client_instance(id, key)
|
|||
|
cert_list = ssl.get_cert_list(ssl_client)
|
|||
|
for cert in cert_list:
|
|||
|
# 获取每个证书的id
|
|||
|
cert_id = cert.CertificateId
|
|||
|
# 获取每个证书的信息
|
|||
|
# if domain == ssl.get_cert_info(ssl_client, cert_id).Domain:
|
|||
|
# # 删除证书
|
|||
|
# # delete_cert(client, cert_id)
|
|||
|
# # break
|
|||
|
# print(cert_id)
|
|||
|
# 上传证书,获取新证书的id
|
|||
|
id = ssl.upload_cert(ssl_client, cert_info)
|
|||
|
if len(id)>0:
|
|||
|
return id
|
|||
|
else:
|
|||
|
exit("获取新证书id失败")
|
|||
|
|
|||
|
|
|||
|
def run_config_cdn(id, key, domain, cert_id):
|
|||
|
'''该函数实现为CDN更新ssl证书的功能
|
|||
|
'''
|
|||
|
cdn_client = cdn.get_cdn_client_instance(id, key)
|
|||
|
cdns = cdn.get_cdn_detail_info(cdn_client)
|
|||
|
https = None
|
|||
|
for _cdn in cdns:
|
|||
|
if _cdn.Domain == domain:
|
|||
|
https = _cdn.Https
|
|||
|
break
|
|||
|
print(https)
|
|||
|
# generate_https(https)
|
|||
|
cdn.update_cdn_ssl(cdn_client, domain, cert_id)
|
|||
|
|
|||
|
def https_options_enabler(id, key, domain, http2, hsts, age, hsts_subdomain, ocsp):
|
|||
|
'''开启HTTPS配置中的部分选项
|
|||
|
'''
|
|||
|
cdn_client = cdn.get_cdn_client_instance(id, key)
|
|||
|
cdn.update_cdn_https_options(cdn_client, domain, http2, hsts, age, hsts_subdomain, ocsp)
|
|||
|
|
|||
|
def delete_old_ssls(id, key, cdn_domain, ignore_id):
|
|||
|
'''删除某个CDN的,除ignore_id以外的所有ssl证书
|
|||
|
'''
|
|||
|
ssl_client = ssl.get_ssl_client_instance(id, key)
|
|||
|
cert_list = ssl.get_cert_list(ssl_client)
|
|||
|
for cert in cert_list:
|
|||
|
cert_id = cert.CertificateId
|
|||
|
# 刚上传的这个证书不删除
|
|||
|
if cert_id == ignore_id:
|
|||
|
continue
|
|||
|
cert_info = ssl.get_cert_info(ssl_client, cert_id)
|
|||
|
cert_domain_and_alt_name = [cert_info.Domain] + cert_info.SubjectAltName
|
|||
|
matched = False
|
|||
|
# 判断域名匹配
|
|||
|
for cert_name in cert_domain_and_alt_name:
|
|||
|
if cert_name:
|
|||
|
# 判断主域名或多域名
|
|||
|
if cert_name == cdn_domain:
|
|||
|
matched = True
|
|||
|
break
|
|||
|
# 判断泛域名 m=['*','example.cn']
|
|||
|
m = cert_name.split('.', 1)
|
|||
|
n = cdn_domain.split('.', 1)
|
|||
|
if m[0] == "*" and m[1] == n[1]:
|
|||
|
matched = True
|
|||
|
break
|
|||
|
# 根据结果删除证书
|
|||
|
if matched:
|
|||
|
ssl.delete_cert(ssl_client, cert_id)
|
|||
|
|
|||
|
|
|||
|
def run_config_ecdn(id, key, domain, cert_id):
|
|||
|
'''全站加速网络:为指定域名的CDN更新SSL证书
|
|||
|
'''
|
|||
|
ecdn_client = ecdn.get_ecdn_client_instance(id, key)
|
|||
|
ecdn.get_ecdn_basic_info(ecdn_client)
|
|||
|
cdns = ecdn.get_ecdn_detail_info(ecdn_client)
|
|||
|
ecdn.update_ecdn_ssl(ecdn_client, domain, cert_id)
|
|||
|
|
|||
|
|
|||
|
def run_url_push(id, key, domain, urls_file):
|
|||
|
'''为CDN推送预热URL
|
|||
|
'''
|
|||
|
from time import sleep
|
|||
|
from os.path import isfile
|
|||
|
urls = []
|
|||
|
try:
|
|||
|
urls = tools.get_sitemap_urls("https://{}/sitemap.xml".format(domain))
|
|||
|
except Exception as e:
|
|||
|
print(repr(e))
|
|||
|
if isfile(urls_file):
|
|||
|
urls = urls + tools.get_urls_from_file(urls_file)
|
|||
|
cdn_client = cdn.get_cdn_client_instance(id, key)
|
|||
|
cdn_region = cdn.get_cdn_basic_info(cdn_client, domain)[0].Area
|
|||
|
# 预热URL支持area为global的参数,但是为了方便统计用量配额,手动分开刷新
|
|||
|
if cdn_region == 'global':
|
|||
|
cdn_region = ['mainland', 'overseas']
|
|||
|
else:
|
|||
|
cdn_region = [cdn_region]
|
|||
|
info = cdn.get_cdn_url_push_info(cdn_client)
|
|||
|
# 统计预热url数量
|
|||
|
cnt = 0
|
|||
|
# 根据加速域名配置的区域进行预热
|
|||
|
for i in info:
|
|||
|
if i.Area in cdn_region:
|
|||
|
grp_size = i.Batch
|
|||
|
available = i.Available
|
|||
|
print("正在对区域{0}进行url预热,剩余配额{1}条".format(i.Area, available))
|
|||
|
new_urls = tools.resize_url_list(urls, grp_size)
|
|||
|
for url_grp in new_urls:
|
|||
|
res = cdn.update_cdn_url_push(cdn_client, url_grp, i.Area)
|
|||
|
if res:
|
|||
|
cnt = cnt + len(url_grp)
|
|||
|
sleep(0.1)
|
|||
|
else:
|
|||
|
break
|
|||
|
print("成功预热{}个URL".format(cnt))
|
|||
|
|
|||
|
|
|||
|
def run_purge_url(id, key, domain, urls_file):
|
|||
|
'''为CDN推送刷新URL
|
|||
|
'''
|
|||
|
from time import sleep
|
|||
|
from os.path import isfile
|
|||
|
urls = []
|
|||
|
try:
|
|||
|
urls = tools.get_sitemap_urls("https://{}/sitemap.xml".format(domain))
|
|||
|
except Exception as e:
|
|||
|
print(repr(e))
|
|||
|
if isfile(urls_file):
|
|||
|
urls = urls + tools.get_urls_from_file(urls_file)
|
|||
|
cdn_client = cdn.get_cdn_client_instance(id, key)
|
|||
|
cdn_region = cdn.get_cdn_basic_info(cdn_client, domain)[0].Area
|
|||
|
# 刷新URL不支持area为global的参数
|
|||
|
if cdn_region == 'global':
|
|||
|
cdn_region = ['mainland', 'overseas']
|
|||
|
else:
|
|||
|
cdn_region = [cdn_region]
|
|||
|
info = cdn.get_cdn_purge_url_info(cdn_client)
|
|||
|
# 统计刷新url数量
|
|||
|
cnt = 0
|
|||
|
# 根据加速域名配置的区域进行刷新
|
|||
|
for i in info:
|
|||
|
if i.Area in cdn_region:
|
|||
|
grp_size = i.Batch
|
|||
|
available = i.Available
|
|||
|
print("正在对区域{0}进行url刷新,剩余配额{1}条".format(i.Area, available))
|
|||
|
new_urls = tools.resize_url_list(urls, grp_size)
|
|||
|
for url_grp in new_urls:
|
|||
|
res = cdn.update_cdn_purge_url(cdn_client, url_grp, i.Area)
|
|||
|
if res:
|
|||
|
cnt = cnt + len(url_grp)
|
|||
|
sleep(0.1)
|
|||
|
else:
|
|||
|
break
|
|||
|
print("成功刷新{}个URL".format(cnt))
|
|||
|
|
|||
|
|
|||
|
if __name__ == "__main__":
|
|||
|
SECRETID = config.SECRETID
|
|||
|
SECRETKEY = config.SECRETKEY
|
|||
|
# 泛域名证书
|
|||
|
if config.UPLOAD_SSL:
|
|||
|
cert_id = run_config_ssl(SECRETID, SECRETKEY, config.CER_FILE, config.KEY_FILE)
|
|||
|
else:
|
|||
|
cert_id = config.CERT_ID
|
|||
|
for my_domain in config.CDN_DOMAIN:
|
|||
|
if config.UPDATE_SSL:
|
|||
|
run_config_cdn(SECRETID, SECRETKEY, my_domain, cert_id)
|
|||
|
if config.ENABLE_HSTS or config.ENABLE_OCSP or config.ENABLE_HTTP2:
|
|||
|
https_options_enabler(SECRETID, SECRETKEY, my_domain, config.ENABLE_HTTP2, config.ENABLE_HSTS,
|
|||
|
config.HSTS_TIMEOUT_AGE, config.HSTS_INCLUDE_SUBDOMAIN, config.ENABLE_OCSP)
|
|||
|
if config.DELETE_OLD_CERTS:
|
|||
|
delete_old_ssls(SECRETID, SECRETKEY, my_domain, cert_id)
|
|||
|
if config.PUSH_URL:
|
|||
|
run_url_push(SECRETID, SECRETKEY, my_domain, config.URLS_FILE)
|
|||
|
if config.PURGE_URL:
|
|||
|
run_purge_url(SECRETID, SECRETKEY, my_domain, config.URLS_FILE)
|
|||
|
# ecdn是全球加速服务,与CDN不同,本账号没有开通该功能
|
|||
|
# run_config_ecdn(SECRETID, SECRETKEY, my_domain, cert_id)
|
|||
|
|