Skip to content

Commit

Permalink
新增证书部署到阿里云CDN和DCND
Browse files Browse the repository at this point in the history
  • Loading branch information
mouday committed Jul 25, 2024
1 parent 3d0aab4 commit 9ce32bc
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 6 deletions.
67 changes: 67 additions & 0 deletions domain_admin/api/issue_certificate_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,20 @@ def get_issue_certificate_by_id():
data = issue_certificate_row.to_dict()
data['deploy_dns'] = None
data['deploy_host'] = None
data['cert_deploy_host'] = None
data['cert_deploy_dns'] = None

if issue_certificate_row.challenge_deploy_type_id == ChallengeDeployTypeEnum.SSH:
data['deploy_host'] = HostModel.get_or_none(HostModel.id == issue_certificate_row.challenge_deploy_id)

elif issue_certificate_row.challenge_deploy_type_id == ChallengeDeployTypeEnum.DNS:
data['deploy_dns'] = DnsModel.get_or_none(DnsModel.id == issue_certificate_row.challenge_deploy_id)

if issue_certificate_row.deploy_type_id == SSLDeployTypeEnum.SSH:
data['cert_deploy_host'] = HostModel.get_or_none(HostModel.id == issue_certificate_row.deploy_host_id)
elif issue_certificate_row.deploy_type_id in [SSLDeployTypeEnum.OSS, SSLDeployTypeEnum.CDN, SSLDeployTypeEnum.DCDN]:
data['cert_deploy_dns'] = DnsModel.get_or_none(DnsModel.id == issue_certificate_row.deploy_host_id)

return data


Expand Down Expand Up @@ -401,6 +408,66 @@ def deploy_cert_to_oss():
return ret


def deploy_cert_to_cdn():
"""
部署证书到阿里云cdn
:return:
"""
issue_certificate_id = request.json['issue_certificate_id']
dns_id = request.json['dns_id']

ret = issue_certificate_service.deploy_cert_to_cdn(
issue_certificate_id=issue_certificate_id,
dns_id=dns_id,
)

# 更新验证信息
IssueCertificateModel.update(
deploy_type_id=SSLDeployTypeEnum.CDN,
deploy_host_id=dns_id,
ssl_deploy_status=DeployStatusEnum.SUCCESS
).where(
IssueCertificateModel.id == issue_certificate_id
).execute()

# 验证成功后, check_auto_renew
issue_certificate_service.check_auto_renew(
issue_certificate_id=issue_certificate_id
)

return ret


def deploy_cert_to_dcdn():
"""
部署证书到阿里云dcdn
:return:
"""
issue_certificate_id = request.json['issue_certificate_id']
dns_id = request.json['dns_id']

ret = issue_certificate_service.deploy_cert_to_dcdn(
issue_certificate_id=issue_certificate_id,
dns_id=dns_id,
)

# 更新验证信息
IssueCertificateModel.update(
deploy_type_id=SSLDeployTypeEnum.DCDN,
deploy_host_id=dns_id,
ssl_deploy_status=DeployStatusEnum.SUCCESS
).where(
IssueCertificateModel.id == issue_certificate_id
).execute()

# 验证成功后, check_auto_renew
issue_certificate_service.check_auto_renew(
issue_certificate_id=issue_certificate_id
)

return ret


def add_dns_domain_record():
"""
添加dns记录
Expand Down
4 changes: 4 additions & 0 deletions domain_admin/enums/ssl_deploy_type_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ class SSLDeployTypeEnum(object):
WEB_HOOK = 1

OSS = 2

CDN = 3

DCDN = 4
2 changes: 2 additions & 0 deletions domain_admin/router/api_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@
'/api/getAllowCommands': issue_certificate_api.get_allow_commands,
'/api/notifyWebHook': issue_certificate_api.notify_web_hook,
'/api/deployCertToOss': issue_certificate_api.deploy_cert_to_oss,
'/api/deployCertToCdn': issue_certificate_api.deploy_cert_to_cdn,
'/api/deployCertToDcdn': issue_certificate_api.deploy_cert_to_dcdn,
'/api/addDnsDomainRecord': issue_certificate_api.add_dns_domain_record,
'/api/updateRowAutoRenew': issue_certificate_api.update_row_auto_renew,
'/api/getIssueCertificateOptions': issue_certificate_api.get_issue_certificate_options,
Expand Down
68 changes: 67 additions & 1 deletion domain_admin/service/issue_certificate_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
from domain_admin.utils.acme_util.key_type_enum import KeyTypeEnum
from domain_admin.utils.cert_util import cert_common
from domain_admin.utils.flask_ext.app_exception import AppException
from domain_admin.utils.open_api import aliyun_domain_api, tencentcloud_domain_api, aliyun_oss_api
from domain_admin.utils.open_api import aliyun_domain_api, tencentcloud_domain_api, aliyun_oss_api, aliyun_cdn_api, \
aliyun_dcdn_api
from domain_admin.utils.open_api.aliyun_domain_api import RecordTypeEnum
from domain_admin import config

Expand Down Expand Up @@ -338,6 +339,17 @@ def renew_certificate_row(row):
dns_id=row.deploy_host_id
)

elif row.deploy_type_id == SSLDeployTypeEnum.CDN:
deploy_cert_to_cdn(
issue_certificate_id=row.id,
dns_id=row.deploy_host_id
)
elif row.deploy_type_id == SSLDeployTypeEnum.DCDN:
deploy_cert_to_dcdn(
issue_certificate_id=row.id,
dns_id=row.deploy_host_id
)


def deploy_verify_file(host_id, verify_deploy_path, challenges):
"""
Expand Down Expand Up @@ -587,6 +599,60 @@ def deploy_cert_to_oss(issue_certificate_id, dns_id):
)


