From 5927a3abab19844a5c17e821248db74e7d8db6da Mon Sep 17 00:00:00 2001 From: midoks Date: Wed, 4 Jan 2023 17:48:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9D=A2=E6=9D=BFssl=E7=94=B3=E8=AF=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- class/core/cert_api.py | 2 +- class/core/cert_request.py | 2 +- class/core/config_api.py | 56 ++++++++++++++++++++++++++++++++++++-- route/__init__.py | 11 +++++++- route/static/app/config.js | 53 ++++++++++++++++++++++++++---------- 5 files changed, 103 insertions(+), 21 deletions(-) diff --git a/class/core/cert_api.py b/class/core/cert_api.py index 1c87651c1..9771ec857 100644 --- a/class/core/cert_api.py +++ b/class/core/cert_api.py @@ -825,7 +825,7 @@ fi ret_title, json.dumps(a_auth))) break - if number_of_checks == self._max_check_num: + if number_of_checks == self.__max_check_num: raise StopIteration( "错误:已尝试验证{0}次. 最大验证次数为{1}. 验证时间间隔为{2}秒.".format( number_of_checks, diff --git a/class/core/cert_request.py b/class/core/cert_request.py index a39391258..afe186a5f 100644 --- a/class/core/cert_request.py +++ b/class/core/cert_request.py @@ -736,7 +736,7 @@ class cert_request: ret_title, json.dumps(a_auth))) break - if number_of_checks == self._max_check_num: + if number_of_checks == self.__max_check_num: raise StopIteration( "错误:已尝试验证{0}次. 最大验证次数为{1}. 验证时间间隔为{2}秒.".format( number_of_checks, diff --git a/class/core/config_api.py b/class/core/config_api.py index e13dfeecb..ec0186b66 100755 --- a/class/core/config_api.py +++ b/class/core/config_api.py @@ -340,11 +340,13 @@ class config_api: # 获取面板证书 def getPanelSslApi(self): - cert = {} + cert = self.getPanelSslData() + return mw.getJson(cert) + def getPanelSslData(self): + cert = {} keyPath = 'ssl/private.pem' certPath = 'ssl/cert.pem' - if not os.path.exists(certPath): mw.createSSL() @@ -352,7 +354,7 @@ class config_api: cert['certPem'] = mw.readFile(certPath) cert['rep'] = os.path.exists('ssl/input.pl') cert['info'] = mw.getCertName(certPath) - return mw.getJson(cert) + return cert # 保存面板证书 def savePanelSslApi(self): @@ -378,6 +380,54 @@ class config_api: mw.writeFile('ssl/input.pl', 'True') return mw.returnJson(True, '证书已保存!') + # 申请面板let证书 + def applyPanelLetSslApi(self): + + # check domain is bind? + bind_domain = 'data/bind_domain.pl' + if not os.path.exists(bind_domain): + return mw.returnJson(False, '未绑定域名!') + + siteName = mw.readFile(bind_domain).strip() + auth_to = mw.getRunDir() + "/tmp" + to_args = { + 'domains': [siteName], + 'auth_type': 'http', + 'auth_to': auth_to, + } + + src_letpath = mw.getServerDir() + '/web_conf/letsencrypt/' + siteName + src_csrpath = src_letpath + "/fullchain.pem" # 生成证书路径 + src_keypath = src_letpath + "/privkey.pem" # 密钥文件路径 + + dst_letpath = mw.getRunDir() + '/' + siteName + dst_csrpath = dst_letpath + '/cert.pem' + dst_keypath = dst_letpath + '/private.pem' + + if not os.path.exists(src_letpath): + import cert_api + data = cert_api.cert_api().applyCertApi(to_args) + if not data['status']: + msg = data['msg'] + if type(data['msg']) != str: + msg = data['msg'][0] + emsg = data['msg'][1]['challenges'][0]['error'] + msg = msg + '

响应状态:' + str(emsg['status']) + '

错误类型:' + emsg[ + 'type'] + '

错误代码:' + emsg['detail'] + '

' + return mw.returnJson(data['status'], msg, data['msg']) + + mw.buildSoftLink(src_csrpath, dst_csrpath, True) + mw.buildSoftLink(src_keypath, dst_keypath, True) + mw.execShell('echo "lets" > "' + dst_letpath + '/README"') + + data = self.getPanelSslData() + + tmp_well_know = auth_to + '/.well-known' + if os.path.exists(tmp_well_know): + mw.execShell('rm -rf ' + tmp_well_know) + + return mw.returnJson(True, '申请成功!', data) + def setPanelDomainApi(self): domain = request.form.get('domain', '') diff --git a/route/__init__.py b/route/__init__.py index bb27fa938..7351204cb 100755 --- a/route/__init__.py +++ b/route/__init__.py @@ -223,9 +223,18 @@ def publicObject(toObject, func, action=None, get=None): # print(os) # return mw.getLocalIp() -# 仅针对webhook插件 +@app.route("/.well-known/acme-challenge/") +def wellknow(val=None): + # 申请面板ssl使用 + f = mw.getRunDir() + "/tmp/.well-known/acme-challenge/" + val + if os.path.exists(f): + return mw.readFile(f) + return '' + + @app.route("/hook") def webhook(): + # 仅针对webhook插件 input_args = { 'access_key': request.args.get('access_key', '').strip(), 'params': request.args.get('params', '').strip() diff --git a/route/static/app/config.js b/route/static/app/config.js index 47bf0c270..c9e66ed07 100755 --- a/route/static/app/config.js +++ b/route/static/app/config.js @@ -364,11 +364,11 @@ function getPanelSSL(){ var cert_data = ''; if (cert['info']){ cert_data = "
\ -
证书品牌:"+cert['info']['issuer']+"
\ -
到期时间:剩余"+cert['info']['endtime']+"天到期
\ +
证书品牌:"+cert['info']['issuer']+"
\ +
到期时间:剩余"+cert['info']['endtime']+"天到期
\
\
\ -
认证域名:"+cert['info']['subject']+"
\ +
认证域名:"+cert['info']['subject']+"
\
"; } @@ -404,19 +404,42 @@ function getPanelSSL(){ },'json'); } + //保存SSL + $('.save-panel-ssl').click(function(){ + var data = { + privateKey:$("#key").val(), + certPem:$("#csr").val() + } + var loadT = layer.msg('正在安装并设置SSL组件,这需要几分钟时间...',{icon:16,time:0,shade: [0.3, '#000']}); + $.post('/config/save_panel_ssl',data,function(rdata){ + layer.close(loadT); + if(rdata.status){ + layer.closeAll(); + } + layer.msg(rdata.msg,{icon:rdata.status?1:2}); + },'json'); + }); -function savePanelSSL(){ - var data = { - privateKey:$("#key").val(), - certPem:$("#csr").val() - } - var loadT = layer.msg('正在安装并设置SSL组件,这需要几分钟时间...',{icon:16,time:0,shade: [0.3, '#000']}); - $.post('/config/save_panel_ssl',data,function(rdata){ - layer.close(loadT); - if(rdata.status){ - layer.closeAll(); - } - layer.msg(rdata.msg,{icon:rdata.status?1:2}); + //申请Lets证书 + $('.apply-lets-ssl').click(function(){ + showSpeedWindow('正在申请...', 'site.get_let_logs', function(layers,index){ + $.post('/config/apply_panel_let_ssl',{},function(rdata){ + layer.close(loadT); + if(rdata.status){ + var tdata = rdata['data']; + $('.ssl_issue').text(tdata['info']['issuer']); + $('.ssl_endtime').text("剩余"+tdata['info']['endtime']+"天到期"); + $('.ssl_subject').text(tdata['info']['subject']); + + $('textarea[name="key"]').val(tdata['info']['privateKey']); + $('textarea[name="csr"]').val(tdata['info']['certPem']); + } + layer.msg(rdata.msg,{icon:rdata.status?1:2}); + },'json'); + }); + }); + } + }); },'json'); }