likes
comments
collection
share

分析七牛云接口利用腾讯云API开发一个基于Python脚本命令行的域名HTTPS证书申请工具

作者站长头像
站长
· 阅读数 71

前言

需要回顾前面几天的几篇文章的代码:

前面已经对七牛云的证书申请的接口进行了分析,完成了整个证书申请流程,其中在七牛云申请免费HTTPS证书的中间需要给域名添加一个DNS解析证明域名归属也根据腾讯云的API文档完成了,今天就来整合这几个接口。

流程整理

首选需要一些必备的账号(腾讯云账户secretId,secretKey,七牛云账号密码),必备的域名,Chrome seleium环境,下面用一个简单的流程图来表示:

未签发
返回检查
已签发
seleium登录七牛云获取cookie
申请证书
完善证书申请信息
腾讯云DNS解析
检查证书状态,是否可下载?
设置压缩包密码
下载
解压
展示

代码

前面所有功能我都封装成了一个个函数,接着就需要把他们组合成一起,主要是对上面的流程进行函数整合,为了方便展示,我就把所有的代码放在一起展示:

# coding=UTF-8
import requests
import json, time, os, zipfile, sys
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.dnspod.v20210323 import dnspod_client, models

user_name = '********@*****.com'
password = '*****'
pwd = '1'
chorme_options = Options()
chorme_options.add_argument("--disable-gpu")
driver = webdriver.Chrome(options=chorme_options)  # 初始化Chrome驱动
driver.implicitly_wait(20)

headers = {
    'authority': 'portal.qiniu.com',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36',
    'content-type': 'application/json',
    'accept': '*/*',
    'origin': 'https://portal.qiniu.com',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-mode': 'cors',
    'sec-fetch-dest': 'empty',
    'referer': 'https://portal.qiniu.com/certificate/apply',
    'accept-language': 'zh,zh-CN;q=0.9',
}


def set_dns(domain, record_type, value, sub_domain):
    try:
        # 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
        # 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
        cred = credential.Credential("**************", "**********")
        # 实例化一个http选项,可选的,没有特殊需求可以跳过
        httpProfile = HttpProfile()
        httpProfile.endpoint = "dnspod.tencentcloudapi.com"

        # 实例化一个client选项,可选的,没有特殊需求可以跳过
        clientProfile = ClientProfile()
        clientProfile.httpProfile = httpProfile
        # 实例化要请求产品的client对象,clientProfile是可选的
        client = dnspod_client.DnspodClient(cred, "", clientProfile)

        # 实例化一个请求对象,每个接口都会对应一个request对象
        req = models.CreateRecordRequest()
        params = {
            "Domain": domain,
            "RecordType": record_type,
            "RecordLine": "默认",
            "Value": value,
            "SubDomain": sub_domain
        }
        req.from_json_string(json.dumps(params))

        # 返回的resp是一个CreateRecordResponse的实例,与请求对象对应
        resp = client.CreateRecord(req)
        # 输出json格式的字符串回包
        print(resp.to_json_string())
        return True
    except TencentCloudSDKException as err:
        print(err)
        return False


def create_ssl(common_name, cookie):
    data = '{"product_short_name":"TrustAsiaTLSC1","years":1,"limit":0,"wildcard_limit":-1,"product_type":"single"}'
    response = requests.post('https://portal.qiniu.com/api/certificate/v1/sslorder/prepare', headers=headers, cookies=cookie,
                             data=data)
    res = json.loads(response.text)
    order_id = res['data']['order_id']
    data = {
        'common_name': common_name,
        'org_addressLine1': '***************',
        'org_city': '深圳市',
        'org_region': '广东',
        'org_country': 'CN',
        'org_postalCode': '430000',
        'org_organization_name': '***********',
        'org_division': '技术部',
        'org_phone': '027-******',
        'admin_firstName': '*',
        'admin_lastName': '**',
        'admin_phone': '**********',
        'admin_email': '******@**.com',
        'orderid': order_id,
        'auth_method': 'DNS',
        'admin_title': '*******',
        'dns_names': '',
        'cert_name': common_name,
        'encrypt': 'RSA',
        'toBeDeployedDomains': [],
    }
    response = requests.post('https://portal.qiniu.com/api/certificate/v1/sslorder/create', headers=headers,
                             cookies=cookie, json=data)
    time.sleep(2)
    response = requests.get('https://portal.qiniu.com/api/certificate/v1/sslorder/' + order_id, headers=headers,
                            cookies=cookie)
    res = response.json()
    print("证书申请成功,域名为:" + common_name + " TXT记录名:" + res['data']['auth_array'][0]['AuthKey'] + " TXT记录值:" +
          res['data']['auth_array'][0]['AuthValue'])
    return {'AuthKey': res['data']['auth_array'][0]['AuthKey'],
            'AuthValue': res['data']['auth_array'][0]['AuthValue'],
            'order_id': order_id}  # 返回记录值