def deploy_cert_to_cdn(issue_certificate_id, dns_id):
"""
部署ssl证书到cdn
"""
issue_certificate_row = IssueCertificateModel.get_by_id(issue_certificate_id)

if not issue_certificate_row:
raise AppException('证书数据不存在')

dns_row = DnsModel.get_by_id(dns_id)
if not dns_row:
raise AppException('DNS数据不存在')

domain = issue_certificate_row.domains[0]

# oss_info = aliyun_oss_api.cname_to_oss_info(domain)
# if not oss_info:
# raise AppException('dns 未设置')
#
# logger.info("oss_info: %s", oss_info)

aliyun_cdn_api.set_cdn_domain_ssl_certificate_v2(
access_key_id=dns_row.access_key,
access_key_secret=dns_row.secret_key,
domain_name=domain,
certificate=issue_certificate_row.ssl_certificate,
private_key=issue_certificate_row.ssl_certificate_key,
)


def deploy_cert_to_dcdn(issue_certificate_id, dns_id):
"""
部署ssl证书到dcdn
"""
issue_certificate_row = IssueCertificateModel.get_by_id(issue_certificate_id)

if not issue_certificate_row:
raise AppException('证书数据不存在')

dns_row = DnsModel.get_by_id(dns_id)
if not dns_row:
raise AppException('DNS数据不存在')

domain = issue_certificate_row.domains[0]

aliyun_dcdn_api.set_dcdn_domain_ssl_certificate(
access_key_id=dns_row.access_key,
access_key_secret=dns_row.secret_key,
domain_name=domain,
certificate=issue_certificate_row.ssl_certificate,
private_key=issue_certificate_row.ssl_certificate_key,
)


def check_auto_renew(issue_certificate_id):
"""
首次申请,自动判断是否可以自动续期
Expand Down
12 changes: 9 additions & 3 deletions domain_admin/utils/open_api/aliyun_cas_api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
@File : aliyun_api.py
@File : aliyun_cas_api.py
@Date : 2024-07-24
"""

Expand All @@ -9,15 +9,19 @@
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models

from domain_admin.utils import uuid_util


