Add panel SSL own certificate to fill in the entry

Fixed known bugs
Panel Feature Modification

Points to note after updating the panel:
1. The default port of the panel is changed to 7800
(Port 8888 has been flooded)
2. Panel entry error will prompt 404
3. After the panel is bound to the domain name,
if the domain access is not used,it will return 401
4. After the panel is set to authorize IP access,
other IP access panels will return 401
5. The website welcome page is changed to the nginx welcome page
6. Change the stop page to Nginx 404 page
This commit is contained in:
bt.cn
2022-01-18 18:01:37 +08:00
parent eec64ddfa2
commit d2a66661db
64 changed files with 1901 additions and 703 deletions
+155 -8
View File
@@ -60,6 +60,7 @@ class acme_v2:
_dnsapi_file = 'config/dns_api.json'
_save_path = 'vhost/letsencrypt'
_conf_file = 'config/letsencrypt.json'
_stop_rp_file = '{}/data/stop_rp_when_renew_ssl.pl'.format(public.get_panel_path())
_by_panel = None
def __init__(self):
@@ -1331,15 +1332,95 @@ fullchain.pem Paste into certificate input box
if not os.path.exists(args.auth_to):
return public.returnMsg(False, 'ACME_DIR_ERR')
check_result = self.check_auth_env(args)
check_result = self.check_auth_env(args, check=True)
if check_result: return check_result
if args.auto_wildcard == '1':
self._auto_wildcard = True
return self.apply_cert(json.loads(args.domains), args.auth_type, args.auth_to)
res = self.apply_cert(json.loads(args.domains), args.auth_type, args.auth_to)
if os.path.exists(self._stop_rp_file):
self.turnon_redirect_proxy_httptohttps(args)
return res
def turnon_redirect_proxy_httptohttps(self,args):
import panelSite
s = panelSite.panelSite()
if not 'siteName' in args:
args.siteName = public.M('sites').where('id=?', (args.id,)).getField('name')
args.sitename = args.siteName
self.turnon_redirect(args,s)
self.turnon_proxy(args, s)
self.turnon_httptohttps(args,s)
public.serviceReload()
def turnon_httptohttps(self,args,s):
conf_file = '{}/data/stop_httptohttps.pl'.format(public.get_panel_path())
if os.path.exists(conf_file):
write_log('|-开启http to https')
s.HttpToHttps(args)
try:
os.remove(conf_file)
except:
pass
def turnon_proxy(self,args,s):
conf_file = '{}/data/stop_p_tmp.pl'.format(public.get_panel_path())
if not os.path.exists(conf_file):
return
write_log('|-开启反向代理')
conf = json.loads(public.readFile(conf_file))
data = s.GetProxyList(args)
for x in data:
if x['sitename'] not in conf:
continue
if x['proxyname'] not in conf[x['sitename']]:
continue
args.type = 1
args.advanced = x['advanced']
args.cache = x['cache']
args.cachetime = x['cachetime']
args.proxydir = x['proxydir']
args.proxyname = x['proxyname']
args.proxysite = x['proxysite']
args.sitename = x['sitename']
args.subfilter = json.dumps(x['subfilter'])
args.todomain = x['todomain']
s.ModifyProxy(args)
try:
os.remove(conf_file)
except:
pass
def turnon_redirect(self,args,s):
conf_file = '{}/data/stop_r_tmp.pl'.format(public.get_panel_path())
if not os.path.exists(conf_file):
return
write_log('|-开启重定向')
conf = json.loads(public.readFile(conf_file))
data = s.GetRedirectList(args)
for x in data:
if x['sitename'] not in conf:
continue
if x['redirectname'] not in conf[x['sitename']]:
continue
args.type = 1
args.sitename = x['sitename']
args.holdpath = x['holdpath']
args.redirectname = x['redirectname']
args.redirecttype = x['redirecttype']
args.domainorpath = x['domainorpath']
args.redirectpath = x['redirectpath']
args.redirectdomain = json.dumps(x['redirectdomain'])
args.tourl = x['tourl']
s.ModifyRedirect(args)
try:
os.remove(conf_file)
except:
pass
#检查认证环境
def check_auth_env(self,args):
def check_auth_env(self,args,check = None):
if not check:
return
for domain in json.loads(args.domains):
if public.checkIp(domain): continue
if domain.find('*.') >=0 and args.auth_type in ['http','tls']:
@@ -1348,26 +1429,80 @@ fullchain.pem Paste into certificate input box
s = panelSite.panelSite()
if args.auth_type in ['http','tls']:
try:
rp_conf = public.readFile(self._stop_rp_file)
try:
if rp_conf:
rp_conf = json.loads(rp_conf)
except:
write_log('|-Failed to parse configuration file')
if not 'siteName' in args:
args.siteName = public.M('sites').where('id=?',(args.id,)).getField('name')
args.sitename = args.siteName
data = s.GetRedirectList(args)
# 检查重定向是否开启
if type(data) == list:
redirect_tmp = {args.sitename:[]}
for x in data:
if x['type']: return public.returnMsg(False, 'SITE_SSL_ERR_301')
if rp_conf and x['sitename'] in rp_conf:
if str(x['type']) == '0':
continue
args.type = 0
args.sitename = x['sitename']
args.holdpath = x['holdpath']
args.redirectname = x['redirectname']
args.redirecttype = x['redirecttype']
args.domainorpath = x['domainorpath']
args.redirectpath = x['redirectpath']
args.redirectdomain = json.dumps(x['redirectdomain'])
args.tourl = x['tourl']
args.notreload = True
write_log("|- Turning off redirection {}".format(args.redirectname))
s.ModifyRedirect(args)
redirect_tmp[args.sitename].append(x['redirectname'])
else:
if x['type']: return public.returnMsg(False, 'SITE_SSL_ERR_301')
if redirect_tmp[args.sitename]:
public.writeFile('{}/data/stop_r_tmp.pl'.format(public.get_panel_path()),json.dumps(redirect_tmp))
data = s.GetProxyList(args)
# 检查反向代理是否开启
if type(data) == list:
proxy_tmp = {args.sitename: []}
for x in data:
if x['type']: return public.returnMsg(False,'ACME_PROXY_ERR')
if rp_conf and x['sitename'] in rp_conf:
if str(x['type']) == '0':
continue
args.type = 0
args.advanced = x['advanced']
args.cache = x['cache']
args.cachetime = x['cachetime']
args.proxydir = x['proxydir']
args.proxyname = x['proxyname']
args.proxysite = x['proxysite']
args.sitename = x['sitename']
args.subfilter = json.dumps(x['subfilter'])
args.todomain = x['todomain']
args.notreload = True
s.ModifyProxy(args)
write_log("|- Turning off proxy {}".format(args.proxyname))
proxy_tmp[args.sitename].append(x['proxyname'])
else:
if x['type']: return public.returnMsg(False,'ACME_PROXY_ERR')
if proxy_tmp[args.sitename]:
public.writeFile('{}/data/stop_p_tmp.pl'.format(public.get_panel_path()),json.dumps(proxy_tmp))
# 检查旧重定向是否开启
data = s.Get301Status(args)
if data['status']:
return public.returnMsg(False,'SITE_SSL_ERR_3011')
#判断是否强制HTTPS
if s.IsToHttps(args.siteName):
return public.returnMsg(False, 'ACME_FORCE_SSL_ERR')
if os.path.exists(self._stop_rp_file):
if rp_conf and args.siteName in rp_conf:
write_log("|- Turning off http to https")
s.CloseToHttps(args)
public.writeFile('{}/data/stop_httptohttps.pl'.format(public.get_panel_path()), '')
else:
return public.returnMsg(False, 'ACME_FORCE_SSL_ERR')
public.serviceReload()
except:
return False
else:
@@ -1511,7 +1646,7 @@ fullchain.pem Paste into certificate input box
# 是否到了最大重试次数
if 'retry_count' in self._config['orders'][i]:
if self._config['orders'][i]['retry_count'] >= 3:
write_log('|-Skip the domain name this time: {}, this certificate will not be renewed due to failure to renew 3 times in a row'.format(self._config['orders'][i]['domains']))
write_log('|-Skip the domain name this time: {}, this certificate will not be renewed due to failure to renew 3 times in a row, (The number of errors will be reset after manual renewal and success)'.format(self._config['orders'][i]['domains']))
continue
# 加入到续签订单
@@ -1524,7 +1659,17 @@ fullchain.pem Paste into certificate input box
n = 0
self.get_apis()
cert = None
args = public.to_dict_obj({})
for index in order_index:
args.domains = json.dumps(self._config['orders'][index]['domains'])
args.auth_type = self._config['orders'][index]['auth_type']
args.auth_to = self._config['orders'][index]['auth_to']
sitename = args.auth_to.split('/')[-1]
if not sitename:
sitename = self._config['orders'][index]['auth_to'].split('/')[-2]
args.siteName = sitename
write_log('|-Renew the visa certificate and start checking the environment')
self.check_auth_env(args,check=True)
n += 1
write_log(public.getMsg("ACME_RENEWING",(str(n),str(self._config['orders'][index]['domains']))))
write_log(public.getMsg('ACME_CREAT_ORDER'))
@@ -1558,6 +1703,8 @@ fullchain.pem Paste into certificate input box
self.save_config()
cert['status'] = True
cert['msg'] = public.getMsg('ACME_RENEW_SUCCESS')
if os.path.exists(self._stop_rp_file):
self.turnon_redirect_proxy_httptohttps(args)
write_log(public.getMsg('ACME_RENEW_SUCCESS1'))
except Exception as e:
if str(e).find('请稍候重试') == -1: # 受其它证书影响和连接CA失败的的不记录重试次数
+1 -1
View File
@@ -698,7 +698,7 @@ class ajax:
# 下载云端php扩展配置
def _get_cloud_phplib(self):
if not session.get('download_url'): session['download_url'] = 'http://download.bt.cn'
if not session.get('download_url'): session['download_url'] = 'http://node.aapanel.com'
download_url = session['download_url'] + '/install/lib/phplib_en.json'
tstr = public.httpGet(download_url)
data = json.loads(tstr)
+2 -2
View File
@@ -26,7 +26,7 @@ class panelSetup:
ua = g.ua.lower()
if ua.find('spider') != -1 or g.ua.find('bot') != -1:
return redirect('https://www.google.com')
g.version = '6.8.17'
g.version = '6.8.21'
g.title = public.GetConfigValue('title')
g.uri = request.path
g.debug = os.path.exists('data/debug.pl')
@@ -150,7 +150,7 @@ class panelAdmin(panelSetup):
if not 'login' in session:
api_check = self.get_sk()
if api_check:
session.clear()
#session.clear()
return api_check
g.api_request = True
else:
+57 -16
View File
@@ -31,10 +31,12 @@ class database(datatool.datatools):
if ssl == "REQUIRE SSL" and not self.check_mysql_ssl_status(get):
return public.returnMsg(False,'MYSQL_SSL_ERR')
data_name = get['name'].strip().lower()
if not data_name: return public.returnMsg(False, 'The database name cannot be empty')
if self.CheckRecycleBin(data_name): return public.returnMsg(False,'DATABASE_DEL_RECYCLE_BIN',(data_name,))
if len(data_name) > 64: return public.returnMsg(False, 'DATABASE_NAME_LEN')
reg = r"^[\w\.-]+$"
username = get.db_user.strip()
if not username: return public.returnMsg(False,'The database user name cannot be empty')
if not re.match(reg, data_name): return public.returnMsg(False,'DATABASE_NAME_ERR_T')
if not re.match(reg, username): return public.returnMsg(False,'DATABASE_NAME_ERR')
if not hasattr(get,'db_user'): get.db_user = data_name
@@ -50,6 +52,8 @@ class database(datatool.datatools):
if sql.where("name=?",(data_name)).count(): return public.returnMsg(False,'DATABASE_NAME_EXISTS')
if sql.where("username=?", (username)).count(): return public.returnMsg(False, 'DATABASE_USERNAME_EXISTS')
address = get['address'].strip()
if address in ['','ip']: return public.returnMsg(False,'If the access permission is [Specified IP], you need to enter the IP address!')
user = ''
password = data_pwd
@@ -102,16 +106,21 @@ openssl x509 -sha1 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.p
openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -subj "/C=CA/ST=CA/L=CA/O=CA/OU=CA/CN={ip}" -keyout client-key.pem > client-req.pem
openssl rsa -in client-key.pem -out client-key.pem
openssl x509 -sha1 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem
tar -zcvf ssl.zip client-cert.pem client-key.pem ca.pem
zip -q ssl.zip client-cert.pem client-key.pem ca.pem
""".format(ip=ip)
public.ExecShell(openssl_command)
# 写入mysqlssl到配置
def write_ssl_to_mysql(self,get):
ssl_conf = """
ssl-ca=/www/server/data/ca.pem
ssl-cert=/www/server/data/server-cert.pem
ssl-key=/www/server/data/server-key.pem
# ssl_conf = """
# ssl-ca=/www/server/data/ca.pem
# ssl-cert=/www/server/data/server-cert.pem
# ssl-key=/www/server/data/server-key.pem
# """
ssl_original_path = """
ssl-ca=/www/server/mysql/mysql-test/std_data/cacert.pem
ssl-cert=/www/server/mysql/mysql-test/std_data//server-cert.pem
ssl-key=/www/server/mysql/mysql-test/std_data/server-key.pem
"""
conf_file = "/etc/my.cnf"
conf = public.readFile(conf_file)
@@ -120,22 +129,37 @@ ssl-key=/www/server/data/server-key.pem
if self.check_mysql_ssl_status(get):
reg = "ssl-ca=/www.*\n.*\n.*server-key.pem\n"
conf = re.sub(reg,"",conf)
if os.path.exists('/www/server/mysql/mysql-test/std_data/server-cert.pem'):
conf = re.sub('\[mysqld\]', '[mysqld]\nskip_ssl', conf)
public.writeFile(conf_file,conf)
return public.returnMsg(True,"SET_SUCCESS")
self._create_mysql_ssl()
# create_ssl = None
# for i in ['5.5','5.6','10.1','10.2','10.3']:
# if i not in public.readFile('/www/server/mysql/version_check.pl'):
# continue
# create_ssl = True
# if create_ssl:
# self._create_mysql_ssl()
if "ssl-ca" not in conf:
conf = re.sub('\[mysqld\]','[mysqld]'+ssl_conf,conf)
conf = re.sub('\[mysqld\]','[mysqld]'+ssl_original_path,conf)
conf = re.sub('skip_ssl\n', '', conf)
public.writeFile(conf_file,conf)
public.ExecShell('chown mysql.mysql /www/server/data/*.pem')
# public.ExecShell('chown mysql.mysql /www/server/data/*.pem')
return public.returnMsg(True,"MYSQL_SSL_OPEN_SUCCESS")
# 检查mysqlssl状态
def check_mysql_ssl_status(self,get):
mysql_obj = panelMysql.panelMysql()
result = mysql_obj.query("show variables like 'have_ssl';")
if result and result[0][1] == "YES":
return True
return False
if not os.path.exists('/www/server/data/ssl.zip'):
if os.path.exists('/www/server/mysql/mysql-test/std_data/client-cert.pem'):
public.ExecShell("cd /www/server/mysql/mysql-test/std_data/ && zip -q /www/server/data/ssl.zip client-cert.pem client-key.pem cacert.pem")
try:
if result and result[0][1] == "YES":
return True
return False
except:
return False
#判断数据库是否存在—从MySQL
def database_exists_for_mysql(self,mysql_obj,dataName):
@@ -163,8 +187,10 @@ ssl-key=/www/server/data/server-key.pem
#检查是否在回收站
def CheckRecycleBin(self,name):
try:
u_name = self.db_name_to_unicode(name)
for n in os.listdir('/www/Recycle_bin'):
if n.find('BTDB_'+name+'_t_') != -1: return True
if n.find('BTDB_'+u_name+'_t_') != -1: return True
return False
except:
return False
@@ -320,7 +346,18 @@ SetLink
except Exception as ex:
public.WriteLog("TYPE_DATABASE",'DATABASE_DEL_ERR',(get.name , str(ex)))
return public.returnMsg(False,'DEL_ERROR')
def db_name_to_unicode(self,name):
'''
@name 中文数据库名转换为Unicode编码
@author hwliang<2021-12-20>
@param name<string> 数据库名
@return name<string> Unicode编码的数据库名
'''
name = name.replace('.','@002e')
return name.encode("unicode_escape").replace(b"\\u",b"@").decode()
#删除数据库到回收站
def DeleteToRecycleBin(self,name):
import json
@@ -333,11 +370,13 @@ SetLink
panelMysql.panelMysql().execute("flush privileges")
rPath = '/www/Recycle_bin/'
data['rmtime'] = int(time.time())
rm_path = '{}/BTDB_{}_t_{}'.format(rPath,name,data['rmtime'])
u_name = self.db_name_to_unicode(name)
rm_path = '{}/BTDB_{}_t_{}'.format(rPath,u_name,data['rmtime'])
if os.path.exists(rm_path): rm_path += '.1'
rm_config_file = '{}/config.json'.format(rm_path)
datadir = public.get_datadir()
db_path = '{}/{}'.format(datadir,name)
db_path = '{}/{}'.format(datadir,u_name)
if not os.path.exists(db_path):
return public.returnMsg(False,'Means that the database data does not exist!')
@@ -387,7 +426,8 @@ SetLink
else:
re_config_file = filename + '/config.json'
data = json.loads(public.readFile(re_config_file))
db_path = "{}/{}".format(public.get_datadir(),data['name'])
u_name = self.db_name_to_unicode(data['name'])
db_path = "{}/{}".format(public.get_datadir(),u_name)
if os.path.exists(db_path):
return public.returnMsg(False,'There is a database with the same name in the current database. To ensure data security, stop recovery!')
_isdir = True
@@ -766,7 +806,8 @@ SetLink
return public.returnMsg(False,'SSL is not enabled in the database, please open it in the Mysql manager first')
name = get['name']
db_name = public.M('databases').where('username=?',(name,)).getField('name')
access = get['access']
access = get['access'].strip()
if access in ['']: return public.returnMsg(False,'The IP address cannot be empty!')
password = public.M('databases').where("username=?",(name,)).getField('password')
mysql_obj = panelMysql.panelMysql()
result = mysql_obj.query("show databases")
+21 -3
View File
@@ -42,7 +42,13 @@ class FileExecuteDeny:
if not conf:
return False
data = re.findall('BEGIN_DENY_.*',conf)
deny_name = [i.split('_')[-1] for i in data]
deny_name = []
for i in data:
tmp = i.split('_')
if len(tmp) > 2:
deny_name.append('_'.join(tmp[2:]))
else:
deny_name.append(tmp[-1])
result = []
for i in deny_name:
reg = '#BEGIN_DENY_{}\n\s*location\s*\~\*\s*\^(.*)\.\*.*\((.*)\)\$'.format(i)
@@ -56,7 +62,13 @@ class FileExecuteDeny:
if not conf:
return False
data = re.findall('BEGIN_DENY_.*',conf)
deny_name = [i.split('_')[-1] for i in data]
deny_name = []
for i in data:
tmp = i.split('_')
if len(tmp) > 2:
deny_name.append('_'.join(tmp[2:]))
else:
deny_name.append(tmp[-1])
result = []
for i in deny_name:
reg = '#BEGIN_DENY_{}\n\s*<Directory\s*\~\s*"(.*)\.\*.*\((.*)\)\$'.format(i)
@@ -70,7 +82,13 @@ class FileExecuteDeny:
if not conf:
return False
data = re.findall('BEGIN_DENY_.*',conf)
deny_name = [i.split('_')[-1] for i in data]
deny_name = []
for i in data:
tmp = i.split('_')
if len(tmp) > 2:
deny_name.append('_'.join(tmp[2:]))
else:
deny_name.append(tmp[-1])
result = []
for i in deny_name:
reg = '#BEGIN_DENY_{}\n\s*rules\s*RewriteRule\s*\^(.*)\.\*.*\((.*)\)\$'.format(i)
+3 -3
View File
@@ -197,7 +197,7 @@ class firewalls:
types=get.type
type_list=['tcp','udp']
if types not in type_list:return public.returnMsg(False, 'FIREWALL_PORT_EXISTS')
notudps = ['80', '443', '8888', '888', '39000:40000', '21', '22']
notudps = ['80', '443', '8888', '888', '39000:40000', '21', '22', '7800']
if port in notudps:flag=True
#return public.M('firewall').where("port=?", (port,)).count()
if types=='tcp':
@@ -314,7 +314,7 @@ class firewalls:
#return public.returnMsg(False,'演示服务器,禁止此操作!');
port = get.port
if int(port) < 22 or int(port) > 65535: return public.returnMsg(False,'FIREWALL_SSH_PORT_ERR');
ports = ['21','25','80','443','8080','888','8888'];
ports = ['21','25','80','443','8080','888','8888', '7800']
if port in ports: return public.returnMsg(False,'');
file = '/etc/ssh/sshd_config'
@@ -419,7 +419,7 @@ class firewalls:
if protocol not in protocol_list: return public.returnMsg(False, 'FIREWALL_PORT_EXISTS')
notudps = ['80', '443', '8888', '888', '39000:40000', '21', '22']
notudps = ['80', '443', '8888', '888', '39000:40000', '21', '22','7800']
if ports in notudps: flag = True
# sql 查询
+2 -2
View File
@@ -141,7 +141,7 @@ class firewalls:
ps = public.xssencode(get.ps)
is_exists = public.M('firewall').where("port=? or port=?",(port,src_port)).count()
if is_exists: return public.returnMsg(False,'FIREWALL_PORT_EXISTS')
notudps = ['80','443','8888','888','39000:40000','21','22']
notudps = ['80','443','8888','888','39000:40000','21','22','7800']
if self.__isUfw:
public.ExecShell('ufw allow ' + port + '/tcp')
if not port in notudps: public.ExecShell('ufw allow ' + port + '/udp')
@@ -255,7 +255,7 @@ class firewalls:
def SetSshPort(self,get):
port = get.port
if int(port) < 22 or int(port) > 65535: return public.returnMsg(False,'FIREWALL_SSH_PORT_ERR')
ports = ['21','25','80','443','8080','888','8888']
ports = ['21','25','80','443','8080','888','8888','7800']
if port in ports: return public.returnMsg(False,'DONT_USE_PORT')
file = '/etc/ssh/sshd_config'
conf = public.readFile(file)
+13 -2
View File
@@ -286,9 +286,20 @@ class MemcachedSessionInterface(SessionInterface):
session_id = self._get_signer(app).sign(want_bytes(session.sid))
else:
session_id = session.sid
from BTPanel import request,g
from BTPanel import request, g, get_input
if 'auth_error' in g: return
if request.path == '/': return
if request.path in ['/', '/tips','/robots.txt']: return
if request.path in ['/public']:
get = get_input()
if 'get_ping' in get: return
if response.status_code in [401]: return
if request.full_path.find('/login?tmp_token=') != 0:
if response.status_code not in [200, 308]: return
else:
if response.status_code not in [302, 301]: return
if secure: samesite = 'None'
if response.status_code not in [200,302]: return
if not request.cookies.get(app.session_cookie_name):
if request.full_path.find('/login?tmp_token=') == 0:
+2
View File
@@ -94,6 +94,8 @@ class panelApi:
return 1
def get_bind_status(self,args):
if not public.cache_get("get_bind_status"):
public.cache_set("get_bind_status",1,60)
bind = self.get_bind_token(args.bind_token)
return bind
+10 -10
View File
@@ -139,7 +139,7 @@ class backup:
if not diskInfo: return '',0,0
_root = None
for d in diskInfo:
if d['path'] == '/':
if d['path'] == '/':
_root = d
continue
if re.match("^{}/.+".format(d['path']),dfile):
@@ -148,7 +148,7 @@ class backup:
return _root['path'],float(_root['size'][2]) * 1024,int(_root['inodes'][2])
return '',0,0
#备份指定目录
#备份指定目录
def backup_path(self,spath,dfile = None,exclude=[],save=3):
error_msg = ""
@@ -166,7 +166,7 @@ class backup:
if not dfile:
fname = 'path_{}_{}.tar.gz'.format(dirname,public.format_date("%Y%m%d_%H%M%S"))
dfile = os.path.join(self._path,'path',fname)
if not self.backup_path_to(spath,dfile,exclude):
if self._error_msg:
error_msg = self._error_msg
@@ -241,7 +241,7 @@ class backup:
self.echo_end()
return dfile
#清理过期备份文件
def delete_old(self,backups,save,data_type = None):
if type(backups) == str:
@@ -299,13 +299,13 @@ class backup:
p_size = public.get_path_size(spath, exclude=exclude_list)
if not self._exclude:
exclude_config = "Not set"
if siteName:
self.echo_info(public.getMsg('BACKUP_SITE',(siteName,)))
self.echo_info(public.getMsg('WEBSITE_DIR',(spath,)))
else:
self.echo_info(public.getMsg('BACKUP_DIR',(spath,)))
self.echo_info(public.getMsg(
"DIR_SIZE",
(str(public.to_size(p_size),))
@@ -513,7 +513,7 @@ class backup:
dfile = os.path.join(self._path,'database',fname)
else:
fname = os.path.basename(dfile)
dpath = os.path.dirname(dfile)
if not os.path.exists(dpath):
os.makedirs(dpath,384)
@@ -529,7 +529,7 @@ class backup:
self.echo_error(error_msg)
self.send_failture_notification(error_msg)
return False
if p_size == None:
error_msg = public.getMsg('DB_BACKUP_ERR',(db_name,))
self.echo_error(error_msg)
@@ -561,7 +561,7 @@ class backup:
self.echo_error(error_msg)
self.send_failture_notification(error_msg)
return False
stime = time.time()
self.echo_info(public.getMsg("EXPORT_DB",(public.format_date(times=stime),)))
if os.path.exists(dfile):
@@ -877,4 +877,4 @@ class backup:
print(e)
return False
+1 -1
View File
@@ -535,7 +535,7 @@ class Dns_com(object):
pass
def get_dns_obj(self):
p_path = '/www/server/panel/plugin/dns'
p_path = '/www/server/panel/plugin/model'
if not os.path.exists(p_path +'/dns_main.py'): return None
sys.path.insert(0,p_path)
import dns_main
+1 -1
View File
@@ -601,7 +601,7 @@ class FPM(object):
'DOCUMENT_ROOT': self.document_root,
'SERVER_PROTOCOL' : 'HTTP/1.1',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '8888',
'REMOTE_PORT': '7800',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'SERVER_NAME': 'BT-Panel'
+78 -67
View File
@@ -159,6 +159,9 @@ class panelPlugin:
def install_plugin(self,get):
if not self.check_sys_write(): return public.returnMsg(False,'CANT_WRITE_SYS_DIR')
if not 'sName' in get: return public.returnMsg(False,'Please specify the software name!')
#处理ols还不支持php81的情况
if get.sName == "php-8.1" and public.get_webserver() == 'openlitespeed':
return public.returnMsg(False, 'Sorry, currently OLS official does not support php8.1')
pluginInfo = self.get_soft_find(get.sName)
get.pluginInfo = pluginInfo
check_result = self.check_install_limit(get)
@@ -314,81 +317,89 @@ class panelPlugin:
#从云端取列表
def get_cloud_list(self,get=None):
lcoalTmp = 'data/plugin.json'
softList = None
listTmp = public.readFile(lcoalTmp)
try:
if listTmp: softList = json.loads(listTmp)
except:
if os.path.exists(lcoalTmp): os.remove(lcoalTmp)
lcoalTmp = 'data/plugin.json'
softList = None
listTmp = public.readFile(lcoalTmp)
force_refresh = 0
try:
if listTmp: softList = json.loads(listTmp)
if 'success' in softList and not softList['success']:
if os.path.exists(lcoalTmp): os.remove(lcoalTmp)
force_refresh = 1
except:
if os.path.exists(lcoalTmp): os.remove(lcoalTmp)
if 'init' in get:
if softList:
if 'success' not in softList:
return softList
if 'init' in get:
if softList:
if 'success' not in softList:
return softList
focre = 0
if hasattr(get,'force'): focre = int(get.force)
if 'focre_cloud' in session:
if session['focre_cloud']:
focre = 1
session['focre_cloud'] = False
focre = 0
if hasattr(get,'force'): focre = int(get.force)
if 'focre_cloud' in session:
if session['focre_cloud']:
focre = 1
session['focre_cloud'] = False
if not 'init_cloud' in session:
if not 'init_cloud' in session:
focre = 1
session['init_cloud'] = True
if not softList or focre > 0:
self.clean_panel_log()
# cloudUrl = 'https://console.aapanel.com/api/panel/get_soft_list'
cloudUrl = '{}/api/panel/getSoftList'.format(self.__official_url)
import panelAuth
import requests
pdata = panelAuth.panelAuth().create_serverid(None)
# listTmp = public.httpPost(cloudUrl,pdata,6)
url_headers={}
if 'token' in pdata:
url_headers = {"authorization": "bt {}".format(pdata['token'])}
pdata['environment_info'] = json.dumps(public.fetch_env_info())
listTmp = requests.post(cloudUrl, params=pdata, headers=url_headers,verify=False)
listTmp=listTmp.json()
if not listTmp:
listTmp = public.readFile(lcoalTmp)
if force_refresh == 1:
focre = 1
if not softList or focre > 0:
self.clean_panel_log()
# cloudUrl = 'https://console.aapanel.com/api/panel/get_soft_list'
cloudUrl = '{}/api/panel/getSoftList'.format(self.__official_url)
import panelAuth
import requests
pdata = panelAuth.panelAuth().create_serverid(None)
# listTmp = public.httpPost(cloudUrl,pdata,6)
url_headers={}
if 'token' in pdata:
url_headers = {"authorization": "bt {}".format(pdata['token'])}
pdata['environment_info'] = json.dumps(public.fetch_env_info())
listTmp = requests.post(cloudUrl, params=pdata, headers=url_headers,verify=False)
listTmp=listTmp.json()
if not listTmp:
listTmp = public.readFile(lcoalTmp)
try:
softList = listTmp
except: pass
if softList: public.writeFile(lcoalTmp,json.dumps(softList))
public.ExecShell('rm -f /tmp/bmac_*')
public.run_thread(self.getCloudPHPExt)
# 专业版和企业版到期提醒,aaPanel目前没有先注释
# self.expire_msg(softList)
try:
softList = listTmp
except: pass
if softList: public.writeFile(lcoalTmp,json.dumps(softList))
public.ExecShell('rm -f /tmp/bmac_*')
public.run_thread(self.getCloudPHPExt)
# 专业版和企业版到期提醒,aaPanel目前没有先注释
# self.expire_msg(softList)
try:
public.writeFile("/tmp/" + cache.get('p_token'),str(softList['pro']))
except:pass
sType = 0
try:
if hasattr(get,'type'): sType = int(get['type'])
public.writeFile("/tmp/" + cache.get('p_token'),str(softList['pro']))
except:pass
sType = 0
try:
if hasattr(get,'type'): sType = int(get['type'])
if hasattr(get,'query'):
if get.query: sType = 0
except:pass
softList['list'] = self.get_local_plugin(softList['list'])
softList['list'] = self.get_types(softList['list'],sType)
if hasattr(get,'query'):
if get.query: sType = 0
except:pass
softList['list'] = self.get_local_plugin(softList['list'])
softList['list'] = self.get_types(softList['list'],sType)
if hasattr(get,'query'):
if get.query:
get.query = get.query.lower()
tmpList = []
for softInfo in softList['list']:
if softInfo['name'].lower().find(get.query) != -1 or \
softInfo['title'].lower().find(get.query) != -1 or \
softInfo['ps'].lower().find(get.query) != -1:
tmpList.append(softInfo)
softList['list'] = tmpList
for softInfo in softList['list']:
if 'uninsatll_checks' not in softInfo:
softInfo['uninsatll_checks'] = softInfo['uninstall_checks']
if not softList['list']:
if os.path.exists(lcoalTmp): os.remove(lcoalTmp)
return softList
if get.query:
get.query = get.query.lower()
tmpList = []
for softInfo in softList['list']:
if softInfo['name'].lower().find(get.query) != -1 or \
softInfo['title'].lower().find(get.query) != -1 or \
softInfo['ps'].lower().find(get.query) != -1:
tmpList.append(softInfo)
softList['list'] = tmpList
for softInfo in softList['list']:
if 'uninsatll_checks' not in softInfo:
softInfo['uninsatll_checks'] = softInfo['uninstall_checks']
if not softList['list']:
if os.path.exists(lcoalTmp): os.remove(lcoalTmp)
return softList
except:
pass
#取提醒标记
def get_level_msg(self,level,s_time,endtime):
+2 -1
View File
@@ -359,7 +359,8 @@ class panelRedirect:
self.SetRedirect(get)
self.SetRedirectNginx(get)
self.SetRedirectApache(get.sitename)
public.serviceReload()
if not hasattr(get,'notreload'):
public.serviceReload()
return public.returnMsg(True, 'EDIT_SUCCESS')
def del_redirect_multiple(self,get):
+388
View File
@@ -0,0 +1,388 @@
#coding: utf-8
#-------------------------------------------------------------------
# 宝塔Linux面板
#-------------------------------------------------------------------
# Copyright (c) 2015-2099 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
# 开机自启模块
#------------------------------
import os,sys,time,json,psutil,re
import public
import signal
class panelRun:
__panel_path = public.get_panel_path()
__run_config_path = '{}/config/run_config'.format(__panel_path)
__run_pids_path = '{}/logs/run_pids'.format(__panel_path)
__run_logs_path = '{}/logs/run_logs'.format(__panel_path)
__log_name = '开机启动项'
def __init__(self):
if not os.path.exists(self.__run_config_path):
os.makedirs(self.__run_config_path)
if not os.path.exists(self.__run_pids_path):
os.makedirs(self.__run_pids_path)
def get_run_list(self,get):
'''
@name 获取启动配置列表
@author hwliang<2021-08-06>
@param get<dict_obj>{
run_type: string<启动类型>
}
@return list
'''
run_type = None
if 'run_type' in get:
run_type = get['run_type']
run_list = []
for run_name in os.listdir(self.__run_config_path):
run_file = '{}/{}'.format(self.__run_config_path,run_name)
if not os.path.isfile(run_file):
continue
run_info = json.loads(public.readFile(run_file))
if run_type:
if run_info['run_type'] != run_type: continue
run_list.append(run_info)
return run_list
def get_run_info(self,get = None,run_name = None):
'''
@name 获取启动配置信息
@author hwliang<2021-08-06>
@param get<dict_obj>{
run_name: string<启动项名称>
}
@return dict
'''
if get: run_name = get['run_name']
run_file = '{}/{}'.format(self.__run_config_path,run_name)
if not os.path.isfile(run_file):
return public.returnMsg(False,'启动配置不存在!')
run_info = json.loads(public.readFile(run_file))
return run_info
def create_run(self,get):
'''
@name 创建启动配置
@author hwliang<2021-08-06>
@param get<dict_obj>{
run_title: string<启动项显示标题>
run_name: string<启动项名称> 格式\w
run_type: string<启动类型> python shell php node java等也可以是一个可执行文件的路径 或直接为空
run_path: string<运行目录>
run_script: string<启动脚本>
run_script_args: string<启动脚本参数>
run_env: list<启动环境变量>
}
@return dict
'''
run_name = get['run_name']
run_title = get['run_title']
run_type = get['run_type']
run_path = get['run_path']
run_script = get['run_script']
run_script_args = get['run_script_args']
run_env = json.loads(get['run_env'])
if not os.path.exists(run_path):
return public.returnMsg(False,'指定运行目录{}不存在!'.format(run_path))
if not re.match(r'^\w+$',run_name):
return public.returnMsg(False, '启动项名称格式不正确,支持:[a-zA-Z0-9_]!')
run_file = '{}/{}'.format(self.__run_config_path,run_name)
if os.path.exists(run_file):
return public.returnMsg(False,'启动配置已存在!')
run_info = {
'run_title': run_title,
'run_name': run_name,
'run_path': run_path,
'run_script': run_script,
'run_env':run_env,
'run_status': 1
}
run_info = json.dumps(run_info)
public.writeFile(run_file,run_info)
public.WriteLog(self.__log_name,'创建启动项[]成功!'.format(run_title))
return public.returnMsg(True,'创建成功!')
def modify_run(self,get):
'''
@name 修改启动配置
@author hwliang<2021-08-06>
@param get<dict_obj>{
run_name: string<启动项名称>
run_title: string<启动项显示标题>
run_type: string<启动类型>
run_path: string<启动路径>
run_script: string<启动脚本>
run_script_args: string<启动脚本参数>
}
@return dict
'''
run_name = get['run_name']
run_title = get['run_title']
run_type = get['run_type']
run_path = get['run_path']
run_script = get['run_script']
run_script_args = get['run_script_args']
run_env = json.loads(get['run_env'])
if not os.path.exists(run_path):
return public.returnMsg(False,'指定运行目录{}不存在!'.format(run_path))
if not re.match(r'^\w+$',run_name):
return public.returnMsg(False, '启动项名称格式不正确,支持:[a-zA-Z0-9_]!')
run_file = '{}/{}'.format(self.__run_config_path,run_name)
if not os.path.exists(run_file):
return public.returnMsg(False,'启动配置不存在!')
run_info = json.loads(public.readFile(run_file))
run_info['run_title'] = run_title
run_info['run_path'] = run_path
run_info['run_script'] = run_script
run_info['run_env'] = run_env
run_info = json.dumps(run_info)
public.writeFile(run_file,run_info)
public.WriteLog(self.__log_name,'修改启动项[]成功!'.format(run_title))
return public.returnMsg(True,'修改成功!')
def remove_run(self,get):
'''
@name 删除启动配置
@author hwliang<2021-08-06>
@param get<dict_obj>{
run_name: string<启动项名称>
}
@return dict
'''
run_name = get['run_name']
run_file = '{}/{}'.format(self.__run_config_path,run_name)
if not os.path.isfile(run_file):
return public.returnMsg(False,'启动配置不存在!')
os.remove(run_file)
public.WriteLog(self.__log_name,'删除启动项[]成功!'.format(run_name))
return public.returnMsg(True,'删除成功!')
def set_run_status(self,get):
'''
@name 设置启动项状态
@author hwliang<2021-08-06>
@param get<dict_obj>{
run_name: string<启动项名称>
run_status: int<启动项状态>
}
@return dict
'''
run_name = get['run_name']
run_status = get['run_status']
run_file = '{}/{}'.format(self.__run_config_path,run_name)
if not os.path.isfile(run_file):
return public.returnMsg(False,'启动配置不存在!')
run_info = json.loads(public.readFile(run_file))
run_info['run_status'] = run_status
run_info = json.dumps(run_info)
public.writeFile(run_file,run_info)
public.WriteLog(self.__log_name,'设置启动项[]状态成功!'.format(run_info['title']))
return public.returnMsg(True,'设置成功!')
def stop_run(self,run_name = None):
'''
@name 关闭启动进程
@author hwliang<2021-08-06>
@param run_name: string<启动项名称>
@return dict
'''
pid = self.get_run_pid(run_name)
if not pid: return True
os.kill(pid,signal.SIGKILL)
public.WriteLog(self.__log_name,'关闭启动项[]成功!'.format(run_name))
return True
def pid_exists(self,pid):
'''
@name 检测PID是否存在
@author hwliang<2021-08-06>
@param pid int<PID>
@return bool
'''
if not isinstance(pid,int):
pid = int(pid)
if pid == 0:
return True
if not os.path.exists('/proc/{}'.format(pid)):
return False
return True
def get_run_pid(self,run_name):
'''
@name 获取启动项PID
@author hwliang<2021-08-06>
@param run_name string<启动项名称>
@return dict
'''
pid_file = '{}/{}.pid'.format(self.__run_pids_path,run_name)
if not os.path.exists(pid_file):
return None
run_pid = int(public.readFile(pid_file))
if run_pid is 0:
return None
if not self.pid_exists(run_pid):
return None
return run_pid
def get_run_status(self,run_name):
'''
@name 获取启动项状态
@author hwliang<2021-08-06>
@param run_name string<启动项名称>
@return dict
'''
pid = self.get_run_pid(run_name)
if not pid: return public.returnMsg(False,'未启动')
process_info = self.get_process_info(pid)
if not process_info: return public.returnMsg(False,'无法获取进程信息')
return process_info
def get_process_info(self,pid):
'''
@name 获取进程信息
@author hwliang<2021-08-06>
@param pid int<PID>
@return dict
'''
process_info = {}
p = psutil.Process(pid)
status_ps = {'sleeping':'睡眠','running':'活动'}
with p.oneshot():
p_mem = p.memory_full_info()
if p_mem.uss + p_mem.rss + p_mem.pss + p_mem.data == 0: return False
pio = p.io_counters()
p_cpus= p.cpu_times()
p_state = p.status()
if p_state in status_ps: p_state = status_ps[p_state]
process_info['exe'] = p.exe()
process_info['name'] = p.name()
process_info['pid'] = pid
process_info['ppid'] = p.ppid()
process_info['create_time'] = int(p.create_time())
process_info['status'] = p_state
process_info['user'] = p.username()
process_info['memory_used'] = p_mem.uss
# process_info['cpu_percent'] = self.get_cpu_percent(str(pid),p_cpus,self.new_info['cpu_time'])
process_info['io_write_bytes'] = pio.write_bytes
process_info['io_read_bytes'] = pio.read_bytes
# process_info['io_write_speed'] = self.get_io_write(str(pid),pio.write_bytes)
# process_info['io_read_speed'] = self.get_io_read(str(pid),pio.read_bytes)
process_info['connects'] = self.get_connects(pid)
process_info['threads'] = p.num_threads()
return process_info
def get_connects(self,pid):
'''
@name 获取进程连接数
@author hwliang<2021-08-06>
@param pid int<PID>
@return dict
'''
connects = 0
if pid == 1: return connects
tp = '/proc/' + str(pid) + '/fd/'
if not os.path.exists(tp): return connects
for d in os.listdir(tp):
fname = tp + d
if os.path.islink(fname):
l = os.readlink(fname)
if l.find('socket:') != -1: connects += 1
return connects
def is_run(self,run_name):
'''
@name 检测启动项是否在运行
@author hwliang<2021-08-06>
@param run_name string<启动项名称>
@return bool
'''
pid = self.get_run_pid(run_name)
if not pid: return False
return True
def get_script_pid(self,run_info):
'''
@name 获取脚本进程PID
@author hwliang<2021-08-06>
@param run_info dict<脚本文件路径>
@return int<PID>
'''
script_last = run_info['run_script'].split(' ')[0]
for pid in psutil.pids():
p = psutil.Process(pid)
if p.exe() == script_last and p.cwd() == run_info['run_path']:
return pid
return None
def start_run(self,run_name):
'''
@name 启动指定启动项
@author hwliang<2021-08-06>
@param run_name string<启动项名称>
@return bool
'''
run_info = self.get_run_info(run_name)
if not run_info: return False
log_file = '{}/{}.log'.format(self.__run_logs_path,run_name)
pid_file = '{}/{}.pid'.format(self.__run_pids_path,run_name)
public.ExecShell("nohup {} 2>&1 >> {} & $! > {}".format(run_info['run_script'],log_file,pid_file),cwd=run_info['run_path'],env=run_info['run_env'])[0]
time.sleep(1)
pid = self.get_script_pid(run_info)
public.writeFile(pid_file,str(pid))
public.WriteLog(self.__log_name, '开机启动{}成功, PID: {}'.format(run_name,pid))
return True
def start(self):
'''
@name 启动所有启动项
@author hwliang<2021-08-06>
@param
@return bool
'''
run_list = self.get_run_list(public.dict_obj())
for run_name in run_list:
if not self.is_run(run_name):
self.start_run(run_name)
return True
+8 -1
View File
@@ -736,6 +736,10 @@ class panelSSL:
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.strf_date(
bytes.decode(x509.get_notAfter())[:-1])
@@ -760,7 +764,10 @@ class panelSSL:
if sub[0] == b'CN':
result['subject'] = sub[1].decode()
break
result['dns'].append(result['subject'])
# result['dns'].append(result['subject'])
if 'subject' in result:
result['dns'].append(result['subject'])
else:
result['subject'] = result['dns'][0]
return result
+8 -5
View File
@@ -1890,7 +1890,8 @@ listener SSL443 {
import firewalls
get.port = '443'
get.ps = 'HTTPS'
firewalls.firewalls().AddAcceptPort(get)
if not public.M('firewall').where('port=?', ('443',)).count():
firewalls.firewalls().AddAcceptPort(get)
public.serviceReload()
self.save_cert(get)
public.WriteLog('TYPE_SITE', 'SITE_SSL_OPEN_SUCCESS', (siteName,))
@@ -2974,13 +2975,13 @@ server
#取当前可用PHP版本
def GetPHPVersion(self,get):
phpVersions = ('00','other','52','53','54','55','56','70','71','72','73','74','80')
phpVersions = ('00','other','52','53','54','55','56','70','71','72','73','74','80','81')
httpdVersion = ""
filename = self.setupPath + '/apache/version.pl'
if os.path.exists(filename): httpdVersion = public.readFile(filename).strip()
if httpdVersion == '2.2': phpVersions = ('00','52','53','54')
if httpdVersion == '2.4': phpVersions = ('00','other','53','54','55','56','70','71','72','73','74','80')
if httpdVersion == '2.4': phpVersions = ('00','other','53','54','55','56','70','71','72','73','74','80','81')
if os.path.exists('/www/server/nginx/sbin/nginx'):
cfile = '/www/server/nginx/conf/enable-php-00.conf'
if not os.path.exists(cfile): public.writeFile(cfile,'')
@@ -3647,7 +3648,8 @@ RewriteRule ^%s(.*)$ http://%s/$1 [P,E=Proxy-Host:%s]
if public.get_webserver() == 'nginx':
if self.CheckLocation(get):
return self.CheckLocation(get)
if not get.proxysite.split('//')[-1]:
return public.returnMsg(False, 'The target URL cannot be [http:// or https://], please fill in the full URL, such as: https://aapanel.com')
proxyUrl = self.__read_config(self.__proxyfile)
proxyUrl.append({
"proxyname": get.proxyname,
@@ -3890,7 +3892,8 @@ RewriteRule ^%s(.*)$ http://%s/$1 [P,E=Proxy-Host:%s]
# if int(get.type) != 1:
# os.system("mv %s %s_bak" % (ap_conf_file, ap_conf_file))
# os.system("mv %s %s_bak" % (ng_conf_file, ng_conf_file))
public.serviceReload()
if not hasattr(get, 'notreload'):
public.serviceReload()
return public.returnMsg(True, 'EDIT_SUCCESS')
# 设置反向代理
+27 -22
View File
@@ -613,7 +613,7 @@ def GetHost(port = False):
try:
if host_tmp.find(':') == -1: host_tmp += ':80'
except:
host_tmp = "127.0.0.1:8888"
host_tmp = "127.0.0.1:7800"
h = host_tmp.split(':')
if port: return h[-1]
if len(h) > 2:
@@ -621,9 +621,15 @@ def GetHost(port = False):
return h
return h[0]
def GetClientIp():
from flask import request
return request.remote_addr.replace('::ffff:', '')
ipaddr = request.remote_addr.replace('::ffff:','')
if not check_ip(ipaddr): return '未知IP地址'
return ipaddr
def get_client_ip():
return GetClientIp()
@@ -1044,7 +1050,7 @@ def checkIp(ip):
#检查端口是否合法
def checkPort(port):
if not re.match("^\d+$",port): return False
ports = ['21','25','443','8080','888','8888','8443']
ports = ['21','25','443','8080','888','8888','8443','7800']
if port in ports: return False
intport = int(port)
if intport < 1 or intport > 65535: return False
@@ -1254,7 +1260,7 @@ def CheckPort(port,other=None):
if type(port) == str: port = int(port)
if port < 1 or port > 65535: return False
if other:
checks = [22, 20, 21, 8888, 3306, 11211, 888, 25]
checks = [22, 20, 21, 8888, 3306, 11211, 888, 25,7800]
if port in checks: return False
return True
@@ -1823,12 +1829,12 @@ def check_ip_panel():
for limit_ip in iplong_list:
if client_ip_long >= limit_ip['min'] and client_ip_long <= limit_ip['max']:
return False
errorStr = ReadFile('./BTPanel/templates/' + GetConfigValue('template') + '/error2.html')
try:
errorStr = errorStr.format(getMsg('PAGE_ERR_TITLE'),getMsg('PAGE_ERR_IP_H1'),getMsg('PAGE_ERR_IP_P1',(GetClientIp(),)),getMsg('PAGE_ERR_IP_P2'),getMsg('PAGE_ERR_IP_P3'),getMsg('NAME'),getMsg('PAGE_ERR_HELP'))
except IndexError:pass
return errorStr
return 404
# errorStr = ReadFile('./BTPanel/templates/' + GetConfigValue('template') + '/error2.html')
# try:
# errorStr = errorStr.format(getMsg('PAGE_ERR_TITLE'),getMsg('PAGE_ERR_IP_H1'),getMsg('PAGE_ERR_IP_P1',(GetClientIp(),)),getMsg('PAGE_ERR_IP_P2'),getMsg('PAGE_ERR_IP_P3'),getMsg('NAME'),getMsg('PAGE_ERR_HELP'))
# except IndexError:pass
# return errorStr
#检查面板域名
def check_domain_panel():
@@ -1838,11 +1844,12 @@ def check_domain_panel():
client_ip = GetClientIp()
if client_ip in ['127.0.0.1','localhost','::1']: return False
if tmp.strip().lower() != domain.strip().lower():
errorStr = ReadFile('./BTPanel/templates/' + GetConfigValue('template') + '/error2.html')
try:
errorStr = errorStr.format(getMsg('PAGE_ERR_TITLE'),getMsg('PAGE_ERR_DOMAIN_H1'),getMsg('PAGE_ERR_DOMAIN_P1'),getMsg('PAGE_ERR_DOMAIN_P2'),getMsg('PAGE_ERR_DOMAIN_P3'),getMsg('NAME'),getMsg('PAGE_ERR_HELP'))
except:pass
return errorStr
return 404
# errorStr = ReadFile('./BTPanel/templates/' + GetConfigValue('template') + '/error2.html')
# try:
# errorStr = errorStr.format(getMsg('PAGE_ERR_TITLE'),getMsg('PAGE_ERR_DOMAIN_H1'),getMsg('PAGE_ERR_DOMAIN_P1'),getMsg('PAGE_ERR_DOMAIN_P2'),getMsg('PAGE_ERR_DOMAIN_P3'),getMsg('NAME'),getMsg('PAGE_ERR_HELP'))
# except:pass
# return errorStr
return False
#是否离线模式
@@ -3054,13 +3061,8 @@ def check_app(check='app'):
path=get_panel_path() + '/'
if check=='app':
try:
if not os.path.exists(path+'data/user.json') and os.path.exists(path+'config/api.json') and not os.path.exists(path+'plugin/app/user.json'):return False
if os.path.exists(path+'plugin/app/user.json'):
wxapp = json.loads(readFile(path+'plugin/app/user.json'))
if wxapp:return True
if os.path.exists(path+'data/user.json'):
app_info = json.loads(readFile(path+'data/user.json'))
if app_info:return True
if not os.path.exists("/www/server/panel/plugin/btapp/btapp_main.py"): return False
if not os.path.exists(path+'config/api.json'):return False
if os.path.exists(path+'config/api.json'):
btapp_info = json.loads(readFile(path+'config/api.json'))
if not btapp_info['open']:return False
@@ -3071,6 +3073,8 @@ def check_app(check='app'):
except:
return False
elif check=='app_bind':
if not cache_get('get_bind_status'):return False
if not os.path.exists("/www/server/panel/plugin/btapp/btapp_main.py"):return False
if not os.path.exists(path + 'config/api.json'):return False
btapp_info = json.loads(readFile(path +'config/api.json'))
if not btapp_info: return False
@@ -3082,6 +3086,7 @@ def check_app(check='app'):
if not app_info: return False
return True
#宝塔邮件报警
def send_mail(title,body,is_logs=False,is_type="aapanel login reminder"):
if is_logs:
+1 -1
View File
@@ -37,7 +37,7 @@ def check_run():
'''
if public.M('crontab').where('sType=? AND sName=?',('database','ALL')).count():
return True,'无风险'
return True,'Risk-free'
db_list = public.M('databases').field('name').select()
+1 -1
View File
@@ -63,4 +63,4 @@ def check_run():
return True,'Fail2ban is enabled'
except: pass
return False,'当前MySQL端口: {},可被任意服务器访问,这可能导致MySQL被暴力破解,存在安全隐患'.format(port_tmp[0])
return False,'MySQL port: {}, can be accessed by any server, which may cause MySQL to be cracked by brute force, posing security risks'.format(port_tmp[0])
+1 -1
View File
@@ -37,7 +37,7 @@ def check_run():
port = public.readFile(port_file)
if not port: return True,'Rick-free'
port = int(port)
if port != 8888:
if port != 8888 and port != 7800:
return True,'Rick-free'
return False,'The panel port is the default port ({}), which may cause unnecessary security risks'.format(port)
+1 -1
View File
@@ -49,7 +49,7 @@ def check_run():
if not is_strong_password(redis_pass):
return False, 'Redis access password is too simple, and there are security risks'
return True,'无风险'
return True,'Risk-free'
def is_strong_password(password):
+3 -1
View File
@@ -71,7 +71,7 @@ class setPanelLets:
return public.returnMsg(False, "Failed to apply for a certificate, please try to manually apply for a certificate for the panel domain name on the site management page")
get.key = cert_info['private_key']
get.csr = cert_info['cert'] + cert_info['root']
return self._deploy_cert(get)
return public.returnMsg(True, self._deploy_cert(get))
# 部署证书
def _deploy_cert(self,get):
@@ -223,6 +223,8 @@ class setPanelLets:
return public.returnMsg(True, 'Panel lets set successfully')
if not create_site:
create_lets = self.__create_lets(get)
if not create_lets['status']:
return create_lets
if create_lets['msg']:
domain_cert = self.__check_cert_dir(get)
self.copy_cert(domain_cert)
+14 -14
View File
@@ -14,7 +14,7 @@ def main():
CLOUDFLARE_EMAIL=example@example.com \
CLOUDFLARE_API_KEY=api-key \
sewer \
--dns cloudflare \
--model cloudflare \
--domain example.com \
--action run
@@ -23,7 +23,7 @@ def main():
CLOUDFLARE_API_KEY=api-key \
sewer \
--account_key /path/to/your/account.key \
--dns cloudflare \
--model cloudflare \
--domain example.com \
--action renew
"""
@@ -34,7 +34,7 @@ def main():
CLOUDFLARE_EMAIL=example@example.com \
CLOUDFLARE_API_KEY=api-key \
sewer \
--dns cloudflare \
--model cloudflare \
--domain example.com \
--action run""",
)
@@ -59,7 +59,7 @@ def main():
eg: --certificate_key /home/mycertificate.key",
)
parser.add_argument(
"--dns",
"--model",
type=str,
required=True,
choices=[
@@ -72,7 +72,7 @@ def main():
"dnspod",
"duckdns",
],
help="The name of the dns provider that you want to use.",
help="The name of the model provider that you want to use.",
)
parser.add_argument(
"--domain",
@@ -195,7 +195,7 @@ def main():
dns_class = CloudFlareDns(
CLOUDFLARE_EMAIL=CLOUDFLARE_EMAIL, CLOUDFLARE_API_KEY=CLOUDFLARE_API_KEY
)
logger.info("chosen_dns_provider. Using {0} as dns provider.".format(dns_provider))
logger.info("chosen_dns_provider. Using {0} as model provider.".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
@@ -210,7 +210,7 @@ def main():
dns_class = AuroraDns(
AURORA_API_KEY=AURORA_API_KEY, AURORA_SECRET_KEY=AURORA_SECRET_KEY
)
logger.info("chosen_dns_provider. Using {0} as dns provider.".format(dns_provider))
logger.info("chosen_dns_provider. Using {0} as model provider.".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
@@ -228,7 +228,7 @@ def main():
ACME_DNS_API_KEY=ACME_DNS_API_KEY,
ACME_DNS_API_BASE_URL=ACME_DNS_API_BASE_URL,
)
logger.info("chosen_dns_provider. Using {0} as dns provider.".format(dns_provider))
logger.info("chosen_dns_provider. Using {0} as model provider.".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
@@ -240,7 +240,7 @@ def main():
aliyun_secret = os.environ["ALIYUN_AK_SECRET"]
aliyun_endpoint = os.environ.get("ALIYUN_ENDPOINT", "cn-beijing")
dns_class = AliyunDns(aliyun_ak, aliyun_secret, aliyun_endpoint)
logger.info("chosen_dns_provider. Using {0} as dns provider.".format(dns_provider))
logger.info("chosen_dns_provider. Using {0} as model provider.".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
@@ -251,7 +251,7 @@ def main():
he_username = os.environ["HURRICANE_USERNAME"]
he_password = os.environ["HURRICANE_PASSWORD"]
dns_class = HurricaneDns(he_username, he_password)
logger.info("chosen_dns_provider. Using {0} as dns provider.".format(dns_provider))
logger.info("chosen_dns_provider. Using {0} as model provider.".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
@@ -262,7 +262,7 @@ def main():
RACKSPACE_USERNAME = os.environ["RACKSPACE_USERNAME"]
RACKSPACE_API_KEY = os.environ["RACKSPACE_API_KEY"]
dns_class = RackspaceDns(RACKSPACE_USERNAME, RACKSPACE_API_KEY)
logger.info("chosen_dns_prover. Using {0} as dns provider. ".format(dns_provider))
logger.info("chosen_dns_prover. Using {0} as model provider. ".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
@@ -273,7 +273,7 @@ def main():
DNSPOD_ID = os.environ["DNSPOD_ID"]
DNSPOD_API_KEY = os.environ["DNSPOD_API_KEY"]
dns_class = DNSPodDns(DNSPOD_ID, DNSPOD_API_KEY)
logger.info("chosen_dns_prover. Using {0} as dns provider. ".format(dns_provider))
logger.info("chosen_dns_prover. Using {0} as model provider. ".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
@@ -284,12 +284,12 @@ def main():
duckdns_token = os.environ["DUCKDNS_TOKEN"]
dns_class = DuckDNSDns(duckdns_token=duckdns_token)
logger.info("chosen_dns_provider. Using {0} as dns provider.".format(dns_provider))
logger.info("chosen_dns_provider. Using {0} as model provider.".format(dns_provider))
except KeyError as e:
logger.error("ERROR:: Please supply {0} as an environment variable.".format(str(e)))
raise
else:
raise ValueError("The dns provider {0} is not recognised.".format(dns_provider))
raise ValueError("The model provider {0} is not recognised.".format(dns_provider))
client = Client(
domain_name=domain,
+3 -3
View File
@@ -291,7 +291,7 @@ class Client(object):
self.logger.info("apply_for_cert_issuance")
identifiers = []
for domain_name in self.all_domain_names:
identifiers.append({"type": "dns", "value": domain_name})
identifiers.append({"type": "model", "value": domain_name})
payload = {"identifiers": identifiers}
url = self.ACME_NEW_ORDER_URL
@@ -354,7 +354,7 @@ class Client(object):
domain = "*." + domain
for i in res["challenges"]:
if i["type"] == "dns-01":
if i["type"] == "model-01":
dns_challenge = i
dns_token = dns_challenge["token"]
dns_challenge_url = dns_challenge["url"]
@@ -684,7 +684,7 @@ class Client(object):
)
# for a case where you want certificates for *.example.com and example.com
# you have to create both dns records AND then respond to the challenge.
# you have to create both model records AND then respond to the challenge.
# see issues/83
for i in responders:
# Make sure the authorization is in a status where we can submit a challenge
+2 -2
View File
@@ -62,7 +62,7 @@ class AcmeDnsDns(common.BaseDns):
# raise error so that we do not continue to make calls to ACME
# server
raise ValueError(
"Error creating acme-dns dns record: status_code={status_code} response={response}".format(
"Error creating acme-model model record: status_code={status_code} response={response}".format(
status_code=update_acmedns_dns_record_response.status_code,
response=self.log_response(update_acmedns_dns_record_response),
)
@@ -71,5 +71,5 @@ class AcmeDnsDns(common.BaseDns):
def delete_dns_record(self, domain_name, domain_dns_value):
self.logger.info("delete_dns_record")
# acme-dns doesn't support this
# acme-model doesn't support this
self.logger.info("delete_dns_record_success")
+3 -3
View File
@@ -31,7 +31,7 @@ class _ResponseForAliyun(object):
class AliyunDns(common.BaseDns):
def __init__(self, key, secret, endpoint="cn-beijing", debug=False):
"""
aliyun dns client
aliyun model client
:param str key: access key
:param str secret: access sceret
:param str endpoint: endpoint
@@ -162,7 +162,7 @@ class AliyunDns(common.BaseDns):
def create_dns_record(self, domain_name, domain_dns_value):
"""
create a dns record
create a model record
:param str domain_name: the value sewer client passed in, like *.menduo.example.com
:param str domain_dns_value: the value sewer client passed in.
:return _ResponseForAliyun:
@@ -200,7 +200,7 @@ class AliyunDns(common.BaseDns):
self.logger.warning(msg)
return
self.logger.info("start to delete dns record, id: %s", record_id)
self.logger.info("start to delete model record, id: %s", record_id)
request = DeleteDomainRecordRequest.DeleteDomainRecordRequest()
request.set_RecordId(record_id)
+7 -7
View File
@@ -29,10 +29,10 @@ class BaseDns(object):
def create_dns_record(self, domain_name, domain_dns_value):
"""
Method that creates/adds a dns TXT record for a domain/subdomain name on
Method that creates/adds a model TXT record for a domain/subdomain name on
a chosen DNS provider.
:param domain_name: :string: The domain/subdomain name whose dns record ought to be
:param domain_name: :string: The domain/subdomain name whose model record ought to be
created/added on a chosen DNS provider.
:param domain_dns_value: :string: The value/content of the TXT record that will be
created/added for the given domain/subdomain
@@ -46,16 +46,16 @@ class BaseDns(object):
whose name is '_acme-challenge' + '.' + domain_name + '.' (ie: _acme-challenge.example.com. )
and whose value/content is HAJA_4MkowIFByHhFaP8u035skaM91lTKplKld
Using a dns client like dig(https://linux.die.net/man/1/dig) to do a dns lookup should result
Using a model client like dig(https://linux.die.net/man/1/dig) to do a model lookup should result
in something like:
dig TXT _acme-challenge.example.com
...
;; ANSWER SECTION:
_acme-challenge.example.com. 120 IN TXT "HAJA_4MkowIFByHhFaP8u035skaM91lTKplKld"
_acme-challenge.singularity.brandur.org. 120 IN TXT "9C0DqKC_4MkowIFByHhFaP8u0Zv4z7Wz2IHM91lTKec"
Optionally, you may also use an online dns client like: https://toolbox.googleapps.com/apps/dig/#TXT/
Optionally, you may also use an online model client like: https://toolbox.googleapps.com/apps/dig/#TXT/
Please consult your dns provider on how/format of their DNS TXT records.
Please consult your model provider on how/format of their DNS TXT records.
You may also want to consult the cloudflare DNS implementation that is found in this repository.
"""
self.logger.info("create_dns_record")
@@ -63,10 +63,10 @@ class BaseDns(object):
def delete_dns_record(self, domain_name, domain_dns_value):
"""
Method that deletes/removes a dns TXT record for a domain/subdomain name on
Method that deletes/removes a model TXT record for a domain/subdomain name on
a chosen DNS provider.
:param domain_name: :string: The domain/subdomain name whose dns record ought to be
:param domain_name: :string: The domain/subdomain name whose model record ought to be
deleted/removed on a chosen DNS provider.
:param domain_dns_value: :string: The value/content of the TXT record that will be
deleted/removed for the given domain/subdomain
+1 -1
View File
@@ -62,7 +62,7 @@ class DNSPodDns(common.BaseDns):
# raise error so that we do not continue to make calls to ACME
# server
raise ValueError(
"Error creating dnspod dns record: status_code={status_code} response={response}".format(
"Error creating dnspod model record: status_code={status_code} response={response}".format(
status_code=create_dnspod_dns_record_response["status"]["code"],
response=create_dnspod_dns_record_response["status"]["message"],
)
+1 -1
View File
@@ -49,7 +49,7 @@ class DuckDNSDns(common.BaseDns):
# raise error so that we do not continue to make calls to DuckDNS
# server
raise ValueError(
"Error creating DuckDNS dns record: status_code={status_code} response={response}".format(
"Error creating DuckDNS model record: status_code={status_code} response={response}".format(
status_code=update_duckdns_dns_record_response.status_code,
response=normalized_response,
)
+11 -11
View File
@@ -47,11 +47,11 @@ class RackspaceDns(common.BaseDns):
data = find_rackspace_api_details_response.json()
api_token = data["access"]["token"]["id"]
url_data = next(
(item for item in data["access"]["serviceCatalog"] if item["type"] == "rax:dns"), None
(item for item in data["access"]["serviceCatalog"] if item["type"] == "rax:model"), None
)
if url_data is None:
raise ValueError(
"Error finding url data for the rackspace dns api in the response from the identity server"
"Error finding url data for the rackspace model api in the response from the identity server"
)
else:
api_base_url = url_data["endpoints"][0]["publicURL"] + "/"
@@ -91,7 +91,7 @@ class RackspaceDns(common.BaseDns):
)
if find_dns_zone_id_response.status_code != 200:
raise ValueError(
"Error getting rackspace dns domain info: status_code={status_code} response={response}".format(
"Error getting rackspace model domain info: status_code={status_code} response={response}".format(
status_code=find_dns_zone_id_response.status_code,
response=self.log_response(find_dns_zone_id_response),
)
@@ -102,7 +102,7 @@ class RackspaceDns(common.BaseDns):
)
if domain_data is None:
raise ValueError(
"Error finding information for {dns_zone} in dns response data:\n{response_data})".format(
"Error finding information for {dns_zone} in model response data:\n{response_data})".format(
dns_zone=self.RACKSPACE_DNS_ZONE,
response_data=self.log_response(find_dns_zone_id_response),
)
@@ -124,7 +124,7 @@ class RackspaceDns(common.BaseDns):
self.logger.debug(url)
if find_dns_record_id_response.status_code != 200:
raise ValueError(
"Error finding dns records for {dns_zone}: status_code={status_code} response={response}".format(
"Error finding model records for {dns_zone}: status_code={status_code} response={response}".format(
dns_zone=self.RACKSPACE_DNS_ZONE,
status_code=find_dns_record_id_response.status_code,
response=self.log_response(find_dns_record_id_response),
@@ -152,21 +152,21 @@ class RackspaceDns(common.BaseDns):
callback_url_response = requests.get(callback_url, headers=self.RACKSPACE_HEADERS)
if time.time() > start_time + self.HTTP_TIMEOUT:
raise ValueError(
"Timed out polling callbackurl for dns record status. Last status_code={status_code} last response={response}".format(
"Timed out polling callbackurl for model record status. Last status_code={status_code} last response={response}".format(
status_code=callback_url_response.status_code,
response=self.log_response(callback_url_response),
)
)
if callback_url_response.status_code != 200:
raise Exception(
"Could not get dns record status from callback url. Status code ={status_code}. response={response}".format(
"Could not get model record status from callback url. Status code ={status_code}. response={response}".format(
status_code=callback_url_response.status_code,
response=self.log_response(callback_url_response),
)
)
if callback_url_response.json()["status"] == "ERROR":
raise Exception(
"Error in creating/deleting dns record: status_Code={status_code}. response={response}".format(
"Error in creating/deleting model record: status_Code={status_code}. response={response}".format(
status_code=callback_url_response.status_code,
response=self.log_response(callback_url_response),
)
@@ -196,13 +196,13 @@ class RackspaceDns(common.BaseDns):
)
if create_rackspace_dns_record_response.status_code != 202:
raise ValueError(
"Error creating rackspace dns record: status_code={status_code} response={response}".format(
"Error creating rackspace model record: status_code={status_code} response={response}".format(
status_code=create_rackspace_dns_record_response.status_code,
response=create_rackspace_dns_record_response.text,
)
)
# response=self.log_response(create_rackspace_dns_record_response)))
# After posting the dns record we want created, the response gives us a url to check that will
# After posting the model record we want created, the response gives us a url to check that will
# update when the job is done
callback_url = create_rackspace_dns_record_response.json()["callbackUrl"]
self.poll_callback_url(callback_url)
@@ -228,7 +228,7 @@ class RackspaceDns(common.BaseDns):
)
if delete_dns_record_response.status_code != 202:
raise ValueError(
"Error deleting rackspace dns record: status_code={status_code} response={response}".format(
"Error deleting rackspace model record: status_code={status_code} response={response}".format(
status_code=delete_dns_record_response.status_code,
response=self.log_response(delete_dns_record_response),
)
+8 -8
View File
@@ -252,7 +252,7 @@ class ACMEclient(object):
print("Apply for a certificate")
identifiers = []
for domain_name in self.all_domain_names:
identifiers.append({"type": "dns", "value": domain_name})
identifiers.append({"type": "model", "value": domain_name})
payload = {"identifiers": identifiers}
url = self.ACME_NEW_ORDER_URL
apply_for_cert_issuance_response = self.make_signed_acme_request(url=url, payload=payload)
@@ -299,7 +299,7 @@ class ACMEclient(object):
if wildcard:
domain = "*." + domain
for i in res["challenges"]:
if i["type"] == "dns-01":
if i["type"] == "model-01":
dns_challenge = i
dns_token = dns_challenge["token"]
dns_challenge_url = dns_challenge["url"]
@@ -364,7 +364,7 @@ class ACMEclient(object):
if authorization_status in desired_status:
break
else:
print("Failed to verify dns txt wait {} seconds to re-verify dns, returned information".format(self.ACME_AUTH_STATUS_WAIT_PERIOD))
print("Failed to verify model txt wait {} seconds to re-verify model, returned information".format(self.ACME_AUTH_STATUS_WAIT_PERIOD))
print(check_authorization_status_response.json())
public.WriteFile(os.path.join(ssl_home_path, "check_authorization_status_response"), check_authorization_status_response.text, mode="w")
# 等待
@@ -806,7 +806,7 @@ class AliyunDns(object):
msg = public.GetMsg("CANT_FIND_RECORDID"), domain_name
print(msg)
return
print("start to delete dns record, id: ", record_id)
print("start to delete model record, id: ", record_id)
randomint = random.randint(11111111111111, 99999999999999)
now = datetime.datetime.utcnow()
otherStyleTime = now.strftime("%Y-%m-%dT%H:%M:%SZ")
@@ -901,7 +901,7 @@ class Dns_com(object):
def create_dns_record(self, domain_name, domain_dns_value):
root, _, acme_txt = extract_zone(domain_name)
print("create_dns_record,", acme_txt, domain_dns_value)
result = public.ExecShell('''{} /www/server/panel/plugin/dns/dns_main.py add_txt {} {}'''.format(public.get_python_bin(),acme_txt + '.' + root, domain_dns_value))
result = public.ExecShell('''{} /www/server/panel/plugin/model/dns_main.py add_txt {} {}'''.format(public.get_python_bin(),acme_txt + '.' + root, domain_dns_value))
if result[0].strip() == "False":
sys.exit(json.dumps({"data": public.GetMsg("BT_DNSRES_ERR")}))
print("create_dns_record_end")
@@ -909,7 +909,7 @@ class Dns_com(object):
def delete_dns_record(self, domain_name, domain_dns_value):
root, _, acme_txt = extract_zone(domain_name)
print("delete_dns_record start: ", acme_txt, domain_dns_value)
public.ExecShell('''{} /www/server/panel/plugin/dns/dns_main.py remove_txt {} {}'''.format(public.get_python_bin() ,acme_txt + '.' + root, domain_dns_value))
public.ExecShell('''{} /www/server/panel/plugin/model/dns_main.py remove_txt {} {}'''.format(public.get_python_bin() ,acme_txt + '.' + root, domain_dns_value))
print("delete_dns_record_success")
@@ -939,9 +939,9 @@ if __name__ == "__main__":#dns调用验证脚本
dns_class = AliyunDns(key=key, secret=secret)
elif dnsapi == "dns_cx": # CloudXns
dns_class = CloudxnsDns(key=key, secret=secret)
elif dnsapi == "dns_bt": # dns.com
elif dnsapi == "dns_bt": # model.com
dns_class = Dns_com()
elif dnsapi == "dns": # 手动的
elif dnsapi == "model": # 手动的
dns_class = Dns_Manual()
Manual = 1
domain_alt_names = data['domain_alt_names'].split(",")
+2
View File
@@ -62,6 +62,8 @@ class SiteDirAuth:
:param get:
:return:
'''
if len(get.username) < 3 or len(get.password) < 3:
return public.returnMsg(False, 'The account number or password cannot be less than 3 characters')
name = get.name
site_dir = get.site_dir
if public.get_webserver() == "openlitespeed":
+5 -1
View File
@@ -182,11 +182,15 @@ class ssh_security:
################## SSH 登陆报警设置 ####################################
def send_mail_data(self,title,body,type='mail'):
import threading
if type=='mail':
if self.__mail_config['user_mail']['user_name']:
if len(self.__mail_config['user_mail']['mail_list'])>=1:
for i in self.__mail_config['user_mail']['mail_list']:
self.__mail.qq_smtp_send(i, title, body)
t = threading.Thread(target=self.__mail.qq_smtp_send,args=(i, title, body))
t.setDaemon(True)
t.start()
# self.__mail.qq_smtp_send(i, title, body)
elif type=='dingding':
if self.__mail_config['dingding']['dingding']:
self.__mail.dingding_send(title+body)
+2 -1
View File
@@ -411,6 +411,8 @@ class system:
for tmp in temp1:
n += 1
try:
if ',' in tmp:
tmp = re.sub(',\d+','',tmp)
inodes = tempInodes1[n-1].split()
disk = re.findall(r"^(.+)\s+([\w\.]+)\s+([\w\.]+)\s+([\w\.]+)\s+([\w\.]+)\s+([\d%]{2,4})\s+(/.{0,100})$",tmp.strip())
if disk: disk = disk[0]
@@ -902,7 +904,6 @@ class system:
public.ExecShell('/etc/init.d/nginx start')
if get.type != 'test':
public.WriteLog("TYPE_SOFT", 'SYS_EXEC_SUCCESS',(execStr,))
if len(result[1]) > 1 and get.name != 'pure-ftpd' and get.name != 'redis': return public.returnMsg(False, '<p>Warning message: <p>' + result[1].replace('\n','<br>'))
return public.returnMsg(True,'SYS_EXEC_SUCCESS')
+7 -6
View File
@@ -177,12 +177,13 @@ class userlogin:
domain = public.readFile('data/domain.conf')
if domain:
if(public.GetHost().lower() != domain.strip().lower()):
errorStr = public.ReadFile('./BTPanel/templates/' + public.GetConfigValue('template') + '/error2.html')
try:
errorStr = errorStr.format(public.getMsg('PAGE_ERR_TITLE'),public.getMsg('PAGE_ERR_DOMAIN_H1'),public.getMsg('PAGE_ERR_DOMAIN_P1'),public.getMsg('PAGE_ERR_DOMAIN_P2'),public.getMsg('PAGE_ERR_DOMAIN_P3'),public.getMsg('NAME'),public.getMsg('PAGE_ERR_HELP'))
except IndexError:pass
return errorStr
if(public.GetHost().lower() != domain.strip().lower()):
return 404
# errorStr = public.ReadFile('./BTPanel/templates/' + public.GetConfigValue('template') + '/error2.html')
# try:
# errorStr = errorStr.format(public.getMsg('PAGE_ERR_TITLE'),public.getMsg('PAGE_ERR_DOMAIN_H1'),public.getMsg('PAGE_ERR_DOMAIN_P1'),public.getMsg('PAGE_ERR_DOMAIN_P2'),public.getMsg('PAGE_ERR_DOMAIN_P3'),public.getMsg('NAME'),public.getMsg('PAGE_ERR_HELP'))
# except IndexError:pass
# return errorStr
if os.path.exists('data/limitip.conf'):
iplist = public.readFile('data/limitip.conf')
if iplist:
+4 -2
View File
@@ -30,7 +30,7 @@ class wxapp():
def is_scan_ok(self, get):
if os.path.exists(self.app_path+"app_login_check.pl"):
key, init_time = public.readFile(self.app_path+'app_login_check.pl').split(':')
if time.time() - float(init_time) > 180:
if time.time() - float(init_time) > 60:
return public.returnMsg(False, 'QRCORE_EXPIRE')
session_id = public.get_session_id()
if cache.get(session_id) == 'True':
@@ -70,7 +70,9 @@ class wxapp():
secret_key, init_time = data.split(':')
if len(session_id)!=64:return public.returnMsg(False,'Waiting for APP scan code login 2')
if len(secret_key)!=64:return public.returnMsg(False,'Waiting for APP scan code login 2')
if time.time() - float(init_time) < 180 and session_id != secret_key:
if time.time() - float(init_time) > 60:
return public.returnMsg(False,'Waiting for APP scan code login')
if session_id != secret_key:
return public.returnMsg(False,'Waiting for APP scan code login')
cache.delete(session_id)
userInfo = public.M('users').where("id=?",(1,)).field('id,username').find()