def check_status(order_id, cookie):
    response = requests.get('https://portal.qiniu.com/api/certificate/v1/sslorder/' + order_id, headers=headers,
                            cookies=cookie)
    res = response.json()
    if res['data']['certID'] == '':
        return ''
    else:
        return res['data']['certID']


def download_data(cookie, cert_id, pwd):
    url = 'https://portal.qiniu.com/api/certificate/v1/ssl/download?certid=' + cert_id + '&type=PEM_Nginx' \
                                                                                         '&key_store_pwd=' + pwd
    response = requests.get(url, headers=headers, cookies=cookie)
    save_path = os.getcwd() + '/cert/' + cert_id + '.zip'
    with open(save_path, 'ab') as f:
        f.write(response.content)
        f.flush()
    print(save_path + " 下载完成!")


def decode_package(cert_id, pwd):
    unzip_path = os.getcwd() + '\cert\' + cert_id
    zip_file = zipfile.ZipFile(os.getcwd() + '\cert\' + cert_id + '.zip')
    if not os.path.exists(unzip_path):
        os.makedirs(unzip_path)
    zip_list = zip_file.namelist()  # 得到压缩包里所有文件
    for i in zip_list:
        zip_file.extract(i, unzip_path, pwd.encode('utf-8'))  # 解压到的目标文件夹
    zip_file.close()
    os.remove(os.getcwd() + '\cert\' + cert_id + '.zip')  # 删掉压缩包


def get_cookie():

    driver.get(url='https://sso.qiniu.com/')  # 直接访问登录页
    user_input = driver.find_element(By.ID, 'email')  # 获取用户名输入框
    user_input.send_keys(user_name)  # 输入用户名
    password_input = driver.find_element(By.ID, 'password')  # 获取密码框
    password_input.send_keys(password)  # 输入密码
    driver.find_element(By.ID, 'login-button').click()  # 登录
    try:
        WebDriverWait(driver, 60).until(EC.visibility_of_element_located(
            (By.CLASS_NAME, "user-plane-entry")))  # 等待网页跳转,超时等待60秒
    except:
        print('登陆超时,失败')  # 等待超过了60
        # driver.quit()
    cookie = driver.get_cookies()  # 获取cookie 此时是键值对
    return cookie


def read_file(domain, cet_id):
    with open(os.getcwd() + '\cert\' + cet_id + '\' + domain + '.crt', 'r') as f1:
        print(f1.read())
    with open(os.getcwd() + '\cert\' + cet_id + '\' + domain + '.crt', 'r') as f2:
        print(f2.read())


if __name__ == '__main__':
    common_name = sys.argv[1]  # 读取完整需要申请证书的域名
    cookie = get_cookie()
    qiniu_cookie = {}
    # 从列表取出字典,从字典获取name和对应的value,再添加到cookies字典中
    for cookie_dic in cookie:
        qiniu_cookie[cookie_dic['name']] = cookie_dic['value']  # 列表转字典
    dns_info = create_ssl(common_name, qiniu_cookie)
    domain_name = common_name.replace(common_name.split('.')[0]+'.', '')  # 去掉二级域名前缀 符合腾讯云API要求
    sub_domain = dns_info['AuthKey'].split('.')[0] + '.' + dns_info['AuthKey'].split('.')[1]  # 子域名参数处理  为了符合腾讯云API要求
    set_dns(domain_name, 'CNAME', dns_info['AuthValue'], sub_domain)
    count = 0
    cert_id = ''
    while True:
        time.sleep(60)
        cert_id = check_status(dns_info['order_id'], qiniu_cookie)
        if cert_id != '':
            print('已签发')
            break
        print('还未签发')
        count += 1
        if count == 60:
            print('检查超时,请手动检查')
            quit()
    download_data(qiniu_cookie, cert_id, pwd)  # 下载证书压缩包
    decode_package(cert_id, pwd) # 解压压缩包
    read_file(common_name, cert_id) # 展示证书内容

运行效果如:

分析七牛云接口利用腾讯云API开发一个基于Python脚本命令行的域名HTTPS证书申请工具

总结

敏感的信息都通过*号替换还有水印遮盖了~

短短两百行代码今天调试了很久,终于把整个流程走通了,花了很多精力,主要是要处理腾讯云API请求格式,文件的处理这里,还有一些参数的共用处理。非常完美,基本上5分钟以内自动地就可以申请一个证书,几乎不会出什么问题,有点繁琐的就是需要一个seleium驱动谷歌浏览器的环境,有机会再用到它再仔细研究登录接口。

转载自:https://juejin.cn/post/7132503603817742367
评论
请登录