def upload_user_certificate(
access_key_id, access_key_secret,
cert_name, cert, key
):
"""
上传证书
@return: Client
@return: cert_id
@throws Exception
https://api.aliyun.com/api-tools/sdk/cas?spm=api-workbench.api_explorer.0.0.74935d8cS3kyPm&version=2020-04-07&language=python-tea&tab=primer-doc
"""
# 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
# 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378659.html。
Expand All @@ -39,4 +43,6 @@ def upload_user_certificate(

runtime = util_models.RuntimeOptions()

client.upload_user_certificate_with_options(upload_user_certificate_request, runtime)
response = client.upload_user_certificate_with_options(upload_user_certificate_request, runtime)

return response.body.cert_id
91 changes: 89 additions & 2 deletions domain_admin/utils/open_api/aliyun_cdn_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,22 @@
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models

from domain_admin.utils import uuid_util
from domain_admin.utils.open_api import aliyun_cas_api

def set_cdn_domain_ssl_certificate(access_key_id, access_key_secret, domain_name):

def set_cdn_domain_ssl_certificate(
access_key_id, access_key_secret,
domain_name,
cert_id, cert_name):
"""
https://api.aliyun.com/api-tools/sdk/Cdn?spm=api-workbench.api_explorer.0.0.539f3761ceDHDv&version=2018-05-10&language=python-tea&tab=primer-doc
:param access_key_id:
:param access_key_secret:
:param domain_name:
:param cert_id:
:return:
"""
# 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
# 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378659.html。
config = open_api_models.Config(
Expand All @@ -19,11 +33,14 @@ def set_cdn_domain_ssl_certificate(access_key_id, access_key_secret, domain_name
# 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。,
access_key_secret=access_key_secret,
)

# Endpoint 请参考 https://api.aliyun.com/product/Cdn
config.endpoint = f'cdn.aliyuncs.com'
config.endpoint = 'cdn.aliyuncs.com'
client = Cdn20180510Client(config)

set_cdn_domain_sslcertificate_request = cdn_20180510_models.SetCdnDomainSSLCertificateRequest(
cert_id=cert_id,
cert_name=cert_name,
cert_type='cas',
domain_name=domain_name,
sslprotocol='on'
Expand All @@ -32,3 +49,73 @@ def set_cdn_domain_ssl_certificate(access_key_id, access_key_secret, domain_name

# 复制代码运行请自行打印 API 的返回值
client.set_cdn_domain_sslcertificate_with_options(set_cdn_domain_sslcertificate_request, runtime)


def set_cdn_domain_cert(
access_key_id, access_key_secret,
domain,
certificate, private_key):
"""
先上传,再部署
:param access_key_id:
:param access_key_secret:
:param domain:
:param certificate:
:param private_key:
:return:
"""
cert_name = uuid_util.get_uuid()
cert_id = aliyun_cas_api.upload_user_certificate(
access_key_id=access_key_id,
access_key_secret=access_key_secret,
cert_name=cert_name,
cert=certificate,
key=private_key
)

print('cert_id: ', cert_id)

set_cdn_domain_ssl_certificate(
access_key_id=access_key_id,
access_key_secret=access_key_secret,
domain_name=domain,
cert_id=cert_id,
cert_name=cert_name
)


def set_cdn_domain_ssl_certificate_v2(
access_key_id, access_key_secret,
domain_name,
certificate, private_key
):
"""
直接部署到CDN
https://api.aliyun.com/api-tools/sdk/Cdn?spm=api-workbench.api_explorer.0.0.539f3761ceDHDv&version=2018-05-10&language=python-tea&tab=primer-doc
:return:
"""
# 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
# 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378659.html。
config = open_api_models.Config(
# 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。,
access_key_id=access_key_id,
# 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。,
access_key_secret=access_key_secret,
)

# Endpoint 请参考 https://api.aliyun.com/product/Cdn
config.endpoint = 'cdn.aliyuncs.com'
client = Cdn20180510Client(config)

set_cdn_domain_sslcertificate_request = cdn_20180510_models.SetCdnDomainSSLCertificateRequest(
domain_name=domain_name,
cert_type='upload',
sslpri=private_key,
sslpub=certificate,
sslprotocol='on'
)

runtime = util_models.RuntimeOptions()

# 复制代码运行请自行打印 API 的返回值
client.set_cdn_domain_sslcertificate_with_options(set_cdn_domain_sslcertificate_request, runtime)
41 changes: 41 additions & 0 deletions domain_admin/utils/open_api/aliyun_dcdn_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
"""
aliyun_dcdn_api.py
"""
# This file is auto-generated, don't edit it. Thanks.

from alibabacloud_dcdn20180115 import models as dcdn_20180115_models
from alibabacloud_dcdn20180115.client import Client as dcdn20180115Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_tea_util import models as util_models


def set_dcdn_domain_ssl_certificate(
access_key_id, access_key_secret,
domain_name,
certificate, private_key):
"""
https://api.aliyun.com/api/dcdn/2018-01-15/SetDcdnDomainSSLCertificate?spm=api-workbench.API%20Document.0.0.26c93c7bP4PZn9&tab=DOC&lang=PYTHON&params={%22DomainName%22:%22www%22,%22SSLProtocol%22:%22on%22,%22SSLPub%22:%22xxx%22,%22SSLPri%22:%22xxx%22}
"""
# 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
# 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378659.html。
config = open_api_models.Config(
# 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。,
access_key_id=access_key_id,
# 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。,
access_key_secret=access_key_secret
)
# Endpoint 请参考 https://api.aliyun.com/product/dcdn
config.endpoint = 'dcdn.aliyuncs.com'
client = dcdn20180115Client(config)

set_dcdn_domain_sslcertificate_request = dcdn_20180115_models.SetDcdnDomainSSLCertificateRequest(
domain_name=domain_name,
sslprotocol='on',
sslpub=certificate,
sslpri=private_key
)
runtime = util_models.RuntimeOptions()

# 复制代码运行请自行打印 API 的返回值
client.set_dcdn_domain_sslcertificate_with_options(set_dcdn_domain_sslcertificate_request, runtime)
8 changes: 8 additions & 0 deletions domain_admin/utils/uuid_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,12 @@


def get_uuid():
"""
返回36位的uuid
:return: eg: 2817cac5-d65f-4fec-8e78-1bdaf55655e8
"""
return str(uuid.uuid4())


if __name__ == '__main__':
print(get_uuid())
Loading

0 comments on commit 9ce32bc

Please sign in to comment.