panel ssl 测试中

pull/291/head
midoks 2 years ago
parent d3e7684f04
commit 3b459e0349
  1. 1
      .gitignore
  2. 39
      class/core/config_api.py
  3. 94
      class/core/mw.py
  4. 69
      class/core/site_api.py
  5. 28
      data/tpl/nginx_panel.conf
  6. 24
      route/static/app/config.js
  7. 6
      route/templates/default/config.html

1
.gitignore vendored

@ -106,6 +106,7 @@ venv.bak/
.idea/*.iml
tmp/*
*.swp
*.pem
*.zip
logs/*
data/*.db

@ -354,9 +354,14 @@ class config_api:
# 获取面板证书
def getPanelSslApi(self):
cert = {}
if not os.path.exists('ssl/certificate.pem'):
mw.createSSL()
cert['privateKey'] = mw.readFile('ssl/privateKey.pem')
cert['certPem'] = mw.readFile('ssl/certificate.pem')
cert['rep'] = os.path.exists('ssl/input.pl')
cert['info'] = mw.getCertName('ssl/certificate.pem')
return mw.getJson(cert)
# 保存面板证书
@ -385,11 +390,11 @@ class config_api:
os.system('rm -f ' + sslConf)
return mw.returnJson(True, 'SSL已关闭,请使用http协议访问面板!')
else:
os.system('pip install cffi==1.10')
os.system('pip install cryptography==2.1')
os.system('pip install pyOpenSSL==16.2')
# os.system('pip install cffi==1.10')
# os.system('pip install cryptography==2.1')
# os.system('pip install pyOpenSSL==16.2')
try:
if not self.createSSL():
if not mw.createSSL():
return mw.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!<p>请尝试手动安装: pip install pyOpenSSL</p>')
mw.writeFile(sslConf, 'True')
except Exception as ex:
@ -401,32 +406,6 @@ class config_api:
return mw.getJson(data)
##### ----- end ----- ###
# 自签证书
def createSSL(self):
if os.path.exists('ssl/input.pl'):
return True
import OpenSSL
key = OpenSSL.crypto.PKey()
key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
cert = OpenSSL.crypto.X509()
cert.set_serial_number(0)
cert.get_subject().CN = mw.getLocalIp()
cert.set_issuer(cert.get_subject())
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(86400 * 3650)
cert.set_pubkey(key)
cert.sign(key, 'md5')
cert_ca = OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, cert)
private_key = OpenSSL.crypto.dump_privatekey(
OpenSSL.crypto.FILETYPE_PEM, key)
if len(cert_ca) > 100 and len(private_key) > 100:
mw.writeFile('ssl/certificate.pem', cert_ca)
mw.writeFile('ssl/privateKey.pem', private_key)
print(cert_ca, private_key)
return True
return False
# 获取临时登录列表
def getTempLoginApi(self):
if 'tmp_login_expire' in session:

@ -1282,6 +1282,100 @@ def get_string_arr(t):
t_arr.append(str(i) + str(j))
return t_arr
# 转换时间
def strfDate(sdate):
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%Y%m%d%H%M%S'))
# 获取证书名称
def getCertName(certPath):
if not os.path.exists(certPath):
return None
try:
import OpenSSL
result = {}
x509 = OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM, readFile(certPath))
# 取产品名称
issuer = x509.get_issuer()
result['issuer'] = ''
if hasattr(issuer, 'CN'):
result['issuer'] = issuer.CN
if not result['issuer']:
is_key = [b'0', '0']
issue_comp = issuer.get_components()
if len(issue_comp) == 1:
is_key = [b'CN', 'CN']
for iss in issue_comp:
if iss[0] in is_key:
result['issuer'] = iss[1].decode()
break
if not result['issuer']:
if hasattr(issuer, 'O'):
result['issuer'] = issuer.O
# 取到期时间
result['notAfter'] = strfDate(
bytes.decode(x509.get_notAfter())[:-1])
# 取申请时间
result['notBefore'] = strfDate(
bytes.decode(x509.get_notBefore())[:-1])
# 取可选名称
result['dns'] = []
for i in range(x509.get_extension_count()):
s_name = x509.get_extension(i)
if s_name.get_short_name() in [b'subjectAltName', 'subjectAltName']:
s_dns = str(s_name).split(',')
for d in s_dns:
result['dns'].append(d.split(':')[1])
subject = x509.get_subject().get_components()
# 取主要认证名称
if len(subject) == 1:
result['subject'] = subject[0][1].decode()
else:
if not result['dns']:
for sub in subject:
if sub[0] == b'CN':
result['subject'] = sub[1].decode()
break
if 'subject' in result:
result['dns'].append(result['subject'])
else:
result['subject'] = result['dns'][0]
result['endtime'] = int(int(time.mktime(time.strptime(
result['notAfter'], "%Y-%m-%d")) - time.time()) / 86400)
return result
except Exception as e:
# print(getTracebackInfo())
return None
def createSSL():
# 自签证书
if os.path.exists('ssl/input.pl'):
return True
import OpenSSL
key = OpenSSL.crypto.PKey()
key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
cert = OpenSSL.crypto.X509()
cert.set_serial_number(0)
cert.get_subject().CN = getLocalIp()
cert.set_issuer(cert.get_subject())
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(86400 * 3650)
cert.set_pubkey(key)
cert.sign(key, 'md5')
cert_ca = OpenSSL.crypto.dump_certificate(
OpenSSL.crypto.FILETYPE_PEM, cert)
private_key = OpenSSL.crypto.dump_privatekey(
OpenSSL.crypto.FILETYPE_PEM, key)
if len(cert_ca) > 100 and len(private_key) > 100:
writeFile('ssl/certificate.pem', cert_ca, 'wb+')
writeFile('ssl/privateKey.pem', private_key, 'wb+')
return True
return False
def getSSHPort():
try:

@ -589,7 +589,7 @@ class site_api:
key = mw.readFile(key_path)
csr = mw.readFile(csr_path)
cert_data = self.getCertName(csr_path)
cert_data = mw.getCertName(csr_path)
data = {
'status': status,
'domain': domains,
@ -2582,7 +2582,6 @@ location ^~ {from} {\n\
conf = conf.replace(listen, listen + http_ssl)
mw.backFile(file)
mw.writeFile(file, conf)
isError = mw.checkWebConfig()
if(isError != True):
@ -2599,7 +2598,7 @@ location ^~ {from} {\n\
def saveCert(self, keyPath, certPath):
try:
certInfo = self.getCertName(certPath)
certInfo = mw.getCertName(certPath)
if not certInfo:
return mw.returnData(False, '证书解析失败!')
vpath = self.sslDir + '/' + certInfo['subject'].strip()
@ -2612,70 +2611,6 @@ location ^~ {from} {\n\
except Exception as e:
return mw.returnData(False, '证书保存失败!')
# 转换时间
def strfDate(self, sdate):
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%Y%m%d%H%M%S'))
# 获取证书名称
def getCertName(self, certPath):
if not os.path.exists(certPath):
return None
try:
import OpenSSL
result = {}
x509 = OpenSSL.crypto.load_certificate(
OpenSSL.crypto.FILETYPE_PEM, mw.readFile(certPath))
# 取产品名称
issuer = x509.get_issuer()
result['issuer'] = ''
if hasattr(issuer, 'CN'):
result['issuer'] = issuer.CN
if not result['issuer']:
is_key = [b'0', '0']
issue_comp = issuer.get_components()
if len(issue_comp) == 1:
is_key = [b'CN', 'CN']
for iss in issue_comp:
if iss[0] in is_key:
result['issuer'] = iss[1].decode()
break
if not result['issuer']:
if hasattr(issuer, 'O'):
result['issuer'] = issuer.O
# 取到期时间
result['notAfter'] = self.strfDate(
bytes.decode(x509.get_notAfter())[:-1])
# 取申请时间
result['notBefore'] = self.strfDate(
bytes.decode(x509.get_notBefore())[:-1])
# 取可选名称
result['dns'] = []
for i in range(x509.get_extension_count()):
s_name = x509.get_extension(i)
if s_name.get_short_name() in [b'subjectAltName', 'subjectAltName']:
s_dns = str(s_name).split(',')
for d in s_dns:
result['dns'].append(d.split(':')[1])
subject = x509.get_subject().get_components()
# 取主要认证名称
if len(subject) == 1:
result['subject'] = subject[0][1].decode()
else:
if not result['dns']:
for sub in subject:
if sub[0] == b'CN':
result['subject'] = sub[1].decode()
break
if 'subject' in result:
result['dns'].append(result['subject'])
else:
result['subject'] = result['dns'][0]
result['endtime'] = int(int(time.mktime(time.strptime(
result['notAfter'], "%Y-%m-%d")) - time.time()) / 86400)
return result
except:
return None
# 清除多余user.ini
def delUserInI(self, path, up=0):
for p1 in os.listdir(path):

@ -0,0 +1,28 @@
server
{
listen {$PORT};
listen [::]:{$PORT};
server_name {$SERVER_NAME};
index index.php index.html index.htm default.php default.htm default.html;
root {$ROOT_DIR};
#SSL-START
#error_page 404/404.html;
#SSL-END
#禁止访问的文件或目录
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
access_log {$LOGPATH}/{$SERVER_NAME}.log main;
error_log {$LOGPATH}/{$SERVER_NAME}.error.log;
}

@ -68,7 +68,6 @@ $('input[name="backup_path"]').change(function(){
$('input[name="bind_domain"]').change(function(){
var domain = $(this).val();
console.log(domain);
$('.btn_bind_domain').removeAttr('disabled');
$('.btn_bind_domain').unbind().click(function(){
$.post('/config/set_panel_domain','domain='+domain, function(rdata){
@ -77,6 +76,13 @@ $('input[name="bind_domain"]').change(function(){
});
});
$('input[name="bind_ssl"]').click(function(){
var open_ssl = $(this).prop("checked");
$.post('/config/set_panel_ssl',{}, function(rdata){
showMsg(rdata.msg,function(){window.location.reload();},{icon:rdata.status?1:2},2000);
},'json');
});
/** op **/
@ -353,14 +359,30 @@ function getPanelSSL(){
var loadT = layer.msg('正在获取证书信息...',{icon:16,time:0,shade: [0.3, '#000']});
$.post('/config/get_panel_ssl',{},function(cert){
layer.close(loadT);
var cert_data = '';
if (cert['info']){
cert_data = "<div class='ssl_state_info'><div class='state_info_flex'>\
<div class='state_item'><span>证书品牌</span><span class='ellipsis_text'>"+cert['info']['issuer']+"</span></div>\
<div class='state_item'><span>到期时间</span><span class='btlink'>"+cert['info']['endtime']+"</span></div>\
</div>\
<div class='state_info_flex'>\
<div class='state_item'><span>认证域名</span><span class='ellipsis_text'>"+cert['info']['subject']+"</span></div>\
</div></div>";
}
var certBody = '<div class="tab-con">\
<div class="myKeyCon ptb15">\
'+cert_data+'\
<div class="custom_certificate_info">\
<div class="ssl-con-key pull-left mr20">密钥(KEY)<br>\
<textarea id="key" class="bt-input-text">'+cert.privateKey+'</textarea>\
</div>\
<div class="ssl-con-key pull-left">证书(PEM格式)<br>\
<textarea id="csr" class="bt-input-text">'+cert.certPem+'</textarea>\
</div>\
</div>\
<div class="ssl-btn pull-left mtb15" style="width:100%">\
<button class="btn btn-success btn-sm" onclick="savePanelSSL()">保存</button>\
</div>\

@ -121,13 +121,13 @@
<span class="set-info c7">为面板绑定一个访问域名,<b style="color: red;">注意:一旦绑定域名,只能通过域名访问面板</b></span>
</p>
<!-- <p class="mtb15">
<p class="mtb15">
<span class="set-tit text-right" title="面板SSL" style="float: left;">面板SSL</span>
<input id="cfg_ssl" name="bind_ssl" class="btswitch btswitch-ios" type="checkbox" {{data['ssl']}}>
<label class="btswitch-btn ml5" for="cfg_ssl" style="float: left;margin-top:4px;" onclick="getPanelSSL()"></label>
<label class="btswitch-btn ml5" for="cfg_ssl" style="float: left;margin-top:4px;"></label>
<button ype="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="getPanelSSL();">面板SSL配置</button>
<span class="set-info c7">为面板设置https协议访问,提升面板访问<b style="color: red;">安全性</b></span>
</p> -->
</p>
<p class="mtb15">
<span class="set-tit text-right" title="BasicAuth认证" style="float: left;">BasicAuth认证</span>

Loading…
Cancel
Save