阿里云自动续签SSL证书
3 分钟
前言
由于国内法律法规的限制,免费的SSL
证书由1年
变成了3个月
,对于在弄了一个带有自己域名博客的人来说,这是一件比较无语的事情,每3个月重复性的工作需要手动更换SSL
证书。网上也有很多docker
版本的自动续签的应用,如宝塔
,acme.sh
等等。但是安装这种软件的话,功能就多了许多其它的,个人又不需要。因此自己简单弄一个脚本去实现就十分必要。
操作过程
1、首先需要在工作台创建一个子账号,并取得账号分配的key
与secret
,给子用户分配AliyunDNSFULLAccess
与AliyunYunDunCertAccess
权限。
2、生成2048
位的crs
证书,一般以RSA
算法为主,通过Linux系统中自带的openssl
命令生成即可
#openssl req -new -nodes -sha256 -newkey rsa:2048 -keyout blog.key -out blog.csr -config openssl.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[dn]
CN = aiwin.net.cn
emailAddress = test@foxmail.com
O = zirong
OU = liu
L = Guangzhou
ST = Guangdong
C = CN
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = aiwin.net.cn
DNS.2 = www.aiwin.net.cn
3、通过crontab
定时任务每3个月执行脚本,注意脚本中的crs
需要带上\r\n
或\n
,最好通过一行直接写完,否则传输到阿里云接口会因为没有固定格式的分行而报错。
import os
import time
import logging
from alibabacloud_cas20200407.client import Client as cas20200407Client
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_cas20200407 import models as cas_20200407_models
from alibabacloud_tea_util import models as util_models
from alibabacloud_alidns20150109.client import Client as Alidns20150109Client
from alibabacloud_alidns20150109 import models as alidns_20150109_models
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
'''
全局存储OrderId与RecordId
'''
OrderIdList = []
RecordIdList = []
class SSL:
def __init__(self, client, endpoint):
self.client = self.create_client(client, endpoint)
'''
环境变量设置id与secret,根据不同的方法与endpoint创建不同的安全功能客户端
@ALIBABA_CLOUD_ACCESS_KEY_ID
@ALIBABA_CLOUD_ACCESS_KEY_SECRET
'''
@staticmethod
def create_client(func, endpoint):
credential = CredentialClient()
config = open_api_models.Config(
credential=credential,
region_id='cn-hangzhou',
endpoint=endpoint,
connect_timeout=5000,
read_timeout=5000
)
return func(config)
'''
请求创建SSL证书并获取订单ID
'''
@staticmethod
def main(self):
create_certificate_for_package_request_request = cas_20200407_models.CreateCertificateForPackageRequestRequest(
csr='''-----BEGIN CERTIFICATE REQUEST-----\r\n内容\r\n-----END CERTIFICATE REQUEST-----''',
product_code='digicert-free-1-free',
username='xxxx',
phone='xxxx',
email='test@foxmail.com',
domain='aiwin.net.cn',
validate_type='DNS'
)
runtime = util_models.RuntimeOptions()
try:
response = self.client.create_certificate_for_package_request_with_options(
create_certificate_for_package_request_request, runtime)
OrderIdList.append(response.body.order_id)
self.parseOrderId(self)
except Exception as error:
logging.error(error)
'''
通过订单Id,请求SSL证书详情,获取验证时需要设置的域名与TXT记录,并且每相隔60秒请求一次是否已签发接口,签发即删除DNS记录并获取pem与key
'''
@staticmethod
def parseOrderId(self):
describe_certificate_state_request = cas_20200407_models.DescribeCertificateStateRequest(
order_id=OrderIdList[0]
)
runtime = util_models.RuntimeOptions()
try:
response = self.client.describe_certificate_state_with_options(describe_certificate_state_request, runtime)
self.addDNS(self, response.body.record_domain, response.body.record_value)
IssuedResult = self.ConfirmSSLIssued(self)
while not IssuedResult:
time.sleep(60)
IssuedResult = self.ConfirmSSLIssued(self)
self.delDNS(self)
self.getPrivatePem(self)
except Exception as error:
logging.error(error)
'''
添加DNS记录
'''
@staticmethod
def addDNS(self, domain, value):
self.client = self.create_client(Alidns20150109Client, 'alidns.cn-hangzhou.aliyuncs.com')
add_domain_record_request = alidns_20150109_models.AddDomainRecordRequest(
lang='zh',
type='TXT',
value='wdadawdawd.txt',
rr='_dnsauth.aiwin.net.cn',
# value=value,
# rr=domain,
domain_name='aiwin.net.cn'
)
runtime = util_models.RuntimeOptions()
try:
response = self.client.add_domain_record_with_options(add_domain_record_request, runtime)
RecordIdList.append(response.body.record_id)
except Exception as error:
logging.error(error)
'''
根据RecordId删除DNS记录,并清空RecordId
'''
@staticmethod
def delDNS(self) -> None:
self.client = self.create_client(Alidns20150109Client, 'alidns.cn-hangzhou.aliyuncs.com')
delete_domain_record_request = alidns_20150109_models.DeleteDomainRecordRequest(
record_id=RecordIdList[0],
lang='zh'
)
runtime = util_models.RuntimeOptions()
try:
response = self.client.delete_domain_record_with_options(delete_domain_record_request, runtime)
if response.status_code == 200:
RecordIdList.clear()
print(RecordIdList)
except Exception as error:
logging.error(error)
'''
验证创建的证书是否已签发状态
'''
@staticmethod
def ConfirmSSLIssued(self):
self.client = self.create_client(cas20200407Client, 'cas.aliyuncs.com')
list_user_certificate_order_request = cas_20200407_models.ListUserCertificateOrderRequest(status='ISSUED')
runtime = util_models.RuntimeOptions()
try:
response = self.client.list_user_certificate_order_with_options(list_user_certificate_order_request,
runtime)
for ResponseBodyCertificateOrderList in response.body.certificate_order_list:
if OrderIdList[0] == ResponseBodyCertificateOrderList.order_id:
return True
return False
except Exception as error:
logging.error(error)
'''
根据订单ID,查看证书的详情,并取得certificate与private_key,即nginx文件中的pem和key内容
'''
@staticmethod
def getPrivatePem(self):
self.client = self.create_client(cas20200407Client, 'cas.aliyuncs.com')
describe_certificate_state_request = cas_20200407_models.DescribeCertificateStateRequest(
order_id=OrderIdList[0]
)
runtime = util_models.RuntimeOptions()
try:
response = self.client.describe_certificate_state_with_options(describe_certificate_state_request, runtime)
self.CreateFile(self, "\n".join(response.body.certificate.splitlines()),
"\n".join(response.body.private_key.splitlines()))
except Exception as error:
logging.error(error)
'''
移除原文件,将新内容写入到nginx.conf路径文件当中
'''
@staticmethod
def CreateFile(self, pem_body, key_body):
try:
os.remove('nginx中pem的路径')
os.remove('nginx中key的路径')
KeyFile = open('替换为域名.key', 'a')
PemFile = open('替换为域名.pem', 'a')
KeyFile.write(key_body)
PemFile.write(pem_body)
logging.info('pem与key文件创建成功')
except Exception as error:
logging.error(error)
if __name__ == '__main__':
ssl = SSL(cas20200407Client, 'cas.aliyuncs.com')
ssl.main(ssl)
~ ~ The End ~ ~


文章标题:阿里云自动续签SSL证书
文章链接:https://www.aiwin.net.cn/index.php/archives/4443/
最后编辑:2025 年 5 月 6 日 20:50 By Aiwin
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)