Compare commits

...
42 Commits
Author SHA1 Message Date
Mr Chen d917fa76f6 Merge pull request #286 from midoks/dev
0.11.3
2022-12-08 00:07:48 +08:00
midoks 32971ccead 0.11.3 2022-12-08 00:06:50 +08:00
midoks c7a3481b95 #285
观察细致入微。
2022-12-07 22:56:18 +08:00
midoks 8915b672e5 Update config_api.py 2022-12-07 19:35:35 +08:00
midoks e472d104d1 Update nginx_panel.conf 2022-12-07 16:33:44 +08:00
midoks 48ee5574c7 Update mw.py 2022-12-07 15:31:47 +08:00
midoks 706afbd681 Update mw.py 2022-12-07 15:31:32 +08:00
midoks 70ca6d0459 Update mw.py 2022-12-07 15:12:18 +08:00
midoks f344a32fa7 Update mw.py 2022-12-07 15:09:43 +08:00
midoks e6123000ac Update nginx_panel.conf 2022-12-07 12:56:30 +08:00
midoks b94361c59f Update config_api.py 2022-12-07 00:37:28 +08:00
midoks 4a7efb67d4 Update config_api.py 2022-12-07 00:22:02 +08:00
midoks 536b7ac997 Update config_api.py 2022-12-07 00:20:31 +08:00
midoks 0f5b055aeb 面板ssl 2022-12-07 00:14:22 +08:00
midoks 7d81a59c8f Update config_api.py 2022-12-06 23:42:23 +08:00
midoks 2540cd1308 Update config_api.py 2022-12-06 23:40:41 +08:00
midoks 5358cd2d38 up 2022-12-06 23:38:09 +08:00
midoks c4bb20ed54 Update files_api.py 2022-12-06 20:37:07 +08:00
midoks 7f2f307131 Update files_api.py 2022-12-06 20:30:02 +08:00
midoks 7a8ef9fe00 Update files_api.py 2022-12-06 20:19:06 +08:00
midoks e1abc66179 Update setting.py 2022-12-06 18:00:28 +08:00
midoks 8bda20c3d0 Update config_api.py 2022-12-06 17:50:49 +08:00
midoks 3c01838df1 Update .gitignore 2022-12-06 17:38:42 +08:00
midoks 3b459e0349 panel ssl 测试中 2022-12-06 17:35:23 +08:00
midoks d3e7684f04 ssl update 2022-12-06 16:27:24 +08:00
midoks b2e6e7f256 Update firewall_api.py 2022-12-06 01:25:53 +08:00
midoks ca6812561a Update mw.py 2022-12-06 01:03:25 +08:00
midoks 44e8079db6 Update README.md 2022-12-05 15:08:39 +08:00
midoks 9bd063cc1d Update phalcon.sh 2022-12-04 16:10:26 +08:00
midoks 1b0044e28a Update index.py 2022-12-04 15:58:04 +08:00
midoks 9b752cf24f up 2022-12-04 15:57:33 +08:00
midoks cf5f98958c Update phplib.conf 2022-12-04 12:19:11 +08:00
midoks c46872dab5 Update phplib.conf 2022-12-04 12:13:14 +08:00
midoks b57edb7b87 加入phalcon 2022-12-04 12:12:26 +08:00
midoks 595cc30c6f Update swoole.sh 2022-12-04 11:42:41 +08:00
midoks 4b6f5a5f4e Update swoole.sh 2022-12-04 11:29:53 +08:00
midoks 741da10906 Update swoole.sh 2022-12-04 11:29:26 +08:00
midoks 9965786976 Update README.md 2022-12-04 11:24:15 +08:00
midoks f083696131 Update install.sh 2022-12-04 11:24:09 +08:00
midoks dd2105d9ab 文件搜索优化 2022-12-04 00:57:03 +08:00
midoks c1574f3430 up 2022-12-03 15:56:58 +08:00
midoks 6394ead5b8 解除域名绑定成功 2022-12-03 13:27:24 +08:00
28 changed files with 683 additions and 251 deletions
+4 -1
View File
@@ -106,6 +106,7 @@ venv.bak/
.idea/*.iml
tmp/*
*.swp
*.pem
*.zip
logs/*
data/*.db
@@ -116,13 +117,15 @@ data/json/config.json
data/site.pl
data/admin_path.pl
data/close.pl
ssl/input.pl
data/datadir.pl
data/502Task.pl
data/default.pl
data/backup.pl
data/debug.pl
data/default_site.pl
ssl/input.pl
lib/python*
bin
+11 -8
View File
@@ -90,15 +90,14 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
```
### 版本更新 0.11.2
### 版本更新 0.11.3
* redis安全强化。
* 添加php命令行设置。
* 域名绑定。
* Gitea优化。
* 网站统计优化。
* centos9下php-gd安装优化。
* php82rc7测试版。
* 域名绑定修改。
* 面板ssl配置加入。
* 文件搜索优化。
* php加入phalcon。
* 文件管理UI优化。
* phpmyadmin优化。
### JSDelivr安装地址
@@ -160,6 +159,8 @@ curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/up
wget -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/uninstall.sh && bash uninstall.sh
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/debug.sh | bash
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/master/scripts/install_dev.sh | bash
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/update_dev.sh | bash
```
@@ -168,6 +169,8 @@ curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/update_dev.sh |
TVbNgrpeGBGZVm5gTLa21ADP7RpnPFhjya
日行一善,以后必定大富大贵
### 微信赞助
+134 -54
View File
@@ -27,7 +27,7 @@ from flask import request
class config_api:
__version = '0.11.2'
__version = '0.11.3'
__api_addr = 'data/api.json'
def __init__(self):
@@ -89,21 +89,6 @@ class config_api:
return mw.returnJson(True, '修改成功!')
return mw.returnJson(False, '修改失败!')
def setPanelDomainApi(self):
domain = request.form.get('domain', '')
cfg_domain = 'data/bind_domain.pl'
if domain == '':
os.remove(cfg_domain)
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, '主域名格式不正确')
mw.writeFile(cfg_domain, domain)
return mw.returnJson(True, '设置域名成功!')
def syncDateApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发系统不必同步时间!')
@@ -150,7 +135,8 @@ class config_api:
import system_api
import firewall_api
if os.path.exists("/lib/systemd/system/firewalld.service"):
sysCfgDir = mw.systemdCfgDir()
if os.path.exists(sysCfgDir + "/firewalld.service"):
if not firewall_api.firewall_api().getFwStatus():
return mw.returnJson(False, 'firewalld必须先启动!')
@@ -257,7 +243,8 @@ class config_api:
import system_api
import firewall_api
if os.path.exists("/lib/systemd/system/firewalld.service"):
sysCfgDir = mw.systemdCfgDir()
if os.path.exists(sysCfgDir + "/firewalld.service"):
if not firewall_api.firewall_api().getFwStatus():
return mw.returnJson(False, 'firewalld必须先启动!')
@@ -354,20 +341,33 @@ class config_api:
# 获取面板证书
def getPanelSslApi(self):
cert = {}
cert['privateKey'] = mw.readFile('ssl/privateKey.pem')
cert['certPem'] = mw.readFile('ssl/certificate.pem')
keyPath = 'ssl/private.pem'
certPath = 'ssl/cert.pem'
if not os.path.exists(certPath):
mw.createSSL()
cert['privateKey'] = mw.readFile(keyPath)
cert['certPem'] = mw.readFile(certPath)
cert['rep'] = os.path.exists('ssl/input.pl')
cert['info'] = mw.getCertName(certPath)
return mw.getJson(cert)
# 保存面板证书
def savePanelSslApi(self):
keyPath = 'ssl/privateKey.pem'
certPath = 'ssl/certificate.pem'
keyPath = 'ssl/private.pem'
certPath = 'ssl/cert.pem'
checkCert = '/tmp/cert.pl'
certPem = request.form.get('certPem', '').strip()
privateKey = request.form.get('privateKey', '').strip()
if(privateKey.find('KEY') == -1):
return mw.returnJson(False, '秘钥错误,请检查!')
if(certPem.find('CERTIFICATE') == -1):
return mw.returnJson(False, '证书错误,请检查!')
mw.writeFile(checkCert, certPem)
if privateKey:
mw.writeFile(keyPath, privateKey)
@@ -378,22 +378,128 @@ class config_api:
mw.writeFile('ssl/input.pl', 'True')
return mw.returnJson(True, '证书已保存!')
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 = 'data/bind_domain.pl'
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()
mw.writeFile(cfg_domain, domain)
return mw.returnJson(True, '设置域名成功!')
# 设置面板SSL
def setPanelSslApi(self):
sslConf = mw.getRunDir() + '/data/ssl.pl'
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:
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():
return mw.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!<p>请尝试手动安装: pip install pyOpenSSL</p>')
if not os.path.exists('ssl/input.ssl'):
mw.createSSL()
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, '开启失败,无法自动安装pyOpenSSL组件!<p>请尝试手动安装: pip install pyOpenSSL</p>')
return mw.returnJson(False, '开启失败:' + str(ex))
mw.restartWeb()
return mw.returnJson(True, '开启成功,请使用https协议访问面板!')
def getApi(self):
@@ -401,32 +507,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:
+87 -27
View File
@@ -97,11 +97,11 @@ class files_api:
import shutil
try:
shutil.move(sfile, dfile)
msg = mw.getInfo('移动文件或目录[{1}]到[{2}]成功!', (sfile, dfile,))
msg = mw.getInfo('移动或重名命文件[{1}]到[{2}]成功!', (sfile, dfile,))
mw.writeLog('文件管理', msg)
return mw.returnJson(True, '移动文件或目录成功!')
return mw.returnJson(True, '移动或重名命文件成功!')
except:
return mw.returnJson(False, '移动文件或目录失败!')
return mw.returnJson(False, '移动或重名命文件失败!')
def deleteApi(self):
path = request.form.get('path', '')
@@ -148,12 +148,16 @@ class files_api:
if not os.path.exists(path):
path = mw.getRootDir() + "/wwwroot"
search = request.args.get('search', '').strip().lower()
search_all = request.args.get('all', '').strip().lower()
page = request.args.get('p', '1').strip().lower()
row = request.args.get('showRow', '10')
disk = request.form.get('disk', '')
if disk == 'True':
row = 1000
# return self.getAllDir(path, int(page), int(row), "wp-inlcude")
if search_all == 'yes' and search != '':
return self.getAllDir(path, int(page), int(row), search)
return self.getDir(path, int(page), int(row), search)
def createFileApi(self):
@@ -830,11 +834,59 @@ class files_api:
if search:
if name.lower().find(search) == -1:
continue
# if name[0:1] == '.':
# continue
if name == '.':
continue
i += 1
return i
def getAllDir(self, path, page=1, page_size=10, search=None):
# print("search:", search)
data = {}
dirnames = []
filenames = []
count = 0
max_limit = 3000
for d_list in os.walk(path):
if count >= max_limit:
break
for d in d_list[1]:
if count >= max_limit:
break
if d.lower().find(search) != -1:
filename = d_list[0] + '/' + d
if not os.path.exists(filename):
continue
dirnames.append(self.__get_stats(filename, path))
count += 1
for f in d_list[2]:
if count >= max_limit:
break
if f.lower().find(search) != -1:
filename = d_list[0] + '/' + f
if not os.path.exists(filename):
continue
filenames.append(self.__get_stats(filename, path))
count += 1
data['DIR'] = sorted(dirnames)
data['FILES'] = sorted(filenames)
data['PATH'] = path.replace('//', '/')
info = {}
info['count'] = len(dirnames) + len(filenames)
info['row'] = page_size
info['p'] = page
info['tojs'] = 'getFiles'
pageObj = mw.getPageObject(info, '1,2,3,4,5,6,7,8')
data['PAGE'] = pageObj[0]
return mw.getJson(data)
def getDir(self, path, page=1, page_size=10, search=None):
data = {}
dirnames = []
@@ -861,31 +913,14 @@ class files_api:
continue
try:
filePath = path + '/' + filename
link = ''
if os.path.islink(filePath):
filePath = os.readlink(filePath)
link = ' -> ' + filePath
if not os.path.exists(filePath):
filePath = path + '/' + filePath
if not os.path.exists(filePath):
continue
if not os.path.exists(filePath):
continue
stat = os.stat(filePath)
accept = str(oct(stat.st_mode)[-3:])
mtime = str(int(stat.st_mtime))
user = ''
try:
user = pwd.getpwuid(stat.st_uid).pw_name
except Exception as ee:
user = str(stat.st_uid)
size = str(stat.st_size)
file_stats = self.__get_stats(filePath, path)
if os.path.isdir(filePath):
dirnames.append(filename + ';' + size + ';' +
mtime + ';' + accept + ';' + user + ';' + link)
dirnames.append(file_stats)
else:
filenames.append(filename + ';' + size + ';' +
mtime + ';' + accept + ';' + user + ';' + link)
filenames.append(file_stats)
n += 1
except Exception as e:
continue
@@ -894,3 +929,28 @@ class files_api:
data['PATH'] = path.replace('//', '/')
return mw.getJson(data)
def __get_stats(self, filename, path=None):
filename = filename.replace('//', '/')
try:
stat = os.stat(filename)
accept = str(oct(stat.st_mode)[-3:])
mtime = str(int(stat.st_mtime))
user = ''
try:
user = str(pwd.getpwuid(stat.st_uid).pw_name)
except:
user = str(stat.st_uid)
size = str(stat.st_size)
link = ''
if os.path.islink(filename):
link = ' -> ' + os.readlink(filename)
if path:
tmp_path = (path + '/').replace('//', '/')
filename = filename.replace(tmp_path, '', 1)
return filename + ';' + size + ';' + mtime + ';' + accept + ';' + user + ';' + link
except Exception as e:
# print(e)
return ';;;;;'
+1 -1
View File
@@ -356,7 +356,7 @@ class firewall_api:
mw.execShell('/etc/init.d/iptables stop')
else:
if self.__isUfw:
mw.execShell("echo 'y'|sudo ufw enable")
mw.execShell("echo 'y'| ufw enable")
if self.__isFirewalld:
mw.execShell('systemctl start firewalld.service')
mw.execShell('systemctl enable firewalld.service')
+106 -3
View File
@@ -920,13 +920,22 @@ def checkDomainPanel():
tmp = getHost()
domain = readFile('data/bind_domain.pl')
port = readFile('data/port.pl').strip()
npid = getServerDir() + "/openresty/nginx/logs/nginx.pid"
if not os.path.exists(npid):
return False
nconf = getServerDir() + "/web_conf/nginx/vhost/panel.conf"
if os.path.exists(nconf):
port = "80"
if domain:
client_ip = getClientIp()
if client_ip in ['127.0.0.1', 'localhost', '::1']:
return False
if tmp.strip().lower() != domain.strip().lower():
from flask import Flask, redirect, request, url_for
to = "http://" + domain + ":" + port
to = "http://" + domain + ":" + str(port)
return redirect(to, code=302)
return False
@@ -1282,13 +1291,107 @@ 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/cert.pem', cert_ca, 'wb+')
writeFile('ssl/private.pem', private_key, 'wb+')
return True
return False
def getSSHPort():
try:
file = '/etc/ssh/sshd_config'
conf = readFile(file)
rep = "#*Port\s+([0-9]+)\s*\n"
port = re.search(rep, conf).groups(0)[0]
rep = "(#*)?Port\s+([0-9]+)\s*\n"
port = re.search(rep, conf).groups(0)[1]
return int(port)
except:
return 22
+2 -67
View File
@@ -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):
+23
View File
@@ -0,0 +1,23 @@
server
{
listen {$PORT};
listen [::]:{$PORT};
server_name {$SERVER_NAME};
index index.php index.html index.htm default.php default.htm default.html;
#SSL-START
#error_page 404/404.html;
#SSL-END
#PROXY-START
location ^~ / {
proxy_pass http://0.0.0.0:{$PANAL_PORT}/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
#PROXY-END
error_log {$LOGPATH}/{$SERVER_NAME}.error.log;
}
+1 -1
View File
@@ -33,7 +33,7 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
if [ ! -f $sourcePath/php/php-${version}.tar.xz ];then
# wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://downloads.php.net/~pierrick/php-${version}.tar.xz
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://downloads.php.net/~sergey/php-${version}.tar.xz
wget --no-check-certificate -O $sourcePath/php/php-${version}.tar.xz https://downloads.php.net/~pierrick/php-${version}.tar.xz
fi
cd $sourcePath/php && tar -Jxf $sourcePath/php/php-${version}.tar.xz
+1 -1
View File
@@ -40,7 +40,7 @@ cd $DIR
PHP_VER_LIST=(53 54 55 56 70 71 72 73 74 80 81 82)
PHP_EXT_LIST=(ioncube ZendGuardLoader pdo mysqlnd sqlite3 openssl pcntl opcache mcrypt fileinfo \
exif gd intl memcache memcached redis imagemagick xdebug xhprof \
swoole yaf yar yac apc mongo mongodb solr seaslog mbstring iconv)
swoole yaf yar yac apc mongo mongodb solr seaslog mbstring iconv phalcon)
for PHP_VER in ${PHP_VER_LIST[@]}; do
echo "php${PHP_VER} -- start"
+7 -4
View File
@@ -17,10 +17,13 @@ sysName=`uname`
actionType=$1
version=$2
if [ "$version" -gt "56" ];then
echo "not need"
exit 1
fi
if [ "$version" -gt "56" ] && [ "$version" -lt "80" ];then
LIBV=4.0.5.2
fi
if [ "$version" -gt "74" ];then
LIBV=8.0
fi
LIB_PATH_NAME=lib/php
+123
View File
@@ -0,0 +1,123 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sourcePath=${serverPath}/source/php
actionType=$1
version=$2
LIBNAME=phalcon
LIBV=4.1.2
if [ "$version" -lt "73" ];then
echo "not support!"
exit 1
else
if [ "$version" -gt "74" ];then
LIBV=5.1.2
else
echo "not support!"
fi
LIB_PATH_NAME=lib/php
if [ -d $serverPath/php/${version}/lib64 ];then
LIB_PATH_NAME=lib64
fi
NON_ZTS_FILENAME=`ls $serverPath/php/${version}/${LIB_PATH_NAME}/extensions | grep no-debug-non-zts`
extFile=$serverPath/php/${version}/${LIB_PATH_NAME}/extensions/${NON_ZTS_FILENAME}/${LIBNAME}.so
sysName=`uname`
if [ "$sysName" == "Darwin" ];then
BAK='_bak'
else
BAK=''
fi
Install_lib()
{
isInstall=`cat $serverPath/php/$version/etc/php.ini|grep "${LIBNAME}.so"`
if [ "${isInstall}" != "" ];then
echo "php-$version 已安装${LIBNAME},请选择其它版本!"
return
fi
if [ ! -f "$extFile" ];then
php_lib=$sourcePath/php_lib
mkdir -p $php_lib
if [ ! -f $php_lib/${LIBNAME}-${LIBV}.tgz ];then
wget -O $php_lib/${LIBNAME}-${LIBV}.tgz http://pecl.php.net/get/${LIBNAME}-${LIBV}.tgz
cd $php_lib
tar xvf ${LIBNAME}-${LIBV}.tgz
fi
cd $php_lib/${LIBNAME}-${LIBV}
$serverPath/php/$version/bin/phpize
./configure --with-php-config=$serverPath/php/$version/bin/php-config
make clean && make && make install && make clean
fi
while [[ ! -f "$extFile" ]];
do
echo -e ".\c"
sleep 0.5
if [ ! -f "$extFile" ];then
echo "ERROR!"
fi
let n+=1
if [ $n -gt 8 ];then
echo "WAIT " $n "TIMES FAIL!"
return;
fi
done
echo "" >> $serverPath/php/$version/etc/php.ini
echo "[${LIBNAME}]" >> $serverPath/php/$version/etc/php.ini
echo "extension=${LIBNAME}.so" >> $serverPath/php/$version/etc/php.ini
bash ${rootPath}/plugins/php/versions/lib.sh $version restart
echo '==========================================================='
echo 'successful!'
}
Uninstall_lib()
{
if [ ! -f "$serverPath/php/$version/bin/php-config" ];then
echo "php-$version 未安装,请选择其它版本!"
return
fi
if [ ! -f "$extFile" ];then
echo "php-$version 未安装${LIBNAME},请选择其它版本!"
return
fi
echo $serverPath/php/$version/etc/php.ini
sed -i $BAK "/${LIBNAME}.so/d" $serverPath/php/$version/etc/php.ini
sed -i $BAK "/${LIBNAME}/d" $serverPath/php/$version/etc/php.ini
rm -f $extFile
bash ${rootPath}/plugins/php/versions/lib.sh $version restart
echo '==============================================='
echo 'successful!'
}
if [ "$actionType" == 'install' ];then
Install_lib
elif [ "$actionType" == 'uninstall' ];then
Uninstall_lib
fi
+5 -8
View File
@@ -19,17 +19,14 @@ LIBV=4.8.10
if [ "$version" -lt "70" ];then
LIBV=1.10.1
elif [ "$version" == "71" ];then
LIBV=4.5.2
elif [ "$version" == "70" ];then
LIBV=4.3.0
elif [ "$version" == "71" ];then
LIBV=4.5.2
elif [ "$version" -gt "74" ];then
LIBV=5.0.1
else
echo '72+'
fi
if [ "$version" -eq "82" ];then
echo "not need"
exit 1
echo 'other?'
fi
LIB_PATH_NAME=lib/php
+22 -1
View File
@@ -314,7 +314,15 @@
"53",
"54",
"55",
"56"
"56",
"70",
"71",
"72",
"73",
"74",
"80",
"81",
"82"
],
"type": "缓存器",
"msg": "强大的内容缓存器,不支持集群",
@@ -486,6 +494,19 @@
"shell": "eaccelerator.sh",
"check": "eaccelerator.so"
},
{
"name": "phalcon",
"versions": [
"73",
"74",
"80",
"81"
],
"type": "框架",
"msg": "Phalcon是一个全栈PHP框架。",
"shell": "phalcon.sh",
"check": "phalcon.so"
},
{
"name": "yaf",
"versions": [
-2
View File
@@ -82,9 +82,7 @@ def getHomePage():
def getPhpVer(expect=55):
import json
v = site_api.site_api().getPhpVersion()
v = json.loads(v)
is_find = False
for i in range(len(v)):
t = int(v[i]['version'])
-1
View File
@@ -71,7 +71,6 @@ def getHomePage():
def getPhpVer(expect=56):
import json
v = site_api.site_api().getPhpVersion()
v = json.loads(v)
for i in range(len(v)):
t = int(v[i]['version'])
if (t >= expect):
+28 -6
View File
@@ -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,13 +359,29 @@ 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">\
<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>\
'+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>\
+23 -9
View File
@@ -289,7 +289,7 @@ function openFilename(obj){
var ext = getSuffixName(path);
// console.log(path,ext);
if (inArray(ext,['html','htm','php','txt','md','js','css','scss','json','c','h','pl','py','java','log','conf'])){
if (inArray(ext,['html','htm','php','txt','md','js','css','scss','json','c','h','pl','py','java','log','conf','sh','json'])){
onlineEditFile(0, path);
}
@@ -317,6 +317,10 @@ function openFilename(obj){
}
}
function searchFile(p){
getFiles(p);
}
//取数据
function getFiles(Path) {
var searchtype = Path;
@@ -342,7 +346,14 @@ function getFiles(Path) {
var data = 'path=' + Path;
var loadT = layer.load();
var totalSize = 0;
$.post('/files/get_dir?p=' + p + '&showRow=' + showRow + search, data, function(rdata) {
var search_all = '';
var all = $('#search_all').hasClass('active');
if(all){
search_all = "&all=yes";
}
$.post('/files/get_dir?p=' + p + '&showRow=' + showRow + search + search_all, data, function(rdata) {
layer.close(loadT);
var rows = ['10','50','100','200','500','1000','2000'];
@@ -444,8 +455,7 @@ function getFiles(Path) {
<a class='btlink' href='javascript:;' onclick=\"cutFile('" + rdata.PATH +"/"+ fmp[0] + "')\">剪切</a> | \
<a class='btlink' href='javascript:;' onclick=\"reName(0,'" + fmp[0] + "')\">重命名</a> | \
<a class='btlink' href=\"javascript:setChmod(0,'" + rdata.PATH +"/"+ fmp[0] + "');\">权限</a> | \
<a class='btlink' href=\"javascript:zip('" + rdata.PATH +"/" +fmp[0] + "');\">压缩</a> | \
"+bodyZip+download+"\
<a class='btlink' href=\"javascript:zip('" + rdata.PATH +"/" +fmp[0] + "');\">压缩</a> | "+bodyZip+download+"\
<a class='btlink' href='javascript:;' onclick=\"deleteFile('" + rdata.PATH +"/"+ fmp[0] + "')\">删除</a>\
</span></td>\
</tr>";
@@ -459,9 +469,9 @@ function getFiles(Path) {
</div>";
}
}
var dirInfo = '(共{1}个目录与{2}个文件,大小:'.replace('{1}',rdata.DIR.length+'').replace('{2}',rdata.DIR.length+'')+'<font id="pathSize">'
var dirInfo = '(共{1}个目录与{2}个文件,大小:'.replace('{1}',rdata.DIR.length+'').replace('{2}',rdata.FILES.length+'')+'<font id="pathSize">'
+ (toSize(totalSize))+'<a class="btlink ml5" onClick="getPathSize()">获取</a></font>)';
$("#DirInfo").html(dirInfo);
$("#dir_info").html(dirInfo);
if( getCookie('rank') == 'a' ){
var tablehtml = '<table width="100%" border="0" cellpadding="0" cellspacing="0" class="table table-hover">\
<thead>\
@@ -791,7 +801,7 @@ function getSuffixName(fileName){
'gif','ico','jpeg','jpg','JPG','png','psd','webp','ape','avi','flv','mkv','mov','mp3','mp4','mpeg',
'mpg','rm','rmvb','swf','wav','webm','wma','wmv','doc','docm','dotx','dotm','dot','rtf','docx','pdf',
'fdf','ppt','pptm','pot','potm','pptx','txt','xls','csv','xlsm','xlsb','xlsx','7z','gz','cab','iso',
'rar','zip','bt','file','apk','css','scss','svg','pl','py','php','md'];
'rar','zip','bt','file','apk','css','scss','svg','pl','py','php','md','json','sh'];
var extLastName = extArr[extArr.length - 1];
for(var i=0; i<exts.length; i++){
if(exts[i]==extLastName){
@@ -1093,7 +1103,7 @@ function reName(type, fileName) {
closeBtn: 1,
area: '320px',
title: '重命名',
btn:["确定","保存"],
btn:["确定","取消"],
content: '<div class="bt-form pd20">\
<div class="line">\
<input type="text" class="bt-input-text" name="Name" id="newFileName" value="' + fileName + '" placeholder="文件名" style="width:100%" />\
@@ -1605,10 +1615,13 @@ function getPathSize(){
$("body").not(".def-log").click(function(){
$("#rmenu").hide()
});
//指定路径
$("#DirPathPlace input").keyup(function(e){
if(e.keyCode == 13) {
getFiles($(this).val());
var fpath = $(this).val();
fpath = filterPath(fpath);
getFiles(fpath);
}
});
@@ -1652,6 +1665,7 @@ function pathLeft(){
$("#PathPlaceBtn ul").css("left",0);
}
}
//路径快捷点击
$("#PathPlaceBtn").on("click", function(e){
if($("#DirPathPlace").is(":hidden")){
+13
View File
@@ -100,6 +100,19 @@ function isContains(str, substr) {
return str.indexOf(substr) >= 0;
}
function filterPath(path){
var path_arr = path.split('/');
var path_new = [];
for (var i = 0; i < path_arr.length; i++) {
if (path_arr[i]!=''){
path_new.push(path_arr[i]);
}
}
var rdata = "/"+path_new.join('/');
return rdata;
}
function msgTpl(msg, args){
if (typeof args == 'string'){
return msg.replace('{1}', args);
+56 -1
View File
@@ -4813,8 +4813,63 @@ select[disabled]{
bottom:10px;
right:10px;
}
.shell_btn_close{
.shell_btn_close {
margin-right:8px;
}
.file_search {
position: absolute;
right: 58px;
font-size: 12px;
color: #666;
width: 85px;
border-top: none;
background: #fff;
height: 8px;
line-height: 48px;
top: 0;
}
.file_search .file_search_checked {
position: relative;
height: 15px;
width: 15px;
border-radius: 1px;
cursor: pointer;
text-align: center;
margin: 0;
vertical-align: sub;
border:1px solid #aaa;
border-radius: 2px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: 400;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
.file_search .file_search_checked.active {
background: #20a53a;
color: #fff;
border-color:#20a53a ;
}
.file_search .file_search_checked.active:after {
content: "\e013";
font-size: 12px;
transform: scale(.85);
position: absolute;
left: .75px;
top: .75px;
}
.file_search label {
position: absolute;
right: 5px;
cursor: pointer;
top: 0;
font-weight: 400;
}
+3 -3
View File
@@ -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>
+13 -4
View File
@@ -13,11 +13,15 @@
<span id='DirPathPlace' class="pull-left"><input id="fileInputPath" type="text"></span>
<span id='PathPlaceBtn' class="pull-left"></span>
</div>
<div class="pull-left mlr15" style="line-height:26px"><span id='DirInfo'></span></div>
<div class="pull-left mlr15" style="line-height:26px"><span id='dir_info'></span></div>
<div class="search pull-right" style="position: absolute; top: 6px; right: 5px;">
<form target="hid" onsubmit='getFiles(1)'>
<input type="text" id="SearchValue" class="ser-text pull-left" placeholder="" />
<button type="button" class="ser-sub pull-left" onclick='getFiles(1)'></button>
<form target="hid">
<input type="text" id="SearchValue" class="ser-text pull-left" placeholder="搜索文件/目录" />
<button type="button" class="ser-sub pull-left" onclick='searchFile(1)'></button>
<div class="file_search" draggable="false">
<div id="search_all" class="file_search_checked"></div>
<label for="search_all">包含子目录</label>
</div>
</form>
<iframe name='hid' id="hid" style="display:none"></iframe>
</div>
@@ -93,5 +97,10 @@ $("#set_list").click(function() {
$(".refreshBtn").click(function() {
getFiles(getCookie('open_dir_path'));
})
$('#search_all').click(function(){
$(this).toggleClass('active');
});
</script>
{% endblock %}
+8
View File
@@ -182,6 +182,13 @@ mw_open()
fi
}
mw_unbind_domain()
{
if [ -f $mw_path/data/bind_domain.pl ];then
rm -rf $mw_path/data/bind_domain.pl
fi
}
error_logs()
{
tail -n 100 $mw_path/logs/error.log
@@ -271,6 +278,7 @@ case "$1" in
'update_dev') mw_update_dev;;
'install_app') mw_install_app;;
'close_admin_path') mw_close_admin_path;;
'unbind_domain') mw_unbind_domain;;
'debug') mw_debug;;
'default')
cd $mw_path
-3
View File
@@ -82,6 +82,3 @@ loglevel = 'info'
errorlog = log_dir + '/error.log'
accesslog = log_dir + '/access.log'
pidfile = log_dir + '/mw.pid'
if os.path.exists(os.getcwd() + '/data/ssl.pl'):
certfile = 'ssl/certificate.pem'
keyfile = 'ssl/privateKey.pem'
+4
View File
@@ -0,0 +1,4 @@
# 自动生成
certificate.pem - 证书信息
privateKey.pem - 私钥
-17
View File
@@ -1,17 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICojCCAYoCAQAwDQYJKoZIhvcNAQEEBQAwFzEVMBMGA1UEAwwMMTIwLjI3LjI3
Ljk4MB4XDTE5MDIyMjA2MDg1MVoXDTI5MDIxOTA2MDg1MVowFzEVMBMGA1UEAwwM
MTIwLjI3LjI3Ljk4MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3P5X
4ROFaVpHNoI+a4+epK5gcfRRxyAjdroryjT/HdSQU9CnE28l5zrUsPx7JZcqbnNN
/S6gJcsIDSqglKRLBgBPab65/MwJvHKoowfuG75144DsgY5bMvoCqSTGX77Ado1W
vcEjwsYolxiDcnSp9A8VZX/qjTgWHe8/Si2saDa2zJ473n4qa0q/DvGXIQDviZcy
cxkPJgoRpFw03oJmdZsJGJ34+TN0AN9XiZ0XgOQIKIq8QXc7By+YUryfecz4GYQT
9f0K9sfY3W0bkkZ6LW9tauZU3N3/nr5fuOU7ia+IhPop7ly+9E6lyGHViwqcufbz
95wBQJR9AEwbJJdtRQIDAQABMA0GCSqGSIb3DQEBBAUAA4IBAQAQtFdCabM+Ybog
Z8xAbikeokOXr+X3UnUehXr3/FSJ+0/aWCzmNn8gXskYLyvCR1fkrk/0bVZoDxXt
pwux58CiJAbn6dhFIP9thqghqQ75Z/YR245pbulpamBgLTVdqWPyaaXokcXpr8wg
DhPZnfowCFu++UqoBeJ0IJGa1dpKdXYR8VIZFXXBf8vPGWsDu1dxMYHEM03Geutm
PNOJgENJGu9XHGBtzadiIiUI4rrmBqeMhQCUeMuiT3URfLAKujz2fi2RvohJvI9/
MYmngt54XY1AJW/wKpdO+FhyIyDl/xGbxdbe1DuCrAm4okAlQVrp1Q2TTEcXflns
jeT+bba8
-----END CERTIFICATE-----
-28
View File
@@ -1,28 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc/lfhE4VpWkc2
gj5rj56krmBx9FHHICN2uivKNP8d1JBT0KcTbyXnOtSw/Hsllypuc039LqAlywgN
KqCUpEsGAE9pvrn8zAm8cqijB+4bvnXjgOyBjlsy+gKpJMZfvsB2jVa9wSPCxiiX
GINydKn0DxVlf+qNOBYd7z9KLaxoNrbMnjvefiprSr8O8ZchAO+JlzJzGQ8mChGk
XDTegmZ1mwkYnfj5M3QA31eJnReA5AgoirxBdzsHL5hSvJ95zPgZhBP1/Qr2x9jd
bRuSRnotb21q5lTc3f+evl+45TuJr4iE+inuXL70TqXIYdWLCpy59vP3nAFAlH0A
TBskl21FAgMBAAECggEAJUEbP24zB1eYua+rJibH76sVxyAQySi50cIAr83PVBAJ
ZJfAEp6iHSDlyhBGEkgxdv0pII1Dohtf+Bg/ic9IdnKG8KSeZedfnM0XcKRdl3+8
D+Yj+JMu/KD44dq5NlrJxzJ8dPCiPqt5HD+dqSXRoLsKOFogCD50PAeg+7hHYCnI
worCm6MoCD8Qps6ArmR/YRatAF0wPQxCTX+TRww12gbgWTFPl0ocETth0r3LQHtz
jaOu/EtO87WXt1i3NjaRImLMnBytOPVUM0tLXGiAnXvfg39c8cyYUof2FbFO+kgT
nK89NrlPWMUo6jGZyf4riVdcPqza/FH5IEv4ToLL4QKBgQD8ICRM9oLtBJKf+749
auZbca25fSDfid/pSWaGB0VymJoETPfUMhKnrBi8uLcL0VJ6+I+kFmhZL/j3R5g3
7D9NhJyfGDBJv3CfjK2L/zPCiESEnMt0IRiEcxaIX+K9SjfHwCam4XLsnDWNG49B
WZ0onQNjY5IdYV7wsRMlBDmN6wKBgQDgY7qCUJVilRVX2TLOYgKIGaAb7QVVX9Bz
wukPRD/OFoufZRltbhwWCDrDRVJZlRccpAq+cr6KXg9AKhbn2xc6aLG4vPWBgLB0
P+QcR4lszRqqiM0yRUhOJSk3nFBtS7lsf80qTdP+Cz/M317/z7yqQNi92tNaHNLN
sYmVrM61jwKBgQDuIznGS+xcDL6lR3Vns2nDI3twQOTk3uhUA5VHsOSCmeqXd095
6JXAM4fl8R5LljmulsmttdB3tR0WC1SWNZmREVmR15n8fkrVGF3vZmuwKV92VlbA
6GWs7LtysgaKvegzzqVzaGxRWjYmgsprckZDzxIdNTYUdBzlgItRokzuYwKBgG7Y
9U7g7hsIGMYP9ug7RJLlTdHd0e+t6HT3SViQV5DAVHMGZ3xGk7tSj2zdduPoIcW1
R9VzK6uA8bm50Rzyf1QMWhcvyXwTDZgv48kQkdPcspqh//Qgg6qO8wCUyKplaREv
RTPrxJjQB9F2WyC2B7Z3WFrZmeT/LigM1zHIb0kDAoGABmrg8nXGBrEdtYXHFdem
1iP0X3+Xt/RwH50YjsNNbUmngIbiR5q71vFkfM7UhIjlnKX/HfSTCUyCtLjHBIFh
E/OHbEVgElbegnCx3uX4+kxP/oFGNh9t9fJAOsipaYrVVyQWK3C5ilrcBcx4jdXB
c4cumeA0lZ2p1hc82ArHxYk=
-----END PRIVATE KEY-----
+8 -1
View File
@@ -56,6 +56,7 @@ def mwcli(mw_input=0):
print("(12) 修改面板用户名")
print("(13) 显示面板错误日志")
print("(20) 关闭BasicAuth认证")
print("(21) 解除域名绑定")
print("(0) 取消")
print(raw_tip)
try:
@@ -65,7 +66,7 @@ def mwcli(mw_input=0):
except:
mw_input = 0
nums = [1, 2, 3, 4, 5, 10, 11, 12, 13, 20]
nums = [1, 2, 3, 4, 5, 10, 11, 12, 13, 20, 21]
if not mw_input in nums:
print(raw_tip)
print("已取消!")
@@ -109,6 +110,12 @@ def mwcli(mw_input=0):
os.remove(basic_auth)
os.system(INIT_CMD + " restart")
print("|-关闭basic_auth成功")
elif mw_input == 21:
bind_domain = 'data/bind_domain.pl'
if os.path.exists(bind_domain):
os.remove(bind_domain)
os.system(INIT_CMD + " unbind_domain")
print("|-解除域名绑定成功")
def set_panel_pwd(password, ncli=False):