|
|
|
@ -28,7 +28,7 @@ from flask import request |
|
|
|
|
|
|
|
|
|
class config_api: |
|
|
|
|
|
|
|
|
|
__version = '0.16.9' |
|
|
|
|
__version = '0.17.0' |
|
|
|
|
__api_addr = 'data/api.json' |
|
|
|
|
|
|
|
|
|
# 统一默认配置文件 |
|
|
|
@ -42,7 +42,7 @@ class config_api: |
|
|
|
|
'bind_domain' : 'data/bind_domain.pl', # 面板域名绑定 |
|
|
|
|
'unauth_status' : 'data/unauthorized_status.pl', # URL路径未成功显示状态 |
|
|
|
|
'auth_secret': 'data/auth_secret.pl', # 二次验证密钥 |
|
|
|
|
'ssl':'data/ssl.pl', # ssl设置 |
|
|
|
|
'ssl':'ssl/choose.pl', # ssl设置 |
|
|
|
|
'hook_database' : 'data/hook_database.json', # 数据库钩子 |
|
|
|
|
'hook_menu' : 'data/hook_menu.json', # 菜单钩子 |
|
|
|
|
'hook_global_static' : 'data/hook_global_static.json', # 静态文件钩子 |
|
|
|
@ -362,19 +362,23 @@ class config_api: |
|
|
|
|
return mw.getJson(cert) |
|
|
|
|
|
|
|
|
|
def getPanelSslData(self): |
|
|
|
|
cert = {} |
|
|
|
|
keyPath = 'ssl/private.pem' |
|
|
|
|
certPath = 'ssl/cert.pem' |
|
|
|
|
rdata = {} |
|
|
|
|
choose_file = self.__file['ssl'] |
|
|
|
|
rdata['choose'] = mw.readFile(choose_file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
keyPath = 'ssl/local/private.pem' |
|
|
|
|
certPath = 'ssl/local/cert.pem' |
|
|
|
|
|
|
|
|
|
if not os.path.exists(certPath): |
|
|
|
|
# 不再自动生成证书 |
|
|
|
|
# mw.createSSL() |
|
|
|
|
cert['privateKey'] = '' |
|
|
|
|
cert['is_https'] = '' |
|
|
|
|
cert['certPem'] = '' |
|
|
|
|
cert['rep'] = os.path.exists('ssl/input.pl') |
|
|
|
|
cert['info'] = {'endtime': 0, 'subject': '无', |
|
|
|
|
'notAfter': '无', 'notBefore': '无', 'issuer': '无'} |
|
|
|
|
return cert |
|
|
|
|
mw.createLocalSSL() |
|
|
|
|
|
|
|
|
|
cert = {} |
|
|
|
|
cert['privateKey'] = mw.readFile(keyPath) |
|
|
|
|
cert['is_https'] = '' |
|
|
|
|
cert['certPem'] = mw.readFile(certPath) |
|
|
|
|
cert['info'] = mw.getCertName(certPath) |
|
|
|
|
rdata['local'] = cert |
|
|
|
|
|
|
|
|
|
panel_ssl = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf" |
|
|
|
|
if not os.path.exists(panel_ssl): |
|
|
|
@ -384,21 +388,68 @@ class config_api: |
|
|
|
|
if ssl_data.find('$server_port !~ 443') != -1: |
|
|
|
|
cert['is_https'] = 'checked' |
|
|
|
|
|
|
|
|
|
keyPath = 'ssl/nginx/private.pem' |
|
|
|
|
certPath = 'ssl/nginx/cert.pem' |
|
|
|
|
|
|
|
|
|
cert = {} |
|
|
|
|
cert['privateKey'] = mw.readFile(keyPath) |
|
|
|
|
cert['certPem'] = mw.readFile(certPath) |
|
|
|
|
cert['rep'] = os.path.exists('ssl/input.pl') |
|
|
|
|
cert['info'] = mw.getCertName(certPath) |
|
|
|
|
return cert |
|
|
|
|
|
|
|
|
|
rdata['nginx'] = cert |
|
|
|
|
|
|
|
|
|
return rdata |
|
|
|
|
|
|
|
|
|
# 面板本地SSL设置 |
|
|
|
|
def setPanelLocalSslApi(self): |
|
|
|
|
cert = {} |
|
|
|
|
keyPath = 'ssl/local/private.pem' |
|
|
|
|
certPath = 'ssl/local/cert.pem' |
|
|
|
|
|
|
|
|
|
if not os.path.exists(certPath): |
|
|
|
|
mw.createLocalSSL() |
|
|
|
|
|
|
|
|
|
choose_file = self.__file['ssl'] |
|
|
|
|
mw.writeFile(choose_file, 'local') |
|
|
|
|
|
|
|
|
|
mw.restartMw() |
|
|
|
|
return mw.returnJson(True, '设置成功') |
|
|
|
|
|
|
|
|
|
# 关闭SSL |
|
|
|
|
def closePanelSslApi(self): |
|
|
|
|
choose_file = self.__file['ssl'] |
|
|
|
|
if os.path.exists(choose_file): |
|
|
|
|
os.remove(choose_file) |
|
|
|
|
|
|
|
|
|
local_ssl = 'ssl/local' |
|
|
|
|
if os.path.exists(local_ssl): |
|
|
|
|
mw.execShell('rm -rf '+ local_ssl) |
|
|
|
|
|
|
|
|
|
nginx_ssl = 'ssl/nginx' |
|
|
|
|
if os.path.exists(nginx_ssl): |
|
|
|
|
mw.execShell('rm -rf '+ nginx_ssl) |
|
|
|
|
|
|
|
|
|
mw.restartMw() |
|
|
|
|
return mw.returnJson(True, '关闭SSL成功') |
|
|
|
|
|
|
|
|
|
# 保存面板证书 |
|
|
|
|
def savePanelSslApi(self): |
|
|
|
|
keyPath = 'ssl/private.pem' |
|
|
|
|
certPath = 'ssl/cert.pem' |
|
|
|
|
checkCert = '/tmp/cert.pl' |
|
|
|
|
|
|
|
|
|
choose = request.form.get('choose', '').strip() |
|
|
|
|
certPem = request.form.get('certPem', '').strip() |
|
|
|
|
privateKey = request.form.get('privateKey', '').strip() |
|
|
|
|
|
|
|
|
|
if not mw.inArray(['local','nginx'], choose): |
|
|
|
|
return mw.returnJson(True, '保存错误面板SSL类型!') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
keyPath = 'ssl/'+choose+'/private.pem' |
|
|
|
|
certPath = 'ssl/'+choose+'/cert.pem' |
|
|
|
|
checkCert = '/tmp/cert.pl' |
|
|
|
|
|
|
|
|
|
if not os.path.exists(keyPath): |
|
|
|
|
return mw.returnJson(False, '【'+choose+'】SSL类型不存在,先申请!') |
|
|
|
|
|
|
|
|
|
if(privateKey.find('KEY') == -1): |
|
|
|
|
return mw.returnJson(False, '秘钥错误,请检查!') |
|
|
|
|
if(certPem.find('CERTIFICATE') == -1): |
|
|
|
@ -411,258 +462,303 @@ class config_api: |
|
|
|
|
mw.writeFile(certPath, certPem) |
|
|
|
|
if not mw.checkCert(checkCert): |
|
|
|
|
return mw.returnJson(False, '证书错误,请检查!') |
|
|
|
|
mw.writeFile('ssl/input.pl', 'True') |
|
|
|
|
return mw.returnJson(True, '证书已保存!') |
|
|
|
|
|
|
|
|
|
# 设置面板SSL证书设置 |
|
|
|
|
def setPanelHttpToHttpsApi(self): |
|
|
|
|
|
|
|
|
|
bind_domain = self.__file['bind_domain'] |
|
|
|
|
if not os.path.exists(bind_domain): |
|
|
|
|
return mw.returnJson(False, '先要绑定域名!') |
|
|
|
|
|
|
|
|
|
keyPath = 'ssl/private.pem' |
|
|
|
|
if not os.path.exists(keyPath): |
|
|
|
|
return mw.returnJson(False, '未申请SSL证书!') |
|
|
|
|
|
|
|
|
|
is_https = request.form.get('https', '').strip() |
|
|
|
|
|
|
|
|
|
panel_ssl = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf" |
|
|
|
|
if not os.path.exists(panel_ssl): |
|
|
|
|
return mw.returnJson(False, '未开启面板SSL!') |
|
|
|
|
|
|
|
|
|
if is_https == 'false': |
|
|
|
|
conf = mw.readFile(panel_ssl) |
|
|
|
|
if conf: |
|
|
|
|
if conf.find('ssl_certificate') == -1: |
|
|
|
|
return mw.returnJson(False, '当前未开启SSL') |
|
|
|
|
to = "#error_page 404/404.html;\n\ |
|
|
|
|
#HTTP_TO_HTTPS_START\n\ |
|
|
|
|
if ($server_port !~ 443){\n\ |
|
|
|
|
rewrite ^(/.*)$ https://$host$1 permanent;\n\ |
|
|
|
|
}\n\ |
|
|
|
|
#HTTP_TO_HTTPS_END" |
|
|
|
|
conf = conf.replace('#error_page 404/404.html;', to) |
|
|
|
|
mw.writeFile(panel_ssl, conf) |
|
|
|
|
else: |
|
|
|
|
conf = mw.readFile(panel_ssl) |
|
|
|
|
if conf: |
|
|
|
|
rep = "\n\\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
mw.writeFile(panel_ssl, conf) |
|
|
|
|
|
|
|
|
|
mw.restartWeb() |
|
|
|
|
|
|
|
|
|
action = '开启' |
|
|
|
|
if is_https == 'true': |
|
|
|
|
action = '关闭' |
|
|
|
|
return mw.returnJson(True, action + 'HTTPS跳转成功!') |
|
|
|
|
# def setPanelHttpToHttpsApi(self): |
|
|
|
|
|
|
|
|
|
# bind_domain = self.__file['bind_domain'] |
|
|
|
|
# if not os.path.exists(bind_domain): |
|
|
|
|
# return mw.returnJson(False, '先要绑定域名!') |
|
|
|
|
|
|
|
|
|
# choose_file = self.__file['ssl'] |
|
|
|
|
# choose = mw.readFile(choose_file) |
|
|
|
|
# if choose == 'local': |
|
|
|
|
# return mw.returnJson(False, '本地SSL无法使用!') |
|
|
|
|
|
|
|
|
|
# keyPath = 'ssl/nginx/private.pem' |
|
|
|
|
# if not os.path.exists(keyPath): |
|
|
|
|
# return mw.returnJson(False, '未申请SSL证书!') |
|
|
|
|
|
|
|
|
|
# is_https = request.form.get('https', '').strip() |
|
|
|
|
|
|
|
|
|
# panel_ssl = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf" |
|
|
|
|
# if not os.path.exists(panel_ssl): |
|
|
|
|
# return mw.returnJson(False, '未开启面板SSL!') |
|
|
|
|
|
|
|
|
|
# if is_https == 'false': |
|
|
|
|
# conf = mw.readFile(panel_ssl) |
|
|
|
|
# if conf: |
|
|
|
|
# if conf.find('ssl_certificate') == -1: |
|
|
|
|
# return mw.returnJson(False, '当前未开启SSL') |
|
|
|
|
# to = "#error_page 404/404.html;\n\ |
|
|
|
|
# #HTTP_TO_HTTPS_START\n\ |
|
|
|
|
# if ($server_port !~ 443){\n\ |
|
|
|
|
# rewrite ^(/.*)$ https://$host$1 permanent;\n\ |
|
|
|
|
# }\n\ |
|
|
|
|
# #HTTP_TO_HTTPS_END" |
|
|
|
|
# conf = conf.replace('#error_page 404/404.html;', to) |
|
|
|
|
# mw.writeFile(panel_ssl, conf) |
|
|
|
|
# else: |
|
|
|
|
# conf = mw.readFile(panel_ssl) |
|
|
|
|
# if conf: |
|
|
|
|
# rep = "\n\\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# mw.writeFile(panel_ssl, conf) |
|
|
|
|
|
|
|
|
|
# mw.restartNginx() |
|
|
|
|
|
|
|
|
|
# action = '开启' |
|
|
|
|
# if is_https == 'true': |
|
|
|
|
# action = '关闭' |
|
|
|
|
# return mw.returnJson(True, action + 'HTTPS跳转成功!') |
|
|
|
|
|
|
|
|
|
# 删除面板证书 |
|
|
|
|
def delPanelSslApi(self): |
|
|
|
|
bind_domain = self.__file['bind_domain'] |
|
|
|
|
if not os.path.exists(bind_domain): |
|
|
|
|
return mw.returnJson(False, '未绑定域名!') |
|
|
|
|
ip = mw.getLocalIp() |
|
|
|
|
if mw.isAppleSystem(): |
|
|
|
|
ip = '127.0.0.1' |
|
|
|
|
|
|
|
|
|
siteName = mw.readFile(bind_domain).strip() |
|
|
|
|
port = mw.readFile('data/port.pl').strip() |
|
|
|
|
|
|
|
|
|
src_letpath = mw.getServerDir() + '/web_conf/letsencrypt/' + siteName |
|
|
|
|
choose = request.form.get('choose', '').strip() |
|
|
|
|
|
|
|
|
|
dst_letpath = mw.getRunDir() + '/ssl' |
|
|
|
|
dst_csrpath = dst_letpath + '/cert.pem' |
|
|
|
|
dst_keypath = dst_letpath + '/private.pem' |
|
|
|
|
if not mw.inArray(['local','nginx'], choose): |
|
|
|
|
return mw.returnJson(True, '删除错误面板SSL类型!') |
|
|
|
|
|
|
|
|
|
if os.path.exists(src_letpath) or os.path.exists(dst_csrpath): |
|
|
|
|
if os.path.exists(src_letpath): |
|
|
|
|
mw.execShell('rm -rf ' + src_letpath) |
|
|
|
|
if os.path.exists(dst_csrpath): |
|
|
|
|
mw.execShell('rm -rf ' + dst_csrpath) |
|
|
|
|
if os.path.exists(dst_keypath): |
|
|
|
|
mw.execShell('rm -rf ' + dst_keypath) |
|
|
|
|
# mw.restartWeb() |
|
|
|
|
return mw.returnJson(True, '已经删除SSL!') |
|
|
|
|
to_panel_url = 'http://'+ip+":"+port+'/config' |
|
|
|
|
|
|
|
|
|
# mw.restartWeb() |
|
|
|
|
return mw.returnJson(False, '已经不存在SSL!') |
|
|
|
|
if choose == 'local': |
|
|
|
|
dst_path = mw.getRunDir() + '/ssl/local' |
|
|
|
|
ssl_file = self.__file['ssl'] |
|
|
|
|
if os.path.exists(dst_path): |
|
|
|
|
mw.execShell('rm -rf ' + dst_path) |
|
|
|
|
mw.execShell('rm -rf ' + ssl_file) |
|
|
|
|
mw.restartMw(); |
|
|
|
|
return mw.returnJson(True, '删除本地面板SSL成功!',to_panel_url) |
|
|
|
|
else: |
|
|
|
|
return mw.returnJson(True, '已经删除本地面板SSL!',to_panel_url) |
|
|
|
|
|
|
|
|
|
# 申请面板let证书 |
|
|
|
|
def applyPanelLetSslApi(self): |
|
|
|
|
|
|
|
|
|
# check domain is bind? |
|
|
|
|
bind_domain = self.__file['bind_domain'] |
|
|
|
|
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, |
|
|
|
|
} |
|
|
|
|
if choose == 'nginx': |
|
|
|
|
|
|
|
|
|
src_letpath = mw.getServerDir() + '/web_conf/letsencrypt/' + siteName |
|
|
|
|
src_csrpath = src_letpath + "/fullchain.pem" # 生成证书路径 |
|
|
|
|
src_keypath = src_letpath + "/privkey.pem" # 密钥文件路径 |
|
|
|
|
|
|
|
|
|
dst_letpath = mw.getRunDir() + '/ssl' |
|
|
|
|
dst_csrpath = dst_letpath + '/cert.pem' |
|
|
|
|
dst_keypath = dst_letpath + '/private.pem' |
|
|
|
|
|
|
|
|
|
is_already_apply = False |
|
|
|
|
|
|
|
|
|
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 + '<p><span>响应状态:</span>' + str(emsg['status']) + '</p><p><span>错误类型:</span>' + emsg[ |
|
|
|
|
'type'] + '</p><p><span>错误代码:</span>' + emsg['detail'] + '</p>' |
|
|
|
|
return mw.returnJson(data['status'], msg, data['msg']) |
|
|
|
|
else: |
|
|
|
|
is_already_apply = True |
|
|
|
|
bind_domain = self.__file['bind_domain'] |
|
|
|
|
if not os.path.exists(bind_domain): |
|
|
|
|
return mw.returnJson(False, '未绑定域名!') |
|
|
|
|
|
|
|
|
|
mw.buildSoftLink(src_csrpath, dst_csrpath, True) |
|
|
|
|
mw.buildSoftLink(src_keypath, dst_keypath, True) |
|
|
|
|
mw.execShell('echo "lets" > "' + dst_letpath + '/README"') |
|
|
|
|
siteName = mw.readFile(bind_domain).strip() |
|
|
|
|
|
|
|
|
|
data = self.getPanelSslData() |
|
|
|
|
src_path = mw.getServerDir() + '/web_conf/letsencrypt/' + siteName |
|
|
|
|
|
|
|
|
|
tmp_well_know = auth_to + '/.well-known' |
|
|
|
|
if os.path.exists(tmp_well_know): |
|
|
|
|
mw.execShell('rm -rf ' + tmp_well_know) |
|
|
|
|
dst_path = mw.getRunDir() + '/ssl/nginx' |
|
|
|
|
dst_csrpath = dst_path + '/cert.pem' |
|
|
|
|
dst_keypath = dst_path + '/private.pem' |
|
|
|
|
|
|
|
|
|
if is_already_apply: |
|
|
|
|
return mw.returnJson(True, '重复申请!', data) |
|
|
|
|
if os.path.exists(src_path) or os.path.exists(dst_path): |
|
|
|
|
if os.path.exists(src_letpath): |
|
|
|
|
mw.execShell('rm -rf ' + src_letpath) |
|
|
|
|
if os.path.exists(dst_csrpath): |
|
|
|
|
mw.execShell('rm -rf ' + dst_csrpath) |
|
|
|
|
if os.path.exists(dst_keypath): |
|
|
|
|
mw.execShell('rm -rf ' + dst_keypath) |
|
|
|
|
mw.restartNginx() |
|
|
|
|
return mw.returnJson(True, '删除面板SSL成功!') |
|
|
|
|
|
|
|
|
|
return mw.returnJson(True, '申请成功!', data) |
|
|
|
|
mw.restartNginx() |
|
|
|
|
mw.restartMw() |
|
|
|
|
return mw.returnJson(False, '已经删除面板SSL!') |
|
|
|
|
return mw.returnJson(False, '未知类型!') |
|
|
|
|
|
|
|
|
|
# 申请面板let证书 |
|
|
|
|
# def applyPanelAcmeSslApi(self): |
|
|
|
|
|
|
|
|
|
# bind_domain = self.__file['bind_domain'] |
|
|
|
|
# if not os.path.exists(bind_domain): |
|
|
|
|
# return mw.returnJson(False, '先要绑定域名!') |
|
|
|
|
|
|
|
|
|
# # 生成nginx配置 |
|
|
|
|
# domain = mw.readFile(bind_domain) |
|
|
|
|
# panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf" |
|
|
|
|
# dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf" |
|
|
|
|
# if not os.path.exists(dst_panel_path): |
|
|
|
|
# reg = r"^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$" |
|
|
|
|
# if not re.match(reg, domain): |
|
|
|
|
# return mw.returnJson(False, '主域名格式不正确') |
|
|
|
|
|
|
|
|
|
# op_dir = mw.getServerDir() + "/openresty" |
|
|
|
|
# if not os.path.exists(op_dir): |
|
|
|
|
# return mw.returnJson(False, '依赖OpenResty,先安装启动它!') |
|
|
|
|
|
|
|
|
|
# content = mw.readFile(panel_tpl) |
|
|
|
|
# content = content.replace("{$PORT}", "80") |
|
|
|
|
# content = content.replace("{$SERVER_NAME}", domain) |
|
|
|
|
# content = content.replace("{$PANAL_PORT}", mw.readFile('data/port.pl')) |
|
|
|
|
# content = content.replace("{$LOGPATH}", mw.getRunDir() + '/logs') |
|
|
|
|
# content = content.replace("{$PANAL_ADDR}", mw.getRunDir()) |
|
|
|
|
# mw.writeFile(dst_panel_path, content) |
|
|
|
|
# mw.restartNginx() |
|
|
|
|
|
|
|
|
|
# siteName = mw.readFile(bind_domain).strip() |
|
|
|
|
# auth_to = mw.getRunDir() + "/tmp" |
|
|
|
|
# to_args = { |
|
|
|
|
# 'domains': [siteName], |
|
|
|
|
# 'auth_type': 'http', |
|
|
|
|
# 'auth_to': auth_to, |
|
|
|
|
# } |
|
|
|
|
|
|
|
|
|
# src_path = mw.getServerDir() + '/web_conf/letsencrypt/' + siteName |
|
|
|
|
# src_csrpath = src_path + "/fullchain.pem" # 生成证书路径 |
|
|
|
|
# src_keypath = src_path + "/privkey.pem" # 密钥文件路径 |
|
|
|
|
|
|
|
|
|
# dst_path = mw.getRunDir() + '/ssl/nginx' |
|
|
|
|
# dst_csrpath = dst_path + '/cert.pem' |
|
|
|
|
# dst_keypath = dst_path + '/private.pem' |
|
|
|
|
|
|
|
|
|
# is_already_apply = False |
|
|
|
|
|
|
|
|
|
# if not os.path.exists(src_path): |
|
|
|
|
# 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 + '<p><span>响应状态:</span>' + str(emsg['status']) + '</p><p><span>错误类型:</span>' + emsg[ |
|
|
|
|
# 'type'] + '</p><p><span>错误代码:</span>' + emsg['detail'] + '</p>' |
|
|
|
|
# return mw.returnJson(data['status'], msg, data['msg']) |
|
|
|
|
# else: |
|
|
|
|
# is_already_apply = True |
|
|
|
|
|
|
|
|
|
# mw.buildSoftLink(src_csrpath, dst_csrpath, True) |
|
|
|
|
# mw.buildSoftLink(src_keypath, dst_keypath, True) |
|
|
|
|
# mw.execShell('echo "acme" > "' + dst_path + '/README"') |
|
|
|
|
|
|
|
|
|
# tmp_well_know = auth_to + '/.well-known' |
|
|
|
|
# if os.path.exists(tmp_well_know): |
|
|
|
|
# mw.execShell('rm -rf ' + tmp_well_know) |
|
|
|
|
|
|
|
|
|
# if os.path.exists(dst_path): |
|
|
|
|
# choose_file = self.__file['ssl'] |
|
|
|
|
# mw.writeFile(choose_file, 'nginx') |
|
|
|
|
|
|
|
|
|
# data = self.getPanelSslData() |
|
|
|
|
|
|
|
|
|
# if is_already_apply: |
|
|
|
|
# return mw.returnJson(True, '重复申请!', data) |
|
|
|
|
# return mw.returnJson(True, '申请成功!', data) |
|
|
|
|
|
|
|
|
|
def setPanelDomainApi(self): |
|
|
|
|
domain = request.form.get('domain', '') |
|
|
|
|
|
|
|
|
|
panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf" |
|
|
|
|
dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf" |
|
|
|
|
|
|
|
|
|
cfg_domain = self.__file['bind_domain'] |
|
|
|
|
|
|
|
|
|
port = mw.readFile('data/port.pl').strip() |
|
|
|
|
ip = mw.getLocalIp() |
|
|
|
|
|
|
|
|
|
if domain == '': |
|
|
|
|
os.remove(cfg_domain) |
|
|
|
|
os.remove(dst_panel_path) |
|
|
|
|
mw.restartWeb() |
|
|
|
|
return mw.returnJson(True, '清空域名成功!') |
|
|
|
|
|
|
|
|
|
reg = r"^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$" |
|
|
|
|
if not re.match(reg, domain): |
|
|
|
|
return mw.returnJson(False, '主域名格式不正确') |
|
|
|
|
|
|
|
|
|
op_dir = mw.getServerDir() + "/openresty" |
|
|
|
|
if not os.path.exists(op_dir): |
|
|
|
|
return mw.returnJson(False, '依赖OpenResty,先安装启动它!') |
|
|
|
|
|
|
|
|
|
content = mw.readFile(panel_tpl) |
|
|
|
|
content = content.replace("{$PORT}", "80") |
|
|
|
|
content = content.replace("{$SERVER_NAME}", domain) |
|
|
|
|
content = content.replace("{$PANAL_PORT}", mw.readFile('data/port.pl')) |
|
|
|
|
content = content.replace("{$LOGPATH}", mw.getRunDir() + '/logs') |
|
|
|
|
content = content.replace("{$PANAL_ADDR}", mw.getRunDir()) |
|
|
|
|
mw.writeFile(dst_panel_path, content) |
|
|
|
|
mw.restartWeb() |
|
|
|
|
if os.path.exists(cfg_domain): |
|
|
|
|
os.remove(cfg_domain) |
|
|
|
|
|
|
|
|
|
to_panel_url = 'http://'+ip+":"+port+'/config' |
|
|
|
|
|
|
|
|
|
mw.restartMw() |
|
|
|
|
return mw.returnJson(True, '清空域名成功!', to_panel_url) |
|
|
|
|
|
|
|
|
|
mw.writeFile(cfg_domain, domain) |
|
|
|
|
return mw.returnJson(True, '设置域名成功!') |
|
|
|
|
to_panel_url = 'http://'+domain+":"+port+'/config' |
|
|
|
|
mw.restartMw() |
|
|
|
|
return mw.returnJson(True, '设置域名成功!',to_panel_url) |
|
|
|
|
|
|
|
|
|
# 设置面板SSL |
|
|
|
|
def setPanelSslApi(self): |
|
|
|
|
sslConf = mw.getRunDir() + '/' + self.__file['ssl'] |
|
|
|
|
|
|
|
|
|
panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf" |
|
|
|
|
dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf" |
|
|
|
|
if os.path.exists(sslConf): |
|
|
|
|
os.system('rm -f ' + sslConf) |
|
|
|
|
|
|
|
|
|
conf = mw.readFile(dst_panel_path) |
|
|
|
|
if conf: |
|
|
|
|
rep = "\\s+ssl_certificate\\s+.+;\\s+ssl_certificate_key\\s+.+;" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_protocols\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_ciphers\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_prefer_server_ciphers\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_session_cache\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_session_timeout\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_ecdh_curve\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_session_tickets\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_stapling\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl_stapling_verify\\s+.+;\n" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+ssl\\s+on;" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+error_page\\s497.+;" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+listen\\s+443.*;" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
rep = "\\s+listen\\s+\\[\\:\\:\\]\\:443.*;" |
|
|
|
|
conf = re.sub(rep, '', conf) |
|
|
|
|
mw.writeFile(dst_panel_path, conf) |
|
|
|
|
|
|
|
|
|
mw.writeLog('面板配置', '面板SSL关闭成功!') |
|
|
|
|
mw.restartWeb() |
|
|
|
|
return mw.returnJson(True, 'SSL已关闭,请使用http协议访问面板!') |
|
|
|
|
else: |
|
|
|
|
try: |
|
|
|
|
mw.writeFile(sslConf, 'True') |
|
|
|
|
|
|
|
|
|
keyPath = mw.getRunDir() + '/ssl/private.pem' |
|
|
|
|
certPath = mw.getRunDir() + '/ssl/cert.pem' |
|
|
|
|
|
|
|
|
|
conf = mw.readFile(dst_panel_path) |
|
|
|
|
if conf: |
|
|
|
|
if conf.find('ssl_certificate') == -1: |
|
|
|
|
sslStr = """#error_page 404/404.html; |
|
|
|
|
ssl_certificate %s; |
|
|
|
|
ssl_certificate_key %s; |
|
|
|
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; |
|
|
|
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; |
|
|
|
|
ssl_prefer_server_ciphers on; |
|
|
|
|
ssl_session_cache shared:SSL:10m; |
|
|
|
|
ssl_session_timeout 10m; |
|
|
|
|
error_page 497 https://$host$request_uri;""" % (certPath, keyPath) |
|
|
|
|
if(conf.find('ssl_certificate') != -1): |
|
|
|
|
return mw.returnJson(True, 'SSL开启成功!') |
|
|
|
|
|
|
|
|
|
conf = conf.replace('#error_page 404/404.html;', sslStr) |
|
|
|
|
|
|
|
|
|
rep = "listen\\s+([0-9]+)\\s*[default_server]*;" |
|
|
|
|
tmp = re.findall(rep, conf) |
|
|
|
|
if not mw.inArray(tmp, '443'): |
|
|
|
|
listen = re.search(rep, conf).group() |
|
|
|
|
http_ssl = "\n\tlisten 443 ssl http2;" |
|
|
|
|
http_ssl = http_ssl + "\n\tlisten [::]:443 ssl http2;" |
|
|
|
|
conf = conf.replace(listen, listen + http_ssl) |
|
|
|
|
|
|
|
|
|
mw.backFile(dst_panel_path) |
|
|
|
|
mw.writeFile(dst_panel_path, conf) |
|
|
|
|
isError = mw.checkWebConfig() |
|
|
|
|
if(isError != True): |
|
|
|
|
mw.restoreFile(dst_panel_path) |
|
|
|
|
return mw.returnJson(False, '证书错误: <br><a style="color:red;">' + isError.replace("\n", '<br>') + '</a>') |
|
|
|
|
except Exception as ex: |
|
|
|
|
return mw.returnJson(False, '开启失败:' + str(ex)) |
|
|
|
|
mw.restartWeb() |
|
|
|
|
return mw.returnJson(True, '开启成功,请使用https协议访问面板!') |
|
|
|
|
# def setPanelSslApi(self): |
|
|
|
|
# sslConf = mw.getRunDir() + '/' + self.__file['ssl'] |
|
|
|
|
|
|
|
|
|
# panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf" |
|
|
|
|
# dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf" |
|
|
|
|
# if os.path.exists(sslConf): |
|
|
|
|
# os.system('rm -f ' + sslConf) |
|
|
|
|
|
|
|
|
|
# conf = mw.readFile(dst_panel_path) |
|
|
|
|
# if conf: |
|
|
|
|
# rep = "\\s+ssl_certificate\\s+.+;\\s+ssl_certificate_key\\s+.+;" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_protocols\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_ciphers\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_prefer_server_ciphers\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_session_cache\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_session_timeout\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_ecdh_curve\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_session_tickets\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_stapling\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl_stapling_verify\\s+.+;\n" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+ssl\\s+on;" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+error_page\\s497.+;" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+listen\\s+443.*;" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# rep = "\\s+listen\\s+\\[\\:\\:\\]\\:443.*;" |
|
|
|
|
# conf = re.sub(rep, '', conf) |
|
|
|
|
# mw.writeFile(dst_panel_path, conf) |
|
|
|
|
|
|
|
|
|
# mw.writeLog('面板配置', '面板SSL关闭成功!') |
|
|
|
|
# mw.restartWeb() |
|
|
|
|
# return mw.returnJson(True, 'SSL已关闭,请使用http协议访问面板!') |
|
|
|
|
# else: |
|
|
|
|
# try: |
|
|
|
|
# mw.writeFile(sslConf, 'True') |
|
|
|
|
|
|
|
|
|
# keyPath = mw.getRunDir() + '/ssl/private.pem' |
|
|
|
|
# certPath = mw.getRunDir() + '/ssl/cert.pem' |
|
|
|
|
|
|
|
|
|
# conf = mw.readFile(dst_panel_path) |
|
|
|
|
# if conf: |
|
|
|
|
# if conf.find('ssl_certificate') == -1: |
|
|
|
|
# sslStr = """#error_page 404/404.html; |
|
|
|
|
# ssl_certificate %s; |
|
|
|
|
# ssl_certificate_key %s; |
|
|
|
|
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; |
|
|
|
|
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; |
|
|
|
|
# ssl_prefer_server_ciphers on; |
|
|
|
|
# ssl_session_cache shared:SSL:10m; |
|
|
|
|
# ssl_session_timeout 10m; |
|
|
|
|
# error_page 497 https://$host$request_uri;""" % (certPath, keyPath) |
|
|
|
|
# if(conf.find('ssl_certificate') != -1): |
|
|
|
|
# return mw.returnJson(True, 'SSL开启成功!') |
|
|
|
|
|
|
|
|
|
# conf = conf.replace('#error_page 404/404.html;', sslStr) |
|
|
|
|
|
|
|
|
|
# rep = "listen\\s+([0-9]+)\\s*[default_server]*;" |
|
|
|
|
# tmp = re.findall(rep, conf) |
|
|
|
|
# if not mw.inArray(tmp, '443'): |
|
|
|
|
# listen = re.search(rep, conf).group() |
|
|
|
|
# http_ssl = "\n\tlisten 443 ssl http2;" |
|
|
|
|
# http_ssl = http_ssl + "\n\tlisten [::]:443 ssl http2;" |
|
|
|
|
# conf = conf.replace(listen, listen + http_ssl) |
|
|
|
|
|
|
|
|
|
# mw.backFile(dst_panel_path) |
|
|
|
|
# mw.writeFile(dst_panel_path, conf) |
|
|
|
|
# isError = mw.checkWebConfig() |
|
|
|
|
# if(isError != True): |
|
|
|
|
# mw.restoreFile(dst_panel_path) |
|
|
|
|
# return mw.returnJson(False, '证书错误: <br><a style="color:red;">' + isError.replace("\n", '<br>') + '</a>') |
|
|
|
|
# except Exception as ex: |
|
|
|
|
# return mw.returnJson(False, '开启失败:' + str(ex)) |
|
|
|
|
# mw.restartWeb() |
|
|
|
|
# return mw.returnJson(True, '开启成功,请使用https协议访问面板!') |
|
|
|
|
|
|
|
|
|
def getApi(self): |
|
|
|
|
data = {} |
|
|
|
@ -958,7 +1054,7 @@ class config_api: |
|
|
|
|
mw.writeFile(auth, crypt_data) |
|
|
|
|
|
|
|
|
|
ip = mw.getHostAddr() |
|
|
|
|
url = pyotp.totp.TOTP(sec).provisioning_uri(name=ip, issuer_name='mdserver-web') |
|
|
|
|
url = pyotp.totp.TOTP(sec).provisioning_uri(name=ip, issuer_name=tag) |
|
|
|
|
|
|
|
|
|
rdata = {} |
|
|
|
|
rdata['secret'] = sec |
|
|
|
|