mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-09-08 02:27:54 +02:00
update to 6.8.27
This commit is contained in:
+325
-181
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/python
|
||||
#coding: utf-8
|
||||
# coding: utf-8
|
||||
# -------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
# -------------------------------------------------------------------
|
||||
@@ -18,21 +18,22 @@ import binascii
|
||||
import hashlib
|
||||
import base64
|
||||
import json
|
||||
import copy
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
|
||||
os.chdir('/www/server/panel')
|
||||
if not 'class/' in sys.path:
|
||||
sys.path.insert(0,'class/')
|
||||
sys.path.insert(0, 'class/')
|
||||
import http_requests as requests
|
||||
|
||||
requests.DEFAULT_TYPE = 'curl'
|
||||
import public
|
||||
|
||||
try:
|
||||
import OpenSSL
|
||||
except:
|
||||
public.ExecShell("pip install -I pyopenssl")
|
||||
public.ExecShell("btpip install -I pyOpenSSL")
|
||||
import OpenSSL
|
||||
try:
|
||||
import dns.resolver
|
||||
@@ -40,6 +41,7 @@ except:
|
||||
public.ExecShell("pip install dnspython")
|
||||
import dns.resolver
|
||||
|
||||
|
||||
class acme_v2:
|
||||
_url = None
|
||||
_apis = None
|
||||
@@ -89,7 +91,7 @@ class acme_v2:
|
||||
result = res.json()
|
||||
if "type" in result:
|
||||
if result['type'] == 'urn:acme:error:serverInternal':
|
||||
raise Exception(public.getMsg('ACME_MSG_ERR'))
|
||||
raise Exception(public.get_msg_gettext('Service shutdown or internal error due to maintenance, check [ https://letsencrypt.status.io ] see for more details.'))
|
||||
if not os.path.exists('/www/server/panel/data/http_type.pl'):
|
||||
public.writeFile('/www/server/panel/data/http_type.pl','python')
|
||||
self.get_apis()
|
||||
@@ -125,19 +127,19 @@ class acme_v2:
|
||||
self.set_crond()
|
||||
return account
|
||||
except Exception as ex:
|
||||
return public.returnMsg(False,str(ex))
|
||||
return public.return_msg_gettext(False,str(ex))
|
||||
|
||||
# 设置帐户信息
|
||||
def set_account_info(self, args):
|
||||
if not 'account' in self._config:
|
||||
return public.returnMsg(False, 'ACME_ACCOUNT_ERR')
|
||||
return public.return_msg_gettext(False, 'The specified account does not exist')
|
||||
account = json.loads(args.account)
|
||||
if 'email' in account:
|
||||
self._config['email'] = account['email']
|
||||
del(account['email'])
|
||||
self._config['account'][self._mod_index[self._debug]] = account
|
||||
self.save_config()
|
||||
return public.returnMsg(True, 'ACME_SUCCESS_ACCOUNT_SETUP')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
# 获取订单列表
|
||||
def get_orders(self, args):
|
||||
@@ -153,19 +155,19 @@ class acme_v2:
|
||||
# 删除订单
|
||||
def remove_order(self, args):
|
||||
if not 'orders' in self._config:
|
||||
return public.returnMsg(False, 'ACME_ORDER_NOT_EXIST')
|
||||
return public.return_msg_gettext(False, 'The specified order does not exist!')
|
||||
if not args.index in self._config['orders']:
|
||||
return public.returnMsg(False, 'ACME_ORDER_NOT_EXIST')
|
||||
return public.return_msg_gettext(False, 'The specified order does not exist!')
|
||||
del(self._config['orders'][args.index])
|
||||
self.save_config()
|
||||
return public.returnMsg(True, 'ACME_DEL_ODER_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Order deleted successfully!')
|
||||
|
||||
# 取指定订单数据
|
||||
def get_order_find(self, args):
|
||||
if not 'orders' in self._config:
|
||||
return public.returnMsg(False, 'ACME_ORDER_NOT_EXIST')
|
||||
return public.return_msg_gettext(False, 'The specified order does not exist!')
|
||||
if not args.index in self._config['orders']:
|
||||
return public.returnMsg(False, 'ACME_ORDER_NOT_EXIST')
|
||||
return public.return_msg_gettext(False, 'The specified order does not exist!')
|
||||
result = self._config['orders'][args.index]
|
||||
result['cert'] = self.get_cert_info(args.index)
|
||||
return result
|
||||
@@ -186,27 +188,27 @@ class acme_v2:
|
||||
if not os.path.exists(path): # 尝试重新下载证书
|
||||
self.download_cert(args.index)
|
||||
if not os.path.exists(path):
|
||||
return public.returnMsg(False, 'ACME_GET_CERT_ERR')
|
||||
return public.return_msg_gettext(False, 'Certificate read failed, directory does not exist!')
|
||||
import panelTask
|
||||
bt_task = panelTask.bt_task()
|
||||
zip_file = path+'/cert.zip'
|
||||
result = bt_task._zip(path, '.', path+'/cert.zip', '/dev/null', 'zip')
|
||||
if not os.path.exists(zip_file):
|
||||
return result
|
||||
return public.returnMsg(True, zip_file)
|
||||
return public.return_msg_gettext(True, zip_file)
|
||||
|
||||
# 吊销证书
|
||||
def revoke_order(self, index):
|
||||
if type(index) != str:
|
||||
index = index.index
|
||||
if not index in self._config['orders']:
|
||||
raise Exception(public.getMsg('ACME_ORDER_NOT_EXIST'))
|
||||
raise Exception(public.get_msg_gettext('The specified order does not exist!'))
|
||||
cert_path = self._config['orders'][index]['save_path']
|
||||
if not os.path.exists(cert_path):
|
||||
raise Exception(public.getMsg('ACME_CERT_ERR'))
|
||||
raise Exception(public.get_msg_gettext('No certificate found for the specified order!'))
|
||||
cert = self.dump_der(cert_path)
|
||||
if not cert:
|
||||
raise Exception(public.getMsg('ACME_CERT_READ_ERR'))
|
||||
raise Exception(public.get_msg_gettext('Certificate read failed!'))
|
||||
payload = {
|
||||
"certificate": self.calculate_safe_base64(cert),
|
||||
"reason": 4
|
||||
@@ -217,7 +219,7 @@ class acme_v2:
|
||||
public.ExecShell("rm -rf {}".format(cert_path))
|
||||
del(self._config['orders'][index])
|
||||
self.save_config()
|
||||
return public.returnMsg(True, "Certificate revoked!")
|
||||
return public.return_msg_gettext(True, "Certificate revoked!")
|
||||
return res.json()
|
||||
|
||||
# 取根域名和记录值
|
||||
@@ -320,7 +322,7 @@ class acme_v2:
|
||||
def create_order(self, domains, auth_type, auth_to, index=None):
|
||||
domains = self.format_domains(domains)
|
||||
if not domains:
|
||||
raise Exception(public.getMsg('ACME_DOMAIN_ERR'))
|
||||
raise Exception(public.get_msg_gettext('Need at least a domain name!'))
|
||||
# 构造标识
|
||||
identifiers = []
|
||||
for domain_name in domains:
|
||||
@@ -348,7 +350,7 @@ class acme_v2:
|
||||
a_auth = res.json()
|
||||
ret_title = self.get_error(str(a_auth))
|
||||
raise StopIteration(
|
||||
"{0} >>>> {1}".format(
|
||||
"{} >>>> {}".format(
|
||||
ret_title,
|
||||
json.dumps(a_auth)
|
||||
)
|
||||
@@ -365,7 +367,7 @@ class acme_v2:
|
||||
# 获取验证信息
|
||||
def get_auths(self, index):
|
||||
if not index in self._config['orders']:
|
||||
raise Exception(public.getMsg('ACME_ORDER_NOT_EXIST'))
|
||||
raise Exception(public.get_msg_gettext('The specified order does not exist!'))
|
||||
|
||||
# 检查是否已经获取过授权信息
|
||||
if 'auths' in self._config['orders'][index]:
|
||||
@@ -447,7 +449,7 @@ class acme_v2:
|
||||
if not self._config['orders'][index]['auth_type'] in ['http','tls']:
|
||||
return True
|
||||
acme_path = '{}/.well-known/acme-challenge'.format(self._config['orders'][index]['auth_to'])
|
||||
write_log(public.getMsg('ACME_V_DIR',(acme_path,)))
|
||||
write_log(public.get_msg_gettext('|-Verify the dir:{}',(acme_path,)))
|
||||
if os.path.exists(acme_path):
|
||||
public.ExecShell("rm -f {}/*".format(acme_path))
|
||||
acme_path = '/www/server/stop/.well-known/acme-challenge'
|
||||
@@ -476,7 +478,7 @@ class acme_v2:
|
||||
except:
|
||||
err = public.get_error_info()
|
||||
print(err)
|
||||
raise Exception(public.getMsg('ACME_WRITE_V_FILE_ERR',(err,)))
|
||||
raise Exception(public.get_msg_gettext('Writing verification file failed: {}',(err,)))
|
||||
|
||||
# 解析域名
|
||||
def create_dns_record(self, auth_to, domain, dns_value):
|
||||
@@ -507,7 +509,7 @@ class acme_v2:
|
||||
key = dc['data'][0]['value']
|
||||
secret = dc['data'][1]['value']
|
||||
except:
|
||||
raise Exception(public.getMsg('ACME_DNS_API_ERR'))
|
||||
raise Exception(public.get_msg_gettext('No valid DNSAPI key information found'))
|
||||
else:
|
||||
key = tmp[1]
|
||||
secret = tmp[2]
|
||||
@@ -526,7 +528,7 @@ class acme_v2:
|
||||
# 验证域名
|
||||
def auth_domain(self, index):
|
||||
if not index in self._config['orders']:
|
||||
raise Exception(public.getMsg('ACME_ORDER_NOT_EXIST'))
|
||||
raise Exception(public.get_msg_gettext('The specified order does not exist!'))
|
||||
|
||||
# 开始验证
|
||||
for auth in self._config['orders'][index]['auths']:
|
||||
@@ -553,7 +555,7 @@ class acme_v2:
|
||||
number_of_checks = 0
|
||||
while True:
|
||||
if desired_status == ['valid', 'invalid']:
|
||||
write_log(public.getMsg('ACME_QUERY_V_RESULT',(str(number_of_checks + 1),)))
|
||||
write_log(public.get_msg_gettext('|-{} Query verification results..',(str(number_of_checks + 1),)))
|
||||
time.sleep(self._wait_time)
|
||||
check_authorization_status_response = self.acme_request(url, "")
|
||||
a_auth = check_authorization_status_response.json()
|
||||
@@ -561,7 +563,7 @@ class acme_v2:
|
||||
number_of_checks += 1
|
||||
if authorization_status in desired_status:
|
||||
if authorization_status == "invalid":
|
||||
write_log("|-"+public.getMsg('VERIFICATION_FAILED'))
|
||||
write_log("|-"+public.get_msg_gettext('Verification failed'))
|
||||
try:
|
||||
if 'error' in a_auth['challenges'][0]:
|
||||
ret_title = a_auth['challenges'][0]['error']['detail']
|
||||
@@ -575,7 +577,7 @@ class acme_v2:
|
||||
except:
|
||||
ret_title = str(a_auth)
|
||||
raise StopIteration(
|
||||
"{0} >>>> {1}".format(
|
||||
"{} >>>> {}".format(
|
||||
ret_title,
|
||||
json.dumps(a_auth)
|
||||
)
|
||||
@@ -584,75 +586,75 @@ class acme_v2:
|
||||
|
||||
if number_of_checks == self._max_check_num:
|
||||
raise StopIteration(
|
||||
public.getMsg('ACME_V_TIMES',(
|
||||
public.get_msg_gettext('Error: Attempted verification {} times. The maximum number of verifications is {}. The verification interval is {} seconds.',(
|
||||
str(number_of_checks),
|
||||
str(self._max_check_num),
|
||||
str(self._wait_time)
|
||||
)))
|
||||
if desired_status == ['valid', 'invalid']:
|
||||
write_log(public.getMsg('ACME_V_SUCCESS'))
|
||||
write_log(public.get_msg_gettext('|-Verification succeeded!'))
|
||||
return check_authorization_status_response
|
||||
|
||||
# 格式化错误输出
|
||||
def get_error(self, error):
|
||||
if error.find("Max checks allowed") >= 0:
|
||||
return public.getMsg('ACME_ERR_MSG1')
|
||||
return public.get_msg_gettext('CA cannot verify your domain name, please check if the domain name resolution is correct, or wait 5-10 minutes and try again.')
|
||||
elif error.find("Max retries exceeded with") >= 0 or error.find('status_code=0 ') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG2')
|
||||
return public.get_msg_gettext('CA server connection timed out, please try again later.')
|
||||
elif error.find("The domain name belongs") >= 0:
|
||||
return public.getMsg('ACME_ERR_MSG3')
|
||||
return public.get_msg_gettext('The domain name does not belong to this DNS service provider, please make sure the domain name is filled in correctly.')
|
||||
elif error.find('login token ID is invalid') >= 0:
|
||||
return public.getMsg('ACME_ERR_MSG4')
|
||||
return public.get_msg_gettext('DNS server connection failed, please check if the key is correct.')
|
||||
elif error.find('Error getting validation data') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG5')
|
||||
return public.get_msg_gettext('Data validation failed and the CA was unable to get the correct captcha from the authenticated connection.')
|
||||
elif "too many certificates already issued for exact set of domains" in error:
|
||||
return public.getMsg('ACME_ERR_MSG6',(str(re.findall("exact set of domains: (.+):", error)),))
|
||||
return public.get_msg_gettext('Issuing failed, the domain {} has exceeded the limit of weekly reissues!',(str(re.findall("exact set of domains: (.+):", error)),))
|
||||
elif "Error creating new account :: too many registrations for this IP" in error:
|
||||
return public.getMsg('ACME_ERR_MSG7')
|
||||
return public.get_msg_gettext('Issuing failed, the current server IP has reached the limit of creating up to 10 accounts every 3 hours.')
|
||||
elif "DNS problem: NXDOMAIN looking up A for" in error:
|
||||
return public.getMsg('ACME_ERR_MSG8')
|
||||
return public.get_msg_gettext('Validation failed, domain name was not resolved, or resolution did not take effect!')
|
||||
elif "Invalid response from" in error:
|
||||
return public.getMsg('ACME_ERR_MSG9')
|
||||
return public.get_msg_gettext('Verification failed, domain name resolution error or verification URL cannot be accessed!')
|
||||
elif error.find('TLS Web Server Authentication') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG10')
|
||||
return public.get_msg_gettext('Connection to CA server failed, please try again later.')
|
||||
elif error.find('Name does not end in a public suffix') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG11',(str(re.findall("Cannot issue for \"(.+)\":", error)),))
|
||||
return public.get_msg_gettext('Unsupported domain name {}, please check the domain name is correct!',(str(re.findall("Cannot issue for \"(.+)\":", error)),))
|
||||
elif error.find('No valid IP addresses found for') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG12',(str(re.findall("No valid IP addresses found for (.+)", error)),))
|
||||
return public.get_msg_gettext('No resolution record was found for domain name {}, please check if the domain name resolution takes effect!',(str(re.findall("No valid IP addresses found for (.+)", error)),))
|
||||
elif error.find('No TXT record found at') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG13',(str(re.findall("No TXT record found at (.+)", error)),))
|
||||
return public.get_msg_gettext('No valid TXT resolution record was found in the domain name {}, please check whether the TXT record is parsed correctly. If it is applied by DNSAPI, please try again in 10 minutes!',(str(re.findall("No TXT record found at (.+)", error)),))
|
||||
elif error.find('Incorrect TXT record') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG14',(str(re.findall("found at (.+)", error)), str(re.findall("Incorrect TXT record \"(.+)\"", error))))
|
||||
return public.get_msg_gettext('A wrong TXT record was found on {}: {}, please check whether the TXT resolution is correct, if it is applied by DNSAPI, please try again in 10 minutes!',(str(re.findall("found at (.+)", error)), str(re.findall("Incorrect TXT record \"(.+)\"", error))))
|
||||
elif error.find('Domain not under you or your user') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG15')
|
||||
return public.get_msg_gettext('This domain name does not exist under this dnspod account, adding resolution failed!')
|
||||
elif error.find('SERVFAIL looking up TXT for') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG16',(str(re.findall("looking up TXT for (.+)", error)),))
|
||||
return public.get_msg_gettext('No valid TXT resolution record was found in the domain name {}, please check whether the TXT record is parsed correctly. If it is applied by DNSAPI, please try again in 10 minutes!',(str(re.findall("looking up TXT for (.+)", error)),))
|
||||
elif error.find('Timeout during connect') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG17')
|
||||
return public.get_msg_gettext('The connection timed out and the CA server was unable to access your website!')
|
||||
elif error.find("DNS problem: SERVFAIL looking up CAA for") != -1:
|
||||
return public.getMsg('ACME_ERR_MSG18',(str(re.findall("looking up CAA for (.+)", error)),))
|
||||
return public.get_msg_gettext('Domain name {} is currently required to verify the CAA record, please parse the CAA record manually, or retry the application after 1 hour!',(str(re.findall("looking up CAA for (.+)", error)),))
|
||||
elif error.find("Read timed out.") != -1:
|
||||
return public.getMsg('ACME_ERR_MSG19')
|
||||
return public.get_msg_gettext('The verification timed out. Please check if the domain name is resolved correctly. If it is resolved correctly, the connection between the server and LetsEncrypt may be abnormal. Please try again later!')
|
||||
elif error.find('Cannot issue for') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG20',(str(re.findall(r'for\s+"(.+)"',error)),))
|
||||
return public.get_msg_gettext('Cannot issue a certificate for {}, cannot apply for a wildcard certificate with a domain name suffix directly!',(str(re.findall(r'for\s+"(.+)"',error)),))
|
||||
elif error.find('too many failed authorizations recently'):
|
||||
return public.getMsg('ACME_ERR_MSG21')
|
||||
return public.get_msg_gettext('The account has more than 5 failed orders within 1 hour, please wait 1 hour and try again!')
|
||||
elif error.find("Error creating new order") != -1:
|
||||
return public.getMsg('ACME_ERR_MSG22')
|
||||
return public.get_msg_gettext('Order creation failed, please try again later!')
|
||||
elif error.find("Too Many Requests") != -1:
|
||||
return public.getMsg('ACME_ERR_MSG23')
|
||||
return public.get_msg_gettext('More than 5 verification failures in 1 hour, the application is temporarily banned, please try again later!')
|
||||
elif error.find('HTTP Error 400: Bad Request') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG24')
|
||||
return public.get_msg_gettext('CA server denied access, please try again later!')
|
||||
elif error.find('Temporary failure in name resolution') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG25')
|
||||
return public.get_msg_gettext('The DNS of the server is faulty and the domain name cannot be resolved. Please use the Linux toolbox to check the DNS configuration')
|
||||
elif error.find('Too Many Requests') != -1:
|
||||
return public.getMsg('ACME_ERR_MSG26')
|
||||
return public.get_msg_gettext('Too many requests for this domain name. Please try again 3 hours later')
|
||||
else:
|
||||
return error
|
||||
|
||||
# 发送验证请求
|
||||
def respond_to_challenge(self, auth):
|
||||
payload = {"keyAuthorization": "{0}".format(
|
||||
payload = {"keyAuthorization": "{}".format(
|
||||
auth['acme_keyauthorization'])}
|
||||
respond_to_challenge_response = self.acme_request(
|
||||
auth['dns_challenge_url'], payload)
|
||||
@@ -666,7 +668,7 @@ class acme_v2:
|
||||
url=self._config['orders'][index]['finalize'], payload=payload)
|
||||
if send_csr_response.status_code not in [200, 201]:
|
||||
raise ValueError(
|
||||
public.getMsg('ACME_SEND_CSR_ERR',(send_csr_response.status_code,send_csr_response.json()))
|
||||
public.get_msg_gettext('Error: Sending CSR: Response status {} Response value: {}',(send_csr_response.status_code,send_csr_response.json()))
|
||||
)
|
||||
send_csr_response_json = send_csr_response.json()
|
||||
certificate_url = send_csr_response_json["certificate"]
|
||||
@@ -689,7 +691,7 @@ class acme_v2:
|
||||
res = self.acme_request(
|
||||
self._config['orders'][index]['certificate_url'], "")
|
||||
if res.status_code not in [200, 201]:
|
||||
raise Exception(public.getMsg('ACME_CERT_DOWNLOAD_ERR',(str(res.json()),)))
|
||||
raise Exception(public.get_msg_gettext('Failed to download certificate: {}',(str(res.json()),)))
|
||||
|
||||
pem_certificate = res.content
|
||||
if type(pem_certificate) == bytes:
|
||||
@@ -781,8 +783,10 @@ fullchain.pem Paste into certificate input box
|
||||
# 获取目标证书的基本信息
|
||||
to_cert_init = self.get_cert_init(to_pem_file)
|
||||
# 判断证书品牌是否一致
|
||||
if to_cert_init['issuer'] != cert_init['issuer'] and to_cert_init['issuer'].find("Let's Encrypt") == -1:
|
||||
continue
|
||||
try:
|
||||
if to_cert_init['issuer'] != cert_init['issuer'] and to_cert_init['issuer'].find("Let's Encrypt") == -1 and to_cert_init['issuer'] != 'R3':
|
||||
continue
|
||||
except: continue
|
||||
# 判断目标证书的到期时间是否较早
|
||||
if to_cert_init['notAfter'] > cert_init['notAfter']:
|
||||
continue
|
||||
@@ -802,7 +806,7 @@ fullchain.pem Paste into certificate input box
|
||||
public.writeFile(
|
||||
to_key_file, public.readFile(key_file, 'rb'), 'wb')
|
||||
public.writeFile(to_info, json.dumps(cert_init))
|
||||
write_log(public.getMsg('ACME_CERT_REPLACE',(to_path,)))
|
||||
write_log(public.get_msg_gettext('|-Detected that the certificate under {} overlaps with the certificate of this application and has an earlier expiration time, and has been replaced with a new certificate!',(to_path,)))
|
||||
# 重载web服务
|
||||
public.serviceReload()
|
||||
if is_panel: public.restart_panel()
|
||||
@@ -818,7 +822,7 @@ fullchain.pem Paste into certificate input box
|
||||
for domain in self._config['orders'][index]['domains']:
|
||||
if domain in cert_init['dns']:
|
||||
return index
|
||||
if cert_init['issuer'].find("Let's Encrypt") != -1:
|
||||
if cert_init['issuer'].find("Let's Encrypt") != -1 or cert_init['issuer'] == 'R3':
|
||||
return pem_file
|
||||
return None
|
||||
except: return None
|
||||
@@ -828,10 +832,10 @@ fullchain.pem Paste into certificate input box
|
||||
if not os.path.exists(args.pem_file):
|
||||
args.pem_file = 'vhost/cert/{}/fullchain.pem'.format(args.siteName)
|
||||
if not os.path.exists(args.pem_file):
|
||||
return public.returnMsg(False, 'ACME_CERT_FILE_ERR')
|
||||
return public.return_msg_gettext(False, 'The specified certificate file does not exist!')
|
||||
cert_init = self.get_cert_init(args.pem_file)
|
||||
if not cert_init:
|
||||
return public.returnMsg(False, 'ACME_CERT_GET_CERTINFO_ERR')
|
||||
return public.return_msg_gettext(False, 'Certificate information acquisition failed!')
|
||||
cert_init['dnsapi'] = json.loads(public.readFile(self._dnsapi_file))
|
||||
return cert_init
|
||||
|
||||
@@ -922,7 +926,7 @@ fullchain.pem Paste into certificate input box
|
||||
|
||||
# 检查DNS记录
|
||||
def check_dns(self, domain, value, s_type='TXT'):
|
||||
write_log(public.getMsg('ACME_CHECK_DNS',(domain, s_type, value)))
|
||||
write_log(public.get_msg_gettext('|-Attempt to verify DNS records locally, domain name: {}, type: {} record value: {}',(domain, s_type, value)))
|
||||
time.sleep(10)
|
||||
n = 0
|
||||
while n < 20:
|
||||
@@ -933,9 +937,9 @@ fullchain.pem Paste into certificate input box
|
||||
for j in ns.response.answer:
|
||||
for i in j.items:
|
||||
txt_value = i.to_text().replace('"', '').strip()
|
||||
write_log(public.getMsg('ACME_CHECK_DNS1',(str(n),txt_value)))
|
||||
write_log(public.get_msg_gettext('|-Number of verifications: {}, value: {}',(str(n),txt_value)))
|
||||
if txt_value == value:
|
||||
write_log(public.getMsg('ACME_CHECK_DNS2'))
|
||||
write_log(public.get_msg_gettext('|-Local authentication succeeded!'))
|
||||
return True
|
||||
except:
|
||||
try:
|
||||
@@ -943,7 +947,7 @@ fullchain.pem Paste into certificate input box
|
||||
except:
|
||||
return False
|
||||
time.sleep(3)
|
||||
write_log(public.getMsg('ACME_CHECK_DNS3'))
|
||||
write_log(public.get_msg_gettext('|-Local authentication failed!'))
|
||||
return True
|
||||
|
||||
# 创建CSR
|
||||
@@ -954,11 +958,11 @@ fullchain.pem Paste into certificate input box
|
||||
X509Req = OpenSSL.crypto.X509Req()
|
||||
X509Req.get_subject().CN = domain_name
|
||||
if domain_alt_names:
|
||||
SAN = "DNS:{0}, ".format(domain_name).encode("utf8") + ", ".join(
|
||||
SAN = "DNS:{}, ".format(domain_name).encode("utf8") + ", ".join(
|
||||
"DNS:" + i for i in domain_alt_names
|
||||
).encode("utf8")
|
||||
else:
|
||||
SAN = "DNS:{0}".format(domain_name).encode("utf8")
|
||||
SAN = "DNS:{}".format(domain_name).encode("utf8")
|
||||
|
||||
X509Req.add_extensions(
|
||||
[
|
||||
@@ -984,7 +988,7 @@ fullchain.pem Paste into certificate input box
|
||||
acme_thumbprint = self.calculate_safe_base64(
|
||||
hashlib.sha256(acme_header_jwk_json.encode("utf8")).digest()
|
||||
)
|
||||
acme_keyauthorization = "{0}.{1}".format(token, acme_thumbprint)
|
||||
acme_keyauthorization = "{}.{}".format(token, acme_thumbprint)
|
||||
base64_of_acme_keyauthorization = self.calculate_safe_base64(
|
||||
hashlib.sha256(acme_keyauthorization.encode("utf8")).digest()
|
||||
)
|
||||
@@ -994,7 +998,7 @@ fullchain.pem Paste into certificate input box
|
||||
# 构造验证信息
|
||||
def get_identifier_auth(self, index, url, auth_info):
|
||||
s_type = self.get_auth_type(index)
|
||||
write_log(public.getMsg('ACME_BUILD_AUTH',(s_type,)))
|
||||
write_log(public.get_msg_gettext('|-Verification type: {}',(s_type,)))
|
||||
domain = auth_info['identifier']['value']
|
||||
wildcard = False
|
||||
# 处理通配符
|
||||
@@ -1019,7 +1023,7 @@ fullchain.pem Paste into certificate input box
|
||||
# 获取域名验证方式
|
||||
def get_auth_type(self, index):
|
||||
if not index in self._config['orders']:
|
||||
raise Exception(public.getMsg('ACME_ORDER_NOT_EXIST'))
|
||||
raise Exception(public.get_msg_gettext('The specified order does not exist!'))
|
||||
s_type = 'http-01'
|
||||
if 'auth_type' in self._config['orders'][index]:
|
||||
if self._config['orders'][index]['auth_type'] == 'dns':
|
||||
@@ -1087,7 +1091,7 @@ fullchain.pem Paste into certificate input box
|
||||
elif self._config['email']:
|
||||
payload = {
|
||||
"termsOfServiceAgreed": True,
|
||||
"contact": ["mailto:{0}".format(self._config['email'])],
|
||||
"contact": ["mailto:{}".format(self._config['email'])],
|
||||
}
|
||||
else:
|
||||
payload = {"termsOfServiceAgreed": True}
|
||||
@@ -1095,7 +1099,7 @@ fullchain.pem Paste into certificate input box
|
||||
res = self.acme_request(url=self._apis['newAccount'], payload=payload)
|
||||
|
||||
if res.status_code not in [201, 200, 409]:
|
||||
raise Exception(public.getMsg('ACME_REGISTERED_ERR',(str(res.json()),)))
|
||||
raise Exception(public.get_msg_gettext('Registration for ACME account failed: {}',(str(res.json()),)))
|
||||
kid = res.headers["Location"]
|
||||
return kid
|
||||
|
||||
@@ -1111,7 +1115,7 @@ fullchain.pem Paste into certificate input box
|
||||
protected = self.get_acme_header(url)
|
||||
protected64 = self.calculate_safe_base64(json.dumps(protected))
|
||||
signature = self.sign_message(
|
||||
message="{0}.{1}".format(protected64, payload64)) # bytes
|
||||
message="{}.{}".format(protected64, payload64)) # bytes
|
||||
signature64 = self.calculate_safe_base64(signature) # str
|
||||
data = json.dumps(
|
||||
{"protected": protected64, "payload": payload64,
|
||||
@@ -1172,7 +1176,7 @@ fullchain.pem Paste into certificate input box
|
||||
public_key_public_numbers = private_key.public_key().public_numbers()
|
||||
|
||||
exponent = "{0:x}".format(public_key_public_numbers.e)
|
||||
exponent = "0{0}".format(exponent) if len(
|
||||
exponent = "0{}".format(exponent) if len(
|
||||
exponent) % 2 else exponent
|
||||
modulus = "{0:x}".format(public_key_public_numbers.n)
|
||||
jwk = {
|
||||
@@ -1268,23 +1272,25 @@ fullchain.pem Paste into certificate input box
|
||||
index = None
|
||||
if 'index' in args:
|
||||
index = args['index']
|
||||
if 'auto_wildcard' in args:
|
||||
self._auto_wildcard = 1
|
||||
if not index: # 判断是否只想验证域名
|
||||
write_log(public.getMsg('ACME_CREAT_ORDER'))
|
||||
write_log(public.get_msg_gettext('|-Creating order..'))
|
||||
index = self.create_order(domains, auth_type, auth_to)
|
||||
write_log(public.getMsg('ACME_GET_V'))
|
||||
write_log(public.get_msg_gettext('|-Getting verification information..'))
|
||||
self.get_auths(index)
|
||||
if auth_to == 'dns' and len(self._config['orders'][index]['auths']) > 0:
|
||||
return self._config['orders'][index]
|
||||
write_log(public.getMsg('ACME_V_DOMAIN'))
|
||||
write_log(public.get_msg_gettext('|-Verifying domain name..'))
|
||||
self.auth_domain(index)
|
||||
self.remove_dns_record()
|
||||
write_log(public.getMsg('ACME_SEND_CSR'))
|
||||
write_log(public.get_msg_gettext('|-Sending CSR..'))
|
||||
self.send_csr(index)
|
||||
write_log(public.getMsg('ACME_DOWNLOAD_CERT'))
|
||||
write_log(public.get_msg_gettext('|-Downloading certificate..'))
|
||||
cert = self.download_cert(index)
|
||||
cert['status'] = True
|
||||
cert['msg'] = public.getMsg('ACME_APPLY_SUCCESS')
|
||||
write_log(public.getMsg('ACME_APPLY_SUCCESS1'))
|
||||
cert['msg'] = public.get_msg_gettext('Application successful!')
|
||||
write_log(public.get_msg_gettext('|-Successful application, deploying to site..'))
|
||||
return cert
|
||||
except Exception as ex:
|
||||
self.remove_dns_record()
|
||||
@@ -1295,7 +1301,7 @@ fullchain.pem Paste into certificate input box
|
||||
else:
|
||||
msg = ex
|
||||
write_log(public.get_error_info())
|
||||
return public.returnMsg(False, msg)
|
||||
return public.return_msg_gettext(False, msg)
|
||||
|
||||
# 申请证书 - api
|
||||
def apply_cert_api(self, args):
|
||||
@@ -1307,7 +1313,7 @@ fullchain.pem Paste into certificate input box
|
||||
try:
|
||||
project_info = json.loads(project_info)
|
||||
if not 'ssl_path' in project_info:
|
||||
return public.returnMsg(False, 'There is a problem with the current Java project configuration file, please rebuild')
|
||||
return public.return_msg_gettext(False, 'There is a problem with the current Java project configuration file, please rebuild')
|
||||
if not os.path.exists(project_info['ssl_path']):
|
||||
os.makedirs(project_info['ssl_path'])
|
||||
path = project_info['ssl_path']
|
||||
@@ -1319,7 +1325,7 @@ fullchain.pem Paste into certificate input box
|
||||
self._auto_wildcard = True
|
||||
return self.apply_cert(json.loads(args.domains), args.auth_type, args.auth_to)
|
||||
except:
|
||||
return public.returnMsg(False, 'There is a problem with the current Java project configuration file, please rebuild')
|
||||
return public.return_msg_gettext(False, 'There is a problem with the current Java project configuration file, please rebuild')
|
||||
else:
|
||||
if re.match(r"^\d+$", args.auth_to):
|
||||
import panelSite
|
||||
@@ -1330,7 +1336,7 @@ fullchain.pem Paste into certificate input box
|
||||
args.auth_to = args.auth_to[:-1]
|
||||
|
||||
if not os.path.exists(args.auth_to):
|
||||
return public.returnMsg(False, 'ACME_DIR_ERR')
|
||||
return public.return_msg_gettext(False, 'Invalid site directory, please check if the specified site exists!')
|
||||
|
||||
check_result = self.check_auth_env(args, check=True)
|
||||
if check_result: return check_result
|
||||
@@ -1423,8 +1429,8 @@ fullchain.pem Paste into certificate input box
|
||||
return
|
||||
for domain in json.loads(args.domains):
|
||||
if public.checkIp(domain): continue
|
||||
if domain.find('*.') >=0 and args.auth_type in ['http','tls']:
|
||||
raise public.returnMsg(False, 'ACME_PAN_DOMAIN_ERR')
|
||||
if domain.find('*.') != -1 and args.auth_type in ['http','tls']:
|
||||
raise public.return_msg_gettext(False, 'Pan domain names cannot apply for a certificate using [File Verification]!')
|
||||
import panelSite
|
||||
s = panelSite.panelSite()
|
||||
if args.auth_type in ['http','tls']:
|
||||
@@ -1460,7 +1466,7 @@ fullchain.pem Paste into certificate input box
|
||||
s.ModifyRedirect(args)
|
||||
redirect_tmp[args.sitename].append(x['redirectname'])
|
||||
else:
|
||||
if x['type']: return public.returnMsg(False, 'SITE_SSL_ERR_301')
|
||||
if x['type']: return public.return_msg_gettext(False, 'Your site has 301 Redirect on,Please turn it off first!')
|
||||
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)
|
||||
@@ -1486,13 +1492,13 @@ fullchain.pem Paste into certificate input box
|
||||
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 x['type']: return public.return_msg_gettext(False,'Sites with reverse proxy turned on cannot apply for SSL!')
|
||||
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')
|
||||
return public.return_msg_gettext(False,'The website has been redirected, please close it before applying!')
|
||||
#判断是否强制HTTPS
|
||||
if s.IsToHttps(args.siteName):
|
||||
if os.path.exists(self._stop_rp_file):
|
||||
@@ -1501,14 +1507,14 @@ fullchain.pem Paste into certificate input box
|
||||
s.CloseToHttps(args)
|
||||
public.writeFile('{}/data/stop_httptohttps.pl'.format(public.get_panel_path()), '')
|
||||
else:
|
||||
return public.returnMsg(False, 'ACME_FORCE_SSL_ERR')
|
||||
return public.return_msg_gettext(False, 'After configuring Force HTTPS, you cannot use [File Verification] to apply for a certificate!')
|
||||
public.serviceReload()
|
||||
except:
|
||||
return False
|
||||
else:
|
||||
if args.auth_to.find('Dns_com') != -1:
|
||||
if not os.path.exists('plugin/dns/dns_main.py'):
|
||||
return public.returnMsg(False, 'ACME_DNS_ERR')
|
||||
return public.return_msg_gettext(False, 'Please go to the software store to install [cloud analysis], and complete the domain name NS binding.')
|
||||
return False
|
||||
|
||||
# DNS手动验证
|
||||
@@ -1601,6 +1607,138 @@ fullchain.pem Paste into certificate input box
|
||||
site_status = public.M('sites').where('id=?', (site_id,)).field('status').select()[0]['status']
|
||||
return site_status
|
||||
|
||||
def get_index(self, domains):
|
||||
'''
|
||||
@name 获取标识
|
||||
@author hwliang<2022-02-10>
|
||||
@param domains<list> 域名列表
|
||||
@return string
|
||||
'''
|
||||
identifiers = []
|
||||
for domain_name in domains:
|
||||
identifiers.append({"type": 'dns', "value": domain_name})
|
||||
return public.md5(json.dumps(identifiers))
|
||||
|
||||
# 续签同品牌其它证书
|
||||
def renew_cert_other(self):
|
||||
'''
|
||||
@name 续签同品牌其它证书
|
||||
@author hwliang<2022-02-10>
|
||||
@return void
|
||||
'''
|
||||
cert_path = "{}/vhost/cert".format(public.get_panel_path())
|
||||
if not os.path.exists(cert_path): return
|
||||
new_time = time.time() + (86400 * 30)
|
||||
n = 0
|
||||
if not 'orders' in self._config: self._config['orders'] = {}
|
||||
import panelSite
|
||||
siteObj = panelSite.panelSite()
|
||||
args = public.dict_obj()
|
||||
for siteName in os.listdir(cert_path):
|
||||
try:
|
||||
cert_file = '{}/{}/fullchain.pem'.format(cert_path, siteName)
|
||||
if not os.path.exists(cert_file): continue # 无证书文件
|
||||
siteInfo = public.M('sites').where('name=?', siteName).find()
|
||||
if not siteInfo: continue # 无网站信息
|
||||
cert_init = self.get_cert_init(cert_file)
|
||||
if not cert_init: continue # 无法获取证书
|
||||
end_time = time.mktime(time.strptime(cert_init['notAfter'], '%Y-%m-%d'))
|
||||
if end_time > new_time: continue # 未到期
|
||||
try:
|
||||
if not cert_init['issuer'] in ['R3', "Let's Encrypt"] and cert_init['issuer'].find(
|
||||
"Let's Encrypt") == -1:
|
||||
continue # 非同品牌证书
|
||||
except:
|
||||
continue
|
||||
|
||||
if isinstance(cert_init['dns'], str): cert_init['dns'] = [cert_init['dns']]
|
||||
index = self.get_index(cert_init['dns'])
|
||||
if index in self._config['orders'].keys(): continue # 已在订单列表
|
||||
|
||||
n += 1
|
||||
write_log("|-Renewing additional certificate {}, domain name:{}..".format(n, cert_init['subject']))
|
||||
write_log("|-Creating order..")
|
||||
args.id = siteInfo['id']
|
||||
runPath = siteObj.GetRunPath(args)
|
||||
if runPath and not runPath in ['/']:
|
||||
path = siteInfo['path'] + '/' + runPath
|
||||
else:
|
||||
path = siteInfo['path']
|
||||
|
||||
self.renew_cert_to(cert_init['dns'],'http',path.replace('//','/'))
|
||||
except:
|
||||
write_log("|-Renewal failed:")
|
||||
|
||||
def renew_cert_to(self, domains, auth_type, auth_to, index=None):
|
||||
siteName = None
|
||||
cert = {}
|
||||
args = public.dict_obj()
|
||||
if auth_to[-1] == "/":
|
||||
auth_to = auth_to[:-1]
|
||||
site_id = public.M('sites').where('path=?', auth_to).getField('id')
|
||||
args.id = site_id
|
||||
if os.path.exists(auth_to):
|
||||
if public.M('sites').where('path=?', auth_to).count() == 1:
|
||||
# site_id = public.M('sites').where('path=?',auth_to).getField('id')
|
||||
siteName = public.M('sites').where('path=?', auth_to).getField('name')
|
||||
import panelSite
|
||||
siteObj = panelSite.panelSite()
|
||||
# args = public.dict_obj()
|
||||
# args.id = site_id
|
||||
runPath = siteObj.GetRunPath(args)
|
||||
if runPath and not runPath in ['/']:
|
||||
path = auth_to + '/' + runPath
|
||||
if os.path.exists(path): auth_to = path.replace('//', '/')
|
||||
|
||||
else:
|
||||
siteName = self.get_site_name_by_domains(domains)
|
||||
try:
|
||||
index = self.create_order(
|
||||
domains,
|
||||
auth_type,
|
||||
auth_to.replace('//', '/'),
|
||||
index
|
||||
)
|
||||
|
||||
write_log("|-Getting verification information..")
|
||||
self.get_auths(index)
|
||||
write_log("|-Verifying domain name..")
|
||||
self.auth_domain(index)
|
||||
write_log("|-Sending CSR..")
|
||||
self.remove_dns_record()
|
||||
self.send_csr(index)
|
||||
write_log("|-Downloading certificate..")
|
||||
cert = self.download_cert(index)
|
||||
self._config['orders'][index]['renew_time'] = int(time.time())
|
||||
|
||||
# 清理失败重试记录
|
||||
self._config['orders'][index]['retry_count'] = 0
|
||||
self._config['orders'][index]['next_retry_time'] = 0
|
||||
|
||||
# 保存证书配置
|
||||
self.save_config()
|
||||
cert['status'] = True
|
||||
cert['msg'] = 'Renewed successfully!'
|
||||
write_log("|-Renewed successfully!!")
|
||||
except Exception as e:
|
||||
if str(e).find('please try again later') == -1: # 受其它证书影响和连接CA失败的的不记录重试次数
|
||||
if index:
|
||||
# 设置下次重试时间
|
||||
self._config['orders'][index]['next_retry_time'] = int(time.time() + (86400 * 2))
|
||||
# 记录重试次数
|
||||
if not 'retry_count' in self._config['orders'][index].keys():
|
||||
self._config['orders'][index]['retry_count'] = 1
|
||||
self._config['orders'][index]['retry_count'] += 1
|
||||
# 保存证书配置
|
||||
self.save_config()
|
||||
msg = str(e).split('>>>>')[0]
|
||||
write_log("|-" + msg)
|
||||
return public.returnMsg(False, msg)
|
||||
finally:
|
||||
self.turnon_redirect_proxy_httptohttps(args)
|
||||
write_log("-" * 70)
|
||||
return cert
|
||||
|
||||
# 续签证书
|
||||
def renew_cert(self, index):
|
||||
write_log("", "wb+")
|
||||
@@ -1612,10 +1750,11 @@ fullchain.pem Paste into certificate input box
|
||||
# 在面板点击申请证书时不要重启面板以防后续请求出错
|
||||
self._by_panel = True
|
||||
if index not in self._config['orders']:
|
||||
raise Exception(public.getMsg('ACME_RENEW_ERR'))
|
||||
raise Exception(public.get_msg_gettext('The specified order number does not exist and cannot be renewed!'))
|
||||
order_index.append(index)
|
||||
else:
|
||||
s_time = time.time() + (30 * 86400)
|
||||
if not 'orders' in self._config: self._config['orders'] = {}
|
||||
for i in self._config['orders'].keys():
|
||||
if not 'save_path' in self._config['orders'][i]:
|
||||
continue
|
||||
@@ -1645,17 +1784,21 @@ 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, (The number of errors will be reset after manual renewal and success)'.format(self._config['orders'][i]['domains']))
|
||||
if self._config['orders'][i]['retry_count'] >= 5:
|
||||
write_log('|-Skip the domain name this time: {}, this certificate will not be renewed due to failure to renew 5 times in a row, (The number of errors will be reset after manual renewal and success)'.format(self._config['orders'][i]['domains']))
|
||||
continue
|
||||
|
||||
# 加入到续签订单
|
||||
order_index.append(i)
|
||||
|
||||
if not order_index:
|
||||
write_log(public.getMsg('ACME_NO_NEED_RENEW'))
|
||||
return public.returnMsg(False,public.getMsg('ACME_NO_NEED_RENEW'))
|
||||
write_log(public.getMsg("ACME_NEED_RENEW",(str(len(order_index)),)))
|
||||
write_log(public.get_msg_gettext('|-No SSL certificate found within 30 days!'))
|
||||
self.get_apis()
|
||||
self.renew_cert_other()
|
||||
# return public.return_msg_gettext(False,public.get_msg_gettext('|-No SSL certificate found within 30 days!'))
|
||||
write_log("|-All tasks have been processed!")
|
||||
return
|
||||
write_log(public.get_msg_gettext('|-A total of {} certificates need to be renewed',(str(len(order_index)),)))
|
||||
n = 0
|
||||
self.get_apis()
|
||||
cert = None
|
||||
@@ -1671,53 +1814,54 @@ fullchain.pem Paste into certificate input box
|
||||
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'))
|
||||
try:
|
||||
run_path = self.get_site_runpath(self._config['orders'][index]['domains'])
|
||||
if run_path:
|
||||
if self._config['orders'][index]['auth_to'] != run_path:
|
||||
self._config['orders'][index]['auth_to'] = run_path
|
||||
index = self.create_order(
|
||||
self._config['orders'][index]['domains'],
|
||||
self._config['orders'][index]['auth_type'],
|
||||
self._config['orders'][index]['auth_to'],
|
||||
index
|
||||
)
|
||||
write_log(public.getMsg('ACME_GET_V'))
|
||||
self.get_auths(index)
|
||||
write_log(public.getMsg('ACME_V_DOMAIN'))
|
||||
self.auth_domain(index)
|
||||
write_log(public.getMsg('ACME_SEND_CSR'))
|
||||
self.remove_dns_record()
|
||||
self.send_csr(index)
|
||||
write_log(public.getMsg('ACME_DOWNLOAD_CERT'))
|
||||
cert = self.download_cert(index)
|
||||
self._config['orders'][index]['renew_time'] = int(time.time())
|
||||
|
||||
# 清理失败重试记录
|
||||
self._config['orders'][index]['retry_count'] = 0
|
||||
self._config['orders'][index]['next_retry_time'] = 0
|
||||
|
||||
# 保存证书配置
|
||||
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失败的的不记录重试次数
|
||||
# 设置下次重试时间
|
||||
self._config['orders'][index]['next_retry_time'] = int(time.time() + (86400 * 2))
|
||||
# 记录重试次数
|
||||
if not 'retry_count' in self._config['orders'][index].keys():
|
||||
self._config['orders'][index]['retry_count'] = 1
|
||||
self._config['orders'][index]['retry_count'] += 1
|
||||
# 保存证书配置
|
||||
self.save_config()
|
||||
write_log("|-" + str(e).split('>>>>')[0])
|
||||
write_log("-" * 70)
|
||||
write_log(public.get_msg_gettext('|-Renewing certificate number of {},domain: {}..',(str(n),str(self._config['orders'][index]['domains']))))
|
||||
write_log(public.get_msg_gettext('|-Creating order..'))
|
||||
cert = self.renew_cert_to(self._config['orders'][index]['domains'],self._config['orders'][index]['auth_type'],self._config['orders'][index]['auth_to'],index)
|
||||
# try:
|
||||
# run_path = self.get_site_runpath(self._config['orders'][index]['domains'])
|
||||
# if run_path:
|
||||
# if self._config['orders'][index]['auth_to'] != run_path:
|
||||
# self._config['orders'][index]['auth_to'] = run_path
|
||||
# index = self.create_order(
|
||||
# self._config['orders'][index]['domains'],
|
||||
# self._config['orders'][index]['auth_type'],
|
||||
# self._config['orders'][index]['auth_to'],
|
||||
# index
|
||||
# )
|
||||
# write_log(public.get_msg_gettext('|-Getting verification information..'))
|
||||
# self.get_auths(index)
|
||||
# write_log(public.get_msg_gettext('|-Verifying domain name..'))
|
||||
# self.auth_domain(index)
|
||||
# write_log(public.get_msg_gettext('|-Sending CSR..'))
|
||||
# self.remove_dns_record()
|
||||
# self.send_csr(index)
|
||||
# write_log(public.get_msg_gettext('|-Downloading certificate..'))
|
||||
# cert = self.download_cert(index)
|
||||
# self._config['orders'][index]['renew_time'] = int(time.time())
|
||||
#
|
||||
# # 清理失败重试记录
|
||||
# self._config['orders'][index]['retry_count'] = 0
|
||||
# self._config['orders'][index]['next_retry_time'] = 0
|
||||
#
|
||||
# # 保存证书配置
|
||||
# self.save_config()
|
||||
# cert['status'] = True
|
||||
# cert['msg'] = public.get_msg_gettext('Renewed successfully!')
|
||||
# if os.path.exists(self._stop_rp_file):
|
||||
# self.turnon_redirect_proxy_httptohttps(args)
|
||||
# write_log(public.get_msg_gettext('|-Renewed successfully!'))
|
||||
# except Exception as e:
|
||||
# if str(e).find('请稍候重试') == -1: # 受其它证书影响和连接CA失败的的不记录重试次数
|
||||
# # 设置下次重试时间
|
||||
# self._config['orders'][index]['next_retry_time'] = int(time.time() + (86400 * 2))
|
||||
# # 记录重试次数
|
||||
# if not 'retry_count' in self._config['orders'][index].keys():
|
||||
# self._config['orders'][index]['retry_count'] = 1
|
||||
# self._config['orders'][index]['retry_count'] += 1
|
||||
# # 保存证书配置
|
||||
# self.save_config()
|
||||
# write_log("|-" + str(e).split('>>>>')[0])
|
||||
# write_log("-" * 70)
|
||||
return cert
|
||||
except Exception as ex:
|
||||
self.remove_dns_record()
|
||||
@@ -1728,7 +1872,7 @@ fullchain.pem Paste into certificate input box
|
||||
else:
|
||||
msg = ex
|
||||
write_log(public.get_error_info())
|
||||
return public.returnMsg(False, msg)
|
||||
return public.return_msg_gettext(False, msg)
|
||||
|
||||
|
||||
def echo_err(msg):
|
||||
@@ -1751,22 +1895,22 @@ def write_log(log_str, mode="ab+"):
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(usage=public.getMsg('ACME_USE_TIPS'))
|
||||
p = argparse.ArgumentParser(usage=public.get_msg_gettext('Required parameters: --domain list of domain names, multiple separated by commas!'))
|
||||
p.add_argument('--domain', default=None,
|
||||
help=public.getMsg('ACME_USE_TIPS1'), dest="domains")
|
||||
p.add_argument('--type', default=None, help=public.getMsg('ACME_USE_TIPS2'), dest="auth_type")
|
||||
p.add_argument('--path', default=None, help=public.getMsg('ACME_USE_TIPS3'), dest="path")
|
||||
p.add_argument('--dnsapi', default=None, help=public.getMsg('ACME_USE_TIPS4'), dest="dnsapi")
|
||||
p.add_argument('--dns_key', default=None, help=public.getMsg('ACME_USE_TIPS5'), dest="key")
|
||||
p.add_argument('--dns_secret', default=None,help=public.getMsg('ACME_USE_TIPS6'), dest="secret")
|
||||
p.add_argument('--index', default=None, help=public.getMsg('ACME_USE_TIPS7'), dest="index")
|
||||
p.add_argument('--renew', default=None, help=public.getMsg('ACME_USE_TIPS8'), dest="renew")
|
||||
p.add_argument('--revoke', default=None, help=public.getMsg('ACME_USE_TIPS9'), dest="revoke")
|
||||
help=public.get_msg_gettext('Please specify the domain name to apply for a certificate'), dest="domains")
|
||||
p.add_argument('--type', default=None, help=public.get_msg_gettext('Please specify verification type'), dest="auth_type")
|
||||
p.add_argument('--path', default=None, help=public.get_msg_gettext('Please specify the website document root'), dest="path")
|
||||
p.add_argument('--dnsapi', default=None, help=public.get_msg_gettext('Please specify DNSAPI'), dest="dnsapi")
|
||||
p.add_argument('--dns_key', default=None, help=public.get_msg_gettext('Please specify DNSAPI key'), dest="key")
|
||||
p.add_argument('--dns_secret', default=None,help=public.get_msg_gettext('Please specify DNSAPI secret'), dest="secret")
|
||||
p.add_argument('--index', default=None, help=public.get_msg_gettext('Specify the order index'), dest="index")
|
||||
p.add_argument('--renew', default=None, help=public.get_msg_gettext('renew certificate'), dest="renew")
|
||||
p.add_argument('--revoke', default=None, help=public.get_msg_gettext('Revoke certificate'), dest="revoke")
|
||||
args = p.parse_args()
|
||||
cert = None
|
||||
if args.revoke:
|
||||
if not args.index:
|
||||
echo_err(public.getMsg('ACME_USE_TIPS10'))
|
||||
echo_err(public.get_msg_gettext('Please enter the index of the order to be revoked in the --index parameter'))
|
||||
p = acme_v2()
|
||||
result = p.revoke_order(args.index)
|
||||
write_log(result)
|
||||
@@ -1779,24 +1923,24 @@ if __name__ == "__main__":
|
||||
try:
|
||||
if not args.index:
|
||||
if not args.domains:
|
||||
echo_err(public.getMsg('ACME_USE_TIPS11'))
|
||||
echo_err(public.get_msg_gettext('Please specify the domain name for which you want to apply for a certificate in the --domain parameter, multiple separated by commas (,)'))
|
||||
if not args.auth_type in ['http', 'tls', 'dns']:
|
||||
echo_err(public.getMsg('ACME_USE_TIPS12'))
|
||||
echo_err(public.get_msg_gettext('Please specify the correct authentication type in the --type parameter, supporting dns and http'))
|
||||
auth_to = ''
|
||||
if args.auth_type in ['http', 'tls']:
|
||||
if not args.path:
|
||||
echo_err(public.getMsg('ACME_USE_TIPS13'))
|
||||
echo_err(public.get_msg_gettext('Please specify the website document root in the --path parameter!'))
|
||||
if not os.path.exists(args.path):
|
||||
echo_err(public.getMsg('ACME_USE_TIPS14',(args.path,)))
|
||||
echo_err(public.get_msg_gettext('The specified site root does not exist, please check: {}',(args.path,)))
|
||||
auth_to = args.path
|
||||
else:
|
||||
if args.dnsapi == '0':
|
||||
auth_to = 'dns'
|
||||
else:
|
||||
if not args.key:
|
||||
echo_err(public.getMsg('ACME_USE_TIPS15'))
|
||||
echo_err(public.get_msg_gettext('When applying using dnsapi, specify the dnsapi key in the --dns_key parameter!'))
|
||||
if not args.secret:
|
||||
echo_err(public.getMsg('ACME_USE_TIPS16'))
|
||||
echo_err(public.get_msg_gettext('When applying using dnsapi, specify the secret of dnsapi in the --dns_secret parameter!'))
|
||||
auth_to = "{}|{}|{}".format(
|
||||
args.dnsapi, args.key, args.secret)
|
||||
|
||||
@@ -1808,27 +1952,27 @@ if __name__ == "__main__":
|
||||
acme_txt = '_acme-challenge.'
|
||||
acme_caa = '1 issue letsencrypt.org'
|
||||
write_log("=" * 65)
|
||||
write_log("\033[32m"+public.getMsg('ACME_USE_TIPS17')+"\033[0m")
|
||||
write_log("\033[32m"+public.get_msg_gettext('|-Manual order submission is successful, please resolve DNS records according to the following tips: ')+"\033[0m")
|
||||
write_log("=" * 65)
|
||||
write_log(public.getMsg('ACME_USE_TIPS18',(cert['index'],)))
|
||||
write_log(public.getMsg('ACME_USE_TIPS19')+": ./acme_v2.py --index=\"{}\"".format(cert['index']))
|
||||
write_log(public.getMsg('ACME_USE_TIPS20',(len(cert['auths']),)))
|
||||
write_log(public.get_msg_gettext('|-Order index: {}',(cert['index'],)))
|
||||
write_log(public.get_msg_gettext('|-Retry the command')+": ./acme_v2.py --index=\"{}\"".format(cert['index']))
|
||||
write_log(public.get_msg_gettext('|-A total of \033[36m{}\033[0m domain name records need to be resolved.',(len(cert['auths']),)))
|
||||
for i in range(len(cert['auths'])):
|
||||
write_log('-' * 70)
|
||||
write_log(public.getMsg('ACME_USE_TIPS21',(str(i+1), cert['auths'][i]['domain'])))
|
||||
write_log(public.getMsg('ACME_USE_TIPS22',(acme_txt + cert['auths'][i]['domain'].replace('*.', ''), cert['auths'][i]['auth_value'])))
|
||||
write_log(public.getMsg('ACME_USE_TIPS23',(cert['auths'][i]['domain'].replace('*.', ''), acme_caa)))
|
||||
write_log(public.get_msg_gettext('|-The \033[36m{}\033[0m domain names are: {}, please resolve the following information: ',(str(i+1), cert['auths'][i]['domain'])))
|
||||
write_log(public.get_msg_gettext('|-Record Type: TXT Record Name: \033[41m{}\033[0m Record Value: \033[41m{}\033 [0m [Required]',(acme_txt + cert['auths'][i]['domain'].replace('*.', ''), cert['auths'][i]['auth_value'])))
|
||||
write_log(public.get_msg_gettext('|-Record type: CAA Record name: \033[41m{}\033[0m Record value: \033[41m{}\033[0m [Optional]',(cert['auths'][i]['domain'].replace('*.', ''), acme_caa)))
|
||||
write_log('-' * 70)
|
||||
input_data = ""
|
||||
while input_data not in ['y', 'Y', 'n', 'N']:
|
||||
input_msg = public.getMsg('ACME_USE_TIPS24')
|
||||
input_msg = public.get_msg_gettext('Please wait 2-3 minutes after completing the resolution and enter Y and press Enter to continue verifying the domain name: ')
|
||||
if sys.version_info[0] == 2:
|
||||
input_data = raw_input(input_msg)
|
||||
else:
|
||||
input_data = input(input_msg)
|
||||
if input_data in ['n', 'N']:
|
||||
write_log("=" * 65)
|
||||
write_log(public.getMsg('ACME_USE_TIPS25'))
|
||||
write_log(public.get_msg_gettext('|-The user abandons the application and exits the program!'))
|
||||
exit()
|
||||
cert = p.apply_cert(
|
||||
[], auth_type=args.auth_type, auth_to='dns', index=cert['index'])
|
||||
@@ -1843,8 +1987,8 @@ if __name__ == "__main__":
|
||||
if not cert:
|
||||
exit()
|
||||
write_log("=" * 65)
|
||||
write_log(public.getMsg('ACME_USE_TIPS26'))
|
||||
write_log(public.get_msg_gettext('|-Certificate obtained successfully!'))
|
||||
write_log("=" * 65)
|
||||
write_log(public.getMsg('ACME_USE_TIPS27',(','.join(cert['domains']),)))
|
||||
write_log(public.getMsg('ACME_USE_TIPS28',(public.format_date(times=cert['cert_timeout']),)))
|
||||
write_log(public.getMsg('ACME_USE_TIPS29',(cert['save_path'],)))
|
||||
write_log(public.get_msg_gettext('Certified Domain Name: {}',(','.join(cert['domains']),)))
|
||||
write_log(public.get_msg_gettext('Certificate expiration time: {}',(public.format_date(times=cert['cert_timeout']),)))
|
||||
write_log(public.get_msg_gettext('Certificate saved at: {}/',(cert['save_path'],)))
|
||||
|
||||
+347
-96
@@ -6,7 +6,7 @@
|
||||
# +-------------------------------------------------------------------
|
||||
# | Author: hwliang <hwl@bt.cn>
|
||||
# +-------------------------------------------------------------------
|
||||
from BTPanel import session,request
|
||||
from BTPanel import session,request,cache
|
||||
import public,os,json,time,apache,psutil
|
||||
class ajax:
|
||||
__official_url = 'https://brandnew.aapanel.com'
|
||||
@@ -25,7 +25,7 @@ class ajax:
|
||||
pass
|
||||
def GetNginxStatus(self,get):
|
||||
try:
|
||||
if not os.path.exists('/www/server/nginx/sbin/nginx'): return public.returnMsg(False,'NGINX_NOT_INSTALL')
|
||||
if not os.path.exists('/www/server/nginx/sbin/nginx'): return public.return_msg_gettext(False,'Nginx is not install')
|
||||
process_cpu = {}
|
||||
worker = int(public.ExecShell("ps aux|grep nginx|grep 'worker process'|wc -l")[0])-1
|
||||
workermen = int(public.ExecShell("ps aux|grep nginx|grep 'worker process'|awk '{memsum+=$6};END {print memsum}'")[0]) / 1024
|
||||
@@ -66,8 +66,8 @@ class ajax:
|
||||
data['workermen'] = "%s%s" % (int(workermen), "MB")
|
||||
return data
|
||||
except Exception as ex:
|
||||
public.WriteLog('GET_INFO','NGINX_LOAD_ERR',(ex,))
|
||||
return public.returnMsg(False,'GET_DATA_ERR')
|
||||
public.write_log_gettext('Get Info','Nginx load status acquisition failed:{}',(ex,))
|
||||
return public.return_msg_gettext(False,'Data acquisition failed!')
|
||||
|
||||
def GetPHPStatus(self,get):
|
||||
#取指定PHP版本的负载状态
|
||||
@@ -80,8 +80,8 @@ class ajax:
|
||||
tmp['start time'] = time.strftime('%Y-%m-%d %H:%M:%S',fTime)
|
||||
return tmp
|
||||
except Exception as ex:
|
||||
public.WriteLog('GET_INFO',"PHP_LOAD_ERR",(public.get_error_info(),))
|
||||
return public.returnMsg(False,'PHP_LOAD_ERR1')
|
||||
public.write_log_gettext('Get Info',"PHP load status acquisition failed: {}",(public.get_error_info(),))
|
||||
return public.return_msg_gettext(False,'PHP load status acquisition failed!')
|
||||
|
||||
def CheckStatusConf(self):
|
||||
if public.get_webserver() != 'nginx': return
|
||||
@@ -152,19 +152,19 @@ class ajax:
|
||||
|
||||
def CheckLibInstall(self,checks):
|
||||
for cFile in checks:
|
||||
if os.path.exists(cFile): return public.GetMsg("ALREADY_INSTALLED")
|
||||
return public.GetMsg("NOT_INSTALL")
|
||||
if os.path.exists(cFile): return public.GetMsg('Already installed')
|
||||
return public.GetMsg('Not installed')
|
||||
|
||||
#取插件操作选项
|
||||
def GetLibOpt(self,status,libName):
|
||||
optStr = ''
|
||||
if status == public.GetMsg("NOT_INSTALL"):
|
||||
optStr = '<a class="link" href="javascript:InstallLib(\''+libName+'\');">'+public.GetMsg("INSTALL")+'</a>'
|
||||
if status == public.GetMsg('Not installed'):
|
||||
optStr = '<a class="link" href="javascript:InstallLib(\''+libName+'\');">'+public.GetMsg('Uninstallaton succeeded')+'</a>'
|
||||
else:
|
||||
libConfig = public.GetMsg("CONF")
|
||||
if(libName == 'beta'): libConfig = public.GetMsg("CLOSE_BETA")
|
||||
libConfig = public.GetMsg('Old configuration')
|
||||
if(libName == 'beta'): libConfig = public.GetMsg('Beta tester profile')
|
||||
|
||||
optStr = '<a class="link" href="javascript:SetLibConfig(\''+libName+'\');">'+libConfig+'</a> | <a class="link" href="javascript:UninstallLib(\''+libName+'\');">'+public.GetMsg("UNINSTALL")+'</a>';
|
||||
optStr = '<a class="link" href="javascript:SetLibConfig(\''+libName+'\');">'+libConfig+'</a> | <a class="link" href="javascript:UninstallLib(\''+libName+'\');">'+public.get_msg_gettext("Uninstallaton succeeded")+'</a>';
|
||||
return optStr
|
||||
|
||||
#取插件AS
|
||||
@@ -189,9 +189,9 @@ class ajax:
|
||||
result = public.ExecShell(public.get_python_bin() + " " + public.GetConfigValue('setup_path') + "/panel/script/backup_"+get.name+".py list")
|
||||
|
||||
if result[0].find("ERROR:") == -1:
|
||||
public.WriteLog("PLUG_MAM","SET_PLUG[" +info['name']+ "]AS!")
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.returnMsg(False,'AK_SK_CONNECT_ERROR',(info['name'],))
|
||||
public.write_log_gettext("Plugin manager","Set plugin [" +info['name']+ "]AS!")
|
||||
return public.return_msg_gettext(True, 'Successfully set')
|
||||
return public.return_msg_gettext(False,'ERROR: Unable to connect to the {} server, please check if the [AK/SK/Storage] setting is correct!',(info['name'],))
|
||||
|
||||
#设置内测
|
||||
def SetBeta(self,get):
|
||||
@@ -229,7 +229,7 @@ class ajax:
|
||||
result = public.ExecShell(public.get_python_bin() + " " + public.GetConfigValue('setup_path') + "/panel/script/backup_"+get.name+".py list")
|
||||
return json.loads(result[0])
|
||||
except:
|
||||
return public.returnMsg(False, 'GET_QINIU_FILE_LIST')
|
||||
return public.return_msg_gettext(False, 'Failed to get the list, please check if the [AK/SK/Storage] setting is correct!')
|
||||
|
||||
|
||||
|
||||
@@ -301,11 +301,11 @@ class ajax:
|
||||
import psutil
|
||||
p = psutil.Process(int(get.pid))
|
||||
name = p.name()
|
||||
if name == 'python': return public.returnMsg(False,'KILL_PROCESS_ERR')
|
||||
if name == 'python': return public.return_msg_gettext(False,'Error, cannot end task processes!')
|
||||
|
||||
p.kill()
|
||||
public.WriteLog('TYPE_PROCESS','KILL_PROCESS',(get.pid,name))
|
||||
return public.returnMsg(True,'KILL_PROCESS',(get.pid,name))
|
||||
public.write_log_gettext('Task manager','Ended processes[{}][{}] Successfully!',(get.pid,name))
|
||||
return public.return_msg_gettext(True,'Ended processes[{}][{}] Successfully!',(get.pid,name))
|
||||
|
||||
def GoToProcess(self,name):
|
||||
ps = ['sftp-server','login','nm-dispatcher','irqbalance','qmgr','wpa_supplicant','lvmetad','auditd','master','dbus-daemon','tapdisk','sshd','init','ksoftirqd','kworker','kmpathd','kmpath_handlerd','python','kdmflush','bioset','crond','kthreadd','migration','rcu_sched','kjournald','iptables','systemd','network','dhclient','systemd-journald','NetworkManager','systemd-logind','systemd-udevd','polkitd','tuned','rsyslogd']
|
||||
@@ -445,8 +445,8 @@ class ajax:
|
||||
public.writeFile('/www/server/panel/data/is_beta.pl','true')
|
||||
try:
|
||||
return {'status': True, 'msg': "Successful application!"}
|
||||
except: return public.returnMsg(False,'AJAX_CONN_ERR')
|
||||
except: return public.returnMsg(False,'AJAX_USER_BINDING_ERR')
|
||||
except: return public.return_msg_gettext(False,'Fail to connect to the server!')
|
||||
except: return public.return_msg_gettext(False,'Please bind your account first!')
|
||||
|
||||
def to_not_beta(self,get):
|
||||
try:
|
||||
@@ -461,8 +461,8 @@ class ajax:
|
||||
if os.path.exists(beta_file):
|
||||
os.remove(beta_file)
|
||||
return {"status": True, "msg": "Successful application!"}
|
||||
except: return public.returnMsg(False,'AJAX_CONN_ERR')
|
||||
except: return public.returnMsg(False,'AJAX_USER_BINDING_ERR')
|
||||
except: return public.return_msg_gettext(False,'Fail to connect to the server!')
|
||||
except: return public.return_msg_gettext(False,'Please bind your account first!')
|
||||
|
||||
def to_beta(self):
|
||||
try:
|
||||
@@ -483,11 +483,10 @@ class ajax:
|
||||
#获取最新的5条测试版更新日志
|
||||
def get_beta_logs(self,get):
|
||||
try:
|
||||
# data = json.loads(public.HttpGet('https://console.aapanel.com/api/panel/get_beta_logs_en'))
|
||||
data = json.loads(public.HttpGet('{}/api/panel/getBetaVersionLogs'.format(self.__official_url)))
|
||||
return data
|
||||
except:
|
||||
return public.returnMsg(False,'AJAX_CONN_ERR')
|
||||
return public.return_msg_gettext(False,'Fail to connect to the server!')
|
||||
|
||||
def get_other_info(self):
|
||||
other = {}
|
||||
@@ -502,13 +501,11 @@ class ajax:
|
||||
|
||||
def UpdatePanel(self,get):
|
||||
try:
|
||||
if not public.IsRestart(): return public.returnMsg(False,'EXEC_ERR_TASK')
|
||||
if not public.IsRestart(): return public.return_msg_gettext(False,'Please run the program when all install tasks finished!')
|
||||
import json
|
||||
conf_status = public.M('config').where("id=?",('1',)).field('status').find()
|
||||
if int(session['config']['status']) == 0 and int(conf_status['status']) == 0:
|
||||
# public.HttpGet('{}/api/setupCount/setupPanel?type=Linux'.format(self.__official_url))
|
||||
public.arequests('get', '{}/api/setupCount/setupPanel?type=Linux'.format(self.__official_url))
|
||||
|
||||
public.M('config').where("id=?",('1',)).setField('status',1)
|
||||
|
||||
#取回远程版本信息
|
||||
@@ -535,21 +532,22 @@ class ajax:
|
||||
data['oem'] = ''
|
||||
data['intrusion'] = 0
|
||||
data['uid'] = self.get_uid()
|
||||
#msg = public.getMsg('PANEL_UPDATE_MSG');
|
||||
#msg = public.getMsg('Current version is stable version and already latest. Update cycle of stable version is generally 2 months,while developer version will update every Wednesday!');
|
||||
data['o'] = public.get_oem_name()
|
||||
sUrl = '{}/api/panel/updateLinuxEn'.format(self.__official_url)
|
||||
updateInfo = json.loads(public.httpPost(sUrl,data))
|
||||
if not updateInfo: return public.returnMsg(False,"CONNECT_ERR")
|
||||
if not updateInfo: return public.return_msg_gettext(False,'Failed to connect server!')
|
||||
#updateInfo['msg'] = msg;
|
||||
if os.path.exists('/www/server/panel/data/is_beta.pl'):
|
||||
updateInfo['is_beta'] = 1
|
||||
session['updateInfo'] = updateInfo
|
||||
|
||||
#检查是否需要升级
|
||||
if updateInfo['is_beta'] == 1:
|
||||
if updateInfo['beta']['version'] ==session['version']: return public.returnMsg(False,updateInfo)
|
||||
else:
|
||||
if updateInfo['version'] ==session['version']: return public.returnMsg(False,updateInfo)
|
||||
if not hasattr(get,'toUpdate'):
|
||||
if updateInfo['is_beta'] == 1:
|
||||
if updateInfo['beta']['version'] == session['version']: return public.returnMsg(False,updateInfo)
|
||||
else:
|
||||
if updateInfo['version'] == session['version']: return public.returnMsg(False,updateInfo)
|
||||
|
||||
|
||||
#是否执行升级程序
|
||||
@@ -560,9 +558,9 @@ class ajax:
|
||||
httpUrl = public.get_url()
|
||||
if httpUrl: updateInfo['downUrl'] = httpUrl + '/install/' + uptype + '/LinuxPanel_EN-' + updateInfo['version'] + '.zip'
|
||||
public.downloadFile(updateInfo['downUrl'],'panel.zip')
|
||||
if os.path.getsize('panel.zip') < 1048576: return public.returnMsg(False,"PANEL_UPDATE_ERR_DOWN")
|
||||
if os.path.getsize('panel.zip') < 1048576: return public.return_msg_gettext(False,'File download failed, please try again or update manually!')
|
||||
public.ExecShell('unzip -o panel.zip -d ' + setupPath + '/')
|
||||
import compileall
|
||||
# import compileall
|
||||
if os.path.exists('/www/server/panel/runserver.py'): public.ExecShell('rm -f /www/server/panel/*.pyc')
|
||||
if os.path.exists('/www/server/panel/class/common.py'): public.ExecShell('rm -f /www/server/panel/class/*.pyc')
|
||||
|
||||
@@ -572,7 +570,7 @@ class ajax:
|
||||
if updateInfo['is_beta'] == 1: self.to_beta()
|
||||
public.ExecShell("/etc/init.d/bt start")
|
||||
public.writeFile('data/restart.pl','True')
|
||||
return public.returnMsg(True,'PANEL_UPDATE',(updateInfo['version'],))
|
||||
return public.return_msg_gettext(True,'Successful to update to {}',(updateInfo['version'],))
|
||||
|
||||
#输出新版本信息
|
||||
data = {
|
||||
@@ -580,13 +578,20 @@ class ajax:
|
||||
'version': updateInfo['version'],
|
||||
'updateMsg' : updateInfo['updateMsg']
|
||||
}
|
||||
|
||||
# 输出忽略的版本
|
||||
updateInfo['ignore'] = []
|
||||
no_path = '{}/data/no_update.pl'.format(public.get_panel_path())
|
||||
if os.path.exists(no_path):
|
||||
try:
|
||||
updateInfo['ignore'] = json.loads(public.readFile(no_path))
|
||||
except:
|
||||
pass
|
||||
public.ExecShell('rm -rf /www/server/phpinfo/*')
|
||||
return public.returnMsg(True,updateInfo)
|
||||
except Exception as ex:
|
||||
return public.get_error_info()
|
||||
return public.returnMsg(False,"CONNECT_ERR")
|
||||
|
||||
return public.return_msg_gettext(False,'Failed to connect server!')
|
||||
|
||||
#检查是否安装任何
|
||||
def CheckInstalled(self,get):
|
||||
checks = ['nginx','apache','php','pure-ftpd','mysql']
|
||||
@@ -611,7 +616,7 @@ class ajax:
|
||||
filename = '/usr/local/lsws/lsphp{}/etc/php/{}.{}/litespeed/php.ini'.format(get.version,get.version[0],get.version[1])
|
||||
if os.path.exists('/etc/redhat-release'):
|
||||
filename = '/usr/local/lsws/lsphp' + get.version + '/etc/php.ini'
|
||||
if not os.path.exists(filename): return public.returnMsg(False,'PHP_NOT_EXISTS')
|
||||
if not os.path.exists(filename): return public.return_msg_gettext(False,'Requested PHP version does NOT exist!')
|
||||
phpini = public.readFile(filename)
|
||||
data = {}
|
||||
rep = "disable_functions\s*=\s{0,1}(.*)\n"
|
||||
@@ -698,7 +703,7 @@ class ajax:
|
||||
|
||||
# 下载云端php扩展配置
|
||||
def _get_cloud_phplib(self):
|
||||
if not session.get('download_url'): session['download_url'] = 'http://node.aapanel.com'
|
||||
if not session.get('download_url'): session['download_url'] = 'https://node.aapanel.com'
|
||||
download_url = session['download_url'] + '/install/lib/phplib_en.json'
|
||||
tstr = public.httpGet(download_url)
|
||||
data = json.loads(tstr)
|
||||
@@ -723,13 +728,13 @@ class ajax:
|
||||
#清理日志
|
||||
def delClose(self,get):
|
||||
if not 'uid' in session: session['uid'] = 1
|
||||
if session['uid'] != 1: return public.returnMsg(False,'PERMISSION_DENIED')
|
||||
if session['uid'] != 1: return public.return_msg_gettext(False,'Permission denied!')
|
||||
if 'tmp_login_id' in session:
|
||||
return public.returnMsg(False,'PERMISSION_DENIED')
|
||||
return public.return_msg_gettext(False,'Permission denied!')
|
||||
|
||||
public.M('logs').where('id>?',(0,)).delete()
|
||||
public.WriteLog('TYPE_CONFIG','LOG_CLOSE')
|
||||
return public.returnMsg(True,'LOG_CLOSE')
|
||||
public.write_log_gettext('Panel setting','Panel Logs emptied!')
|
||||
return public.return_msg_gettext(True,'Panel Logs emptied!')
|
||||
|
||||
def __get_webserver_conffile(self):
|
||||
webserver = public.get_webserver()
|
||||
@@ -778,54 +783,54 @@ class ajax:
|
||||
# 修改php ssl端口
|
||||
def change_phpmyadmin_ssl_port(self,get):
|
||||
if public.get_webserver() == "openlitespeed":
|
||||
return public.returnMsg(False, 'NOT_SUPPORT_OLS')
|
||||
return public.return_msg_gettext(False, 'The current web server is openlitespeed. This function is not supported yet.')
|
||||
import re
|
||||
try:
|
||||
port = int(get.port)
|
||||
if 1 > port > 65535:
|
||||
return public.returnMsg(False, 'PORT_CHECK_RANGE')
|
||||
return public.return_msg_gettext(False, 'Port range is incorrect!')
|
||||
except:
|
||||
return public.returnMsg(False, 'PORT_FORMAT_ERR')
|
||||
return public.return_msg_gettext(False, 'Please enter the correct port number')
|
||||
for i in ["nginx","apache"]:
|
||||
file = "/www/server/panel/vhost/{}/phpmyadmin.conf".format(i)
|
||||
conf = public.readFile(file)
|
||||
if not conf:
|
||||
return public.returnMsg(False,"PHPMYADMIN_SSL_ERR",(i,))
|
||||
return public.return_msg_gettext(False,'Did not find the {} configuration file, please try to close the ssl port settings before opening',(i,))
|
||||
rulePort = ['80', '443', '21', '20', '8080', '8081', '8089', '11211', '6379']
|
||||
if get.port in rulePort:
|
||||
return public.returnMsg(False, 'AJAX_PHPMYADMIN_PORT_ERR')
|
||||
return public.return_msg_gettext(False, 'Please do NOT use the usual port as the phpMyAdmin port!')
|
||||
if i == "nginx":
|
||||
if not os.path.exists("/www/server/panel/vhost/apache/phpmyadmin.conf"):
|
||||
return public.returnMsg(False, "PHPMYADMIN_SSL_ERR1")
|
||||
return public.return_msg_gettext(False, 'Did not find the apache phpmyadmin ssl configuration file, please try to close the ssl port settings before opening')
|
||||
rep = "listen\s*([0-9]+)\s*.*;"
|
||||
oldPort = re.search(rep, conf)
|
||||
if not oldPort:
|
||||
return public.returnMsg(False, 'PHPMYADMIN_SSL_ERR2')
|
||||
return public.return_msg_gettext(False, 'Did not detect the port that nginx phpmyadmin listens, please confirm whether the file has been manually modified.')
|
||||
oldPort = oldPort.groups()[0]
|
||||
conf = re.sub(rep, 'listen ' + get.port + ' ssl;', conf)
|
||||
else:
|
||||
rep = "Listen\s*([0-9]+)\s*\n"
|
||||
oldPort = re.search(rep, conf)
|
||||
if not oldPort:
|
||||
return public.returnMsg(False, 'PHPMYADMIN_SSL_ERR3')
|
||||
return public.return_msg_gettext(False, 'Did not detect the port that apache phpmyadmin listens, please confirm whether the file has been manually modified.')
|
||||
oldPort = oldPort.groups()[0]
|
||||
conf = re.sub(rep, "Listen " + get.port + "\n", conf, 1)
|
||||
rep = "VirtualHost\s*\*:[0-9]+"
|
||||
conf = re.sub(rep, "VirtualHost *:" + get.port, conf, 1)
|
||||
if oldPort == get.port: return public.returnMsg(False, 'SOFT_PHPVERSION_ERR_PORT')
|
||||
if oldPort == get.port: return public.return_msg_gettext(False, 'Port [{}] is in use!',(get.port,))
|
||||
public.writeFile(file, conf)
|
||||
public.serviceReload()
|
||||
if i=="apache":
|
||||
import firewalls
|
||||
get.ps = public.getMsg('SOFT_PHPVERSION_PS')
|
||||
get.ps = public.getMsg('New phpMyAdmin Port')
|
||||
fw = firewalls.firewalls()
|
||||
fw.AddAcceptPort(get)
|
||||
public.serviceReload()
|
||||
public.WriteLog('TYPE_SOFT', 'SOFT_PHPMYADMIN_PORT', (get.port,))
|
||||
public.write_log_gettext('Software manager', 'Modified access port to {} for phpMyAdmin!', (get.port,))
|
||||
get.id = public.M('firewall').where('port=?', (oldPort,)).getField('id')
|
||||
get.port = oldPort
|
||||
fw.DelAcceptPort(get)
|
||||
return public.returnMsg(True, 'SET_PORT_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
def _get_phpmyadmin_auth(self):
|
||||
import re
|
||||
@@ -846,9 +851,9 @@ class ajax:
|
||||
# 设置phpmyadmin ssl
|
||||
def set_phpmyadmin_ssl(self,get):
|
||||
if public.get_webserver() == "openlitespeed":
|
||||
return public.returnMsg(False, 'NOT_SUPPORT_OLS')
|
||||
return public.return_msg_gettext(False, 'The current web server is openlitespeed. This function is not supported yet.')
|
||||
if not os.path.exists("/www/server/panel/ssl/certificate.pem"):
|
||||
return public.returnMsg(False,'PHPMYADMIN_SSL_ERR4')
|
||||
return public.return_msg_gettext(False,'The panel certificate does not exist. Please apply for the panel certificate and try again.')
|
||||
if get.v == "1":
|
||||
# 获取auth信息
|
||||
auth = ""
|
||||
@@ -952,9 +957,9 @@ class ajax:
|
||||
if os.path.exists("/www/server/panel/vhost/apache/phpmyadmin.conf"):
|
||||
os.remove("/www/server/panel/vhost/apache/phpmyadmin.conf")
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'PHPMYADMIN_SSL_ERR5')
|
||||
return public.return_msg_gettext(True,'Open successfully, please manually release phpmyadmin ssl port')
|
||||
|
||||
|
||||
#设置PHPMyAdmin
|
||||
@@ -965,13 +970,13 @@ class ajax:
|
||||
if public.get_webserver() == 'openlitespeed':
|
||||
filename = "/www/server/panel/vhost/openlitespeed/detail/phpmyadmin.conf"
|
||||
conf = public.readFile(filename)
|
||||
if not conf: return public.returnMsg(False,'ERROR')
|
||||
if not conf: return public.return_msg_gettext(False,'Operation failed')
|
||||
if hasattr(get,'port'):
|
||||
mainPort = public.readFile('data/port.pl').strip()
|
||||
rulePort = ['80','443','21','20','8080','8081','8089','11211','6379']
|
||||
oldPort = "888"
|
||||
if get.port in rulePort:
|
||||
return public.returnMsg(False,'AJAX_PHPMYADMIN_PORT_ERR')
|
||||
return public.return_msg_gettext(False,'Please do NOT use the usual port as the phpMyAdmin port!')
|
||||
if public.get_webserver() == 'nginx':
|
||||
rep = r"listen\s+([0-9]+)\s*;"
|
||||
oldPort = re.search(rep,conf).groups()[0]
|
||||
@@ -990,19 +995,19 @@ class ajax:
|
||||
if tmp:
|
||||
oldPort = tmp.groups(1)
|
||||
conf = re.sub(reg,"address *:{}".format(get.port),conf)
|
||||
if oldPort == get.port: return public.returnMsg(False,'SOFT_PHPVERSION_ERR_PORT')
|
||||
if oldPort == get.port: return public.returnMsg(False,'Port [{}] is in use!',(get.port,))
|
||||
|
||||
public.writeFile(filename,conf)
|
||||
import firewalls
|
||||
get.ps = public.getMsg('SOFT_PHPVERSION_PS')
|
||||
get.ps = public.getMsg('New phpMyAdmin Port')
|
||||
fw = firewalls.firewalls()
|
||||
fw.AddAcceptPort(get)
|
||||
public.serviceReload()
|
||||
public.WriteLog('TYPE_SOFT','SOFT_PHPMYADMIN_PORT',(get.port,))
|
||||
public.write_log_gettext('Software manager','Modified access port to {} for phpMyAdmin!',(get.port,))
|
||||
get.id = public.M('firewall').where('port=?',(oldPort,)).getField('id')
|
||||
get.port = oldPort
|
||||
fw.DelAcceptPort(get)
|
||||
return public.returnMsg(True,'SET_PORT_SUCCESS')
|
||||
return public.returnMsg(True,'Setup successfully!')
|
||||
|
||||
if hasattr(get,'phpversion'):
|
||||
if public.get_webserver() == 'nginx':
|
||||
@@ -1018,8 +1023,8 @@ class ajax:
|
||||
conf = re.sub(reg,'/usr/local/lsws/lsphp{}/bin/lsphp'.format(get.phpversion),conf)
|
||||
public.writeFile(filename,conf)
|
||||
public.serviceReload()
|
||||
public.WriteLog('TYPE_SOFT','SOFT_PHPMYADMIN_PHP',(get.phpversion,))
|
||||
return public.returnMsg(True,'SOFT_PHPVERSION_SET')
|
||||
public.write_log_gettext('Software manager','Modified PHP runtime version to PHP-{} for phpMyAdmin!',(get.phpversion,))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
if hasattr(get,'password'):
|
||||
import panelSite
|
||||
@@ -1029,17 +1034,49 @@ class ajax:
|
||||
return panelSite.panelSite().SetHasPwd(get)
|
||||
|
||||
if hasattr(get,'status'):
|
||||
if conf.find(public.GetConfigValue('setup_path') + '/stop') != -1:
|
||||
conf = conf.replace(public.GetConfigValue('setup_path') + '/stop',public.GetConfigValue('setup_path') + '/phpmyadmin')
|
||||
pma_path = public.GetConfigValue('setup_path') + '/phpmyadmin'
|
||||
stop_path = public.GetConfigValue('setup_path') + '/stop'
|
||||
|
||||
|
||||
webserver = public.get_webserver()
|
||||
if conf.find(stop_path) != -1:
|
||||
conf = conf.replace(stop_path,pma_path)
|
||||
msg = public.getMsg('START')
|
||||
|
||||
if webserver == 'nginx':
|
||||
sub_string = '''{};
|
||||
allow 127.0.0.1;
|
||||
allow ::1;
|
||||
deny all'''.format(pma_path)
|
||||
if conf.find(sub_string) != -1:
|
||||
conf = conf.replace(sub_string,pma_path)
|
||||
msg = public.getMsg('START')
|
||||
else:
|
||||
conf = conf.replace(pma_path,sub_string)
|
||||
msg = public.getMsg('STOP')
|
||||
elif webserver == 'apache':
|
||||
src_string = 'AllowOverride All'
|
||||
sub_string = '''{}
|
||||
Deny from all
|
||||
Allow from 127.0.0.1 ::1 localhost'''.format(src_string,pma_path)
|
||||
if conf.find(sub_string) != -1:
|
||||
conf = conf.replace(sub_string,src_string)
|
||||
msg = public.getMsg('START')
|
||||
else:
|
||||
conf = conf.replace(src_string,sub_string)
|
||||
msg = public.getMsg('STOP')
|
||||
else:
|
||||
conf = conf.replace(public.GetConfigValue('setup_path') + '/phpmyadmin',public.GetConfigValue('setup_path') + '/stop')
|
||||
msg = public.getMsg('STOP')
|
||||
if conf.find(stop_path) != -1:
|
||||
conf = conf.replace(stop_path,pma_path)
|
||||
msg = public.getMsg('START')
|
||||
else:
|
||||
conf = conf.replace(pma_path,stop_path)
|
||||
msg = public.getMsg('STOP')
|
||||
|
||||
public.writeFile(filename,conf)
|
||||
public.serviceReload()
|
||||
public.WriteLog('TYPE_SOFT','SOFT_PHPMYADMIN_STATUS',(msg,))
|
||||
return public.returnMsg(True,'SOFT_PHPMYADMIN_STATUS',(msg,))
|
||||
public.write_log_gettext('Software manager','phpMyAdmin already {}!',(msg,))
|
||||
return public.return_msg_gettext(True,'phpMyAdmin already {}!',(msg,))
|
||||
#except:
|
||||
#return public.returnMsg(False,'ERROR');
|
||||
|
||||
@@ -1060,8 +1097,8 @@ class ajax:
|
||||
|
||||
#保存PHP排序
|
||||
def phpSort(self,get):
|
||||
if public.writeFile('/www/server/php/sort.pl',get.ssort): return public.returnMsg(True,'SUCCESS')
|
||||
return public.returnMsg(False,'ERROR')
|
||||
if public.writeFile('/www/server/php/sort.pl',get.ssort): return public.return_msg_gettext(True,'Setup successfully!')
|
||||
return public.return_msg_gettext(False,'Operation failed')
|
||||
|
||||
#获取广告代码
|
||||
def GetAd(self,get):
|
||||
@@ -1081,7 +1118,7 @@ class ajax:
|
||||
#获取警告标识
|
||||
def GetWarning(self,get):
|
||||
warningFile = 'data/warning.json'
|
||||
if not os.path.exists(warningFile): return public.returnMsg(False,'AJAX_WARNING_ERR')
|
||||
if not os.path.exists(warningFile): return public.return_msg_gettext(False,'Warning list does NOT exist!')
|
||||
import json,time;
|
||||
wlist = json.loads(public.readFile(warningFile))
|
||||
wlist['time'] = int(time.time())
|
||||
@@ -1099,7 +1136,7 @@ class ajax:
|
||||
|
||||
warningFile = 'data/warning.json'
|
||||
public.writeFile(warningFile,json.dumps(wlist))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
#获取memcached状态
|
||||
def GetMemcachedStatus(self,get):
|
||||
@@ -1139,7 +1176,7 @@ class ajax:
|
||||
conf = re.sub('CACHESIZE=\d+','CACHESIZE='+get.cachesize,conf)
|
||||
public.writeFile(confFile,conf)
|
||||
public.ExecShell(confFile + ' reload')
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
#取redis状态
|
||||
def GetRedisStatus(self,get):
|
||||
@@ -1180,10 +1217,10 @@ class ajax:
|
||||
def GetFpmLogs(self,get):
|
||||
import re
|
||||
fpm_path = '/www/server/php/' + get.version + '/etc/php-fpm.conf'
|
||||
if not os.path.exists(fpm_path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
|
||||
if not os.path.exists(fpm_path): return public.return_msg_gettext(False,'Log file does NOT exist!')
|
||||
fpm_conf = public.readFile(fpm_path)
|
||||
log_tmp = re.findall(r"error_log\s*=\s*(.+)",fpm_conf)
|
||||
if not log_tmp: return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
|
||||
if not log_tmp: return public.return_msg_gettext(False,'Log file does NOT exist!')
|
||||
log_file = log_tmp[0].strip()
|
||||
if log_file.find('var/log') == 0:
|
||||
log_file = '/www/server/php/' +get.version + '/'+ log_file
|
||||
@@ -1193,10 +1230,10 @@ class ajax:
|
||||
def GetFpmSlowLogs(self,get):
|
||||
import re
|
||||
fpm_path = '/www/server/php/' + get.version + '/etc/php-fpm.conf'
|
||||
if not os.path.exists(fpm_path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
|
||||
if not os.path.exists(fpm_path): return public.return_msg_gettext(False,'Log file does NOT exist!')
|
||||
fpm_conf = public.readFile(fpm_path)
|
||||
log_tmp = re.findall(r"slowlog\s*=\s*(.+)",fpm_conf)
|
||||
if not log_tmp: return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
|
||||
if not log_tmp: return public.return_msg_gettext(False,'Log file does NOT exist!')
|
||||
log_file = log_tmp[0].strip()
|
||||
if log_file.find('var/log') == 0:
|
||||
log_file = '/www/server/php/' +get.version + '/'+ log_file
|
||||
@@ -1204,12 +1241,120 @@ class ajax:
|
||||
|
||||
#取指定日志
|
||||
def GetOpeLogs(self,get):
|
||||
if not os.path.exists(get.path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
|
||||
if not os.path.exists(get.path): return public.return_msg_gettext(False,'Log file does NOT exist!')
|
||||
return public.returnMsg(True,public.GetNumLines(get.path,1000))
|
||||
|
||||
|
||||
def get_pd(self,get):
|
||||
from BTPanel import cache
|
||||
tmp = -1
|
||||
try:
|
||||
import panelPlugin
|
||||
# get = public.dict_obj()
|
||||
# get.init = 1
|
||||
tmp1 = panelPlugin.panelPlugin().get_cloud_list(get)
|
||||
except:
|
||||
tmp1 = None
|
||||
if tmp1:
|
||||
tmp = tmp1[public.to_string([112, 114, 111])]
|
||||
ltd = tmp1.get('ltd', -1)
|
||||
else:
|
||||
ltd = -1
|
||||
tmp4 = cache.get(public.to_string([112, 95, 116, 111, 107, 101, 110]))
|
||||
if tmp4:
|
||||
tmp_f = public.to_string([47, 116, 109, 112, 47]) + tmp4
|
||||
if not os.path.exists(tmp_f): public.writeFile(tmp_f, '-1')
|
||||
tmp = public.readFile(tmp_f)
|
||||
if tmp: tmp = int(tmp)
|
||||
if not ltd: ltd = -1
|
||||
if tmp == None: tmp = -1
|
||||
if ltd < 1:
|
||||
if ltd == -2:
|
||||
tmp3 = public.to_string(
|
||||
[60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116, 108, 116, 100,
|
||||
45, 103, 114, 97, 121, 34, 62, 60, 115, 112, 97, 110, 32, 115, 116, 121, 108, 101,
|
||||
61, 34, 99, 111, 108, 111, 114, 58, 32, 35, 102, 99, 54, 100, 50, 54, 59, 102, 111,
|
||||
110, 116, 45, 119, 101, 105, 103, 104, 116, 58, 32, 98, 111, 108, 100, 59, 109, 97,
|
||||
114, 103, 105, 110, 45, 114, 105, 103, 104, 116, 58, 53, 112, 120, 34, 62, 24050, 36807,
|
||||
26399, 60, 47, 115, 112, 97, 110, 62, 60, 97, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116,
|
||||
108, 105, 110, 107, 34, 32, 111, 110, 99, 108, 105, 99, 107, 61, 34, 98, 116, 46, 115, 111,
|
||||
102, 116, 46, 117, 112, 100, 97, 116, 97, 95, 108, 116, 100, 40, 41, 34, 62, 82, 69, 78, 69, 87,
|
||||
60, 47, 97,
|
||||
62, 60, 47, 115, 112, 97, 110, 62])
|
||||
elif tmp == -1:
|
||||
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98,
|
||||
116, 112, 114, 111, 45, 102, 114, 101, 101, 34, 32, 111, 110, 99, 108, 105, 99,
|
||||
107,
|
||||
61, 34, 98, 116, 46, 115, 111, 102, 116, 46, 114, 101, 110, 101, 119, 95, 112,
|
||||
114,
|
||||
111, 40, 41, 34, 32, 116, 105, 116, 108, 101, 61, 34, 67, 108, 105, 99, 107,
|
||||
32, 116, 111, 32,
|
||||
103, 101, 116, 32, 80, 82, 79, 34, 62, 20813, 36153, 29256, 60, 47, 115, 112,
|
||||
97, 110, 62])
|
||||
elif tmp == -2:
|
||||
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116,
|
||||
112, 114, 111, 45, 103, 114, 97, 121, 34, 62, 60, 115, 112, 97, 110, 32,
|
||||
115, 116, 121, 108, 101, 61, 34, 99, 111, 108, 111, 114, 58, 32, 35,
|
||||
102, 99, 54, 100, 50, 54, 59, 102, 111, 110, 116, 45, 119, 101, 105, 103,
|
||||
104, 116, 58, 32, 98, 111, 108, 100, 59, 109, 97, 114, 103, 105, 110, 45,
|
||||
114, 105, 103, 104, 116, 58, 53, 112, 120, 34, 62, 24050, 36807, 26399,
|
||||
60, 47, 115, 112, 97, 110, 62, 60, 97, 32, 99, 108, 97, 115, 115, 61, 34,
|
||||
98, 116, 108, 105, 110, 107, 34, 32, 111, 110, 99, 108, 105, 99, 107, 61,
|
||||
34, 98, 116, 46, 115, 111, 102, 116, 46, 114, 101, 110, 101, 119, 95, 112, 114,
|
||||
111, 40, 41, 34, 62, 82, 69, 78, 69, 87, 60, 47, 97, 62, 60, 47, 115, 112, 97,
|
||||
110, 62])
|
||||
if tmp >= 0 and ltd in [-1, -2]:
|
||||
if tmp == 0:
|
||||
tmp2 = public.to_string([27704, 20037, 25480, 26435])
|
||||
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116,
|
||||
112, 114, 111, 34, 62, 123, 48, 125, 60, 115, 112, 97, 110, 32, 115, 116,
|
||||
121, 108, 101, 61, 34, 99, 111, 108, 111, 114, 58, 32, 35, 102, 99, 54,
|
||||
100,
|
||||
50, 54, 59, 102, 111, 110, 116, 45, 119, 101, 105, 103, 104, 116,
|
||||
58, 32, 98, 111, 108, 100, 59, 34, 62, 123, 49, 125, 60, 47, 115,
|
||||
112, 97, 110, 62, 60, 47, 115, 112, 97, 110, 62]).format(
|
||||
public.to_string([21040, 26399, 26102, 38388, 65306]), tmp2)
|
||||
else:
|
||||
tmp2 = time.strftime(public.to_string([37, 89, 45, 37, 109, 45, 37, 100]), time.localtime(tmp))
|
||||
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116,
|
||||
112, 114, 111, 34, 62, 69, 120, 112, 105, 114, 101, 58, 32, 60, 115, 112,
|
||||
97, 110, 32, 115, 116, 121, 108, 101, 61, 34, 99, 111, 108, 111, 114,
|
||||
58, 32, 35, 102, 99, 54, 100, 50, 54, 59, 102, 111, 110, 116, 45, 119,
|
||||
101, 105, 103, 104, 116, 58, 32, 98, 111, 108, 100, 59, 109, 97, 114,
|
||||
103, 105, 110, 45, 114, 105, 103, 104, 116, 58, 53, 112, 120, 34, 62, 123,
|
||||
48, 125, 60, 47, 115, 112, 97, 110, 62, 60, 97, 32, 99, 108, 97, 115,
|
||||
115, 61, 34, 98, 116, 108, 105, 110, 107, 34, 32, 111, 110, 99, 108, 105,
|
||||
99,
|
||||
107, 61, 34, 98, 116, 46, 115, 111, 102, 116, 46, 114, 101, 110, 101, 119,
|
||||
95,
|
||||
112, 114, 111, 40, 41, 34, 62, 82, 69, 78, 69, 87, 60, 47, 97, 62, 60,
|
||||
47, 115, 112, 97, 110, 62]).format(tmp2)
|
||||
else:
|
||||
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116, 112,
|
||||
114, 111, 45, 103, 114, 97, 121, 34, 32, 111, 110, 99, 108, 105, 99, 107,
|
||||
61, 34, 98, 116, 46, 115, 111, 102, 116, 46, 117, 112, 100, 97, 116, 97, 95, 112,
|
||||
114, 111, 40, 41, 34, 32, 116, 105, 116, 108, 101, 61, 34, 67, 108, 105, 99,
|
||||
107, 32, 116,
|
||||
111, 32, 103, 101, 116, 32, 80, 82, 79, 34, 62, 70, 82,
|
||||
69, 69, 60, 47, 115, 112, 97, 110, 62])
|
||||
else:
|
||||
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116, 108, 116,
|
||||
100, 34, 62, 69, 120, 112, 105, 114, 101, 58, 32, 60, 115, 112, 97, 110, 32, 115,
|
||||
116,
|
||||
121, 108, 101, 61, 34, 99, 111, 108, 111, 114, 58, 32, 35, 102, 99, 54, 100, 50,
|
||||
54, 59, 102, 111, 110, 116, 45, 119, 101, 105, 103, 104, 116, 58, 32, 98, 111,
|
||||
108, 100, 59, 109, 97, 114, 103, 105, 110, 45, 114, 105, 103, 104, 116, 58, 53,
|
||||
112, 120, 34, 62, 123, 125, 60, 47, 115, 112, 97, 110, 62, 60, 97, 32, 99, 108,
|
||||
97, 115, 115, 61, 34, 98, 116, 108, 105, 110, 107, 34, 32, 111, 110, 99, 108, 105,
|
||||
99, 107, 61, 34, 98, 116, 46, 115, 111, 102, 116, 46, 114, 101, 110, 101, 119, 95,
|
||||
112, 114, 111, 40, 41, 34, 62, 82, 69, 78, 69, 87, 60, 47, 97, 62, 60, 47, 115,
|
||||
112, 97, 110, 62]).format(
|
||||
time.strftime(public.to_string([37, 89, 45, 37, 109, 45, 37, 100]), time.localtime(ltd)))
|
||||
|
||||
return tmp3, tmp, ltd
|
||||
|
||||
#检查用户绑定是否正确
|
||||
def check_user_auth(self,get):
|
||||
import requests
|
||||
# import requests
|
||||
m_key = 'check_user_auth'
|
||||
if m_key in session: return session[m_key]
|
||||
u_path = 'data/userInfo.json'
|
||||
@@ -1217,15 +1362,16 @@ class ajax:
|
||||
userInfo = json.loads(public.ReadFile(u_path))
|
||||
except:
|
||||
if os.path.exists(u_path): os.remove(u_path)
|
||||
return public.returnMsg(False,'AJAX_USER_BE_OVERDUE')
|
||||
return public.return_msg_gettext(False,'Account binding has expired, please re-bind on the [Settings] page!')
|
||||
url_headers = {"authorization":"bt {}".format(userInfo['token'])}
|
||||
resp = requests.post('{}/api/user/verifyToken'.format(self.__official_url),headers=url_headers,verify=False)
|
||||
# resp = requests.post('{}/api/user/verifyToken'.format(self.__official_url),headers=url_headers,verify=False)
|
||||
resp = public.HttpPost.post('{}/api/user/verifyToken'.format(self.__official_url), headers=url_headers, verify=False)
|
||||
resp = resp.json()
|
||||
if not resp['success']:
|
||||
if os.path.exists(u_path): os.remove(u_path)
|
||||
return public.returnMsg(False,'AJAX_USER_BE_OVERDUE')
|
||||
return public.return_msg_gettext(False,'Account binding has expired, please re-bind on the [Settings] page!')
|
||||
else:
|
||||
session[m_key] = public.returnMsg(True,'AJAX_USER_IS_VALID')
|
||||
session[m_key] = public.return_msg_gettext(True,'Binding is valid!')
|
||||
return session[m_key]
|
||||
|
||||
|
||||
@@ -1239,7 +1385,7 @@ class ajax:
|
||||
php_ini = php_path + php_version + '/etc/php.ini'
|
||||
if not os.path.exists('/etc/redhat-release') and public.get_webserver() == 'openlitespeed':
|
||||
php_ini = php_path + php_version + '/etc/php/'+args.php_version+'/litespeed/php.ini'
|
||||
tmp = public.ExecShell(php_bin + ' /www/server/panel/class/php_info.php')[0]
|
||||
tmp = public.ExecShell(php_bin + ' -c {} /www/server/panel/class/php_info.php'.format(php_ini))[0]
|
||||
if tmp.find('Warning: JIT is incompatible') != -1:
|
||||
tmp = tmp.strip().split('\n')[-1]
|
||||
result = json.loads(tmp)
|
||||
@@ -1258,8 +1404,113 @@ class ajax:
|
||||
|
||||
#取指定行
|
||||
def get_lines(self,args):
|
||||
if not os.path.exists(args.filename): return public.returnMsg(False,'LOG_EMPTY')
|
||||
if not os.path.exists(args.filename): return public.returnMsg(False,'Logs emptied')
|
||||
s_body = public.ExecShell("tail -n {} {}".format(args.num,args.filename))[0]
|
||||
return public.returnMsg(True,s_body)
|
||||
|
||||
|
||||
def log_analysis(self,get):
|
||||
import log_analysis
|
||||
log_analysis=log_analysis.log_analysis()
|
||||
return log_analysis.log_analysis(get)
|
||||
|
||||
|
||||
def speed_log(self,get):
|
||||
import log_analysis
|
||||
log_analysis=log_analysis.log_analysis()
|
||||
return log_analysis.speed_log(get)
|
||||
|
||||
|
||||
|
||||
def get_result(self,get):
|
||||
import log_analysis
|
||||
log_analysis=log_analysis.log_analysis()
|
||||
return log_analysis.get_result(get)
|
||||
|
||||
def get_detailed(self,get):
|
||||
import log_analysis
|
||||
log_analysis=log_analysis.log_analysis()
|
||||
return log_analysis.get_detailed(get)
|
||||
|
||||
def download_pay_type(self, path):
|
||||
public.downloadFile(public.get_url() + '/install/lib/pay_type_en.json', path)
|
||||
return True
|
||||
|
||||
def get_pay_type(self, get):
|
||||
"""
|
||||
@name 获取推荐列表
|
||||
"""
|
||||
spath = '{}/data/pay_type.json'.format(public.get_panel_path())
|
||||
down = cache.get('pay_type')
|
||||
if not down:
|
||||
public.run_thread(self.download_pay_type, (spath,))
|
||||
cache.set('pay_type', 1, 86400)
|
||||
try:
|
||||
data = json.loads(public.readFile("data/pay_type.json"))
|
||||
except:
|
||||
public.run_thread(self.download_pay_type, (spath,))
|
||||
data = {}
|
||||
|
||||
import panelPlugin
|
||||
plu_panel = panelPlugin.panelPlugin()
|
||||
plugin_list = plu_panel.get_cloud_list()
|
||||
if not 'pro' in plugin_list: plugin_list['pro'] = -1
|
||||
|
||||
for item in data:
|
||||
if 'list' in item:
|
||||
item['list'] = self.__get_home_list(item['list'], item['type'], plugin_list, plu_panel)
|
||||
if item['type'] == 1:
|
||||
if len(item['list']) > 4: item['list'] = item['list'][:4]
|
||||
# if item['type'] == 0 and plugin_list['pro'] >= 0:
|
||||
# item['show'] = False
|
||||
return data
|
||||
|
||||
def __get_home_list(self, sList, stype, plugin_list, plu_panel):
|
||||
"""
|
||||
@name 获取首页软件列表推荐
|
||||
"""
|
||||
nList = []
|
||||
webserver = public.get_webserver()
|
||||
for x in sList:
|
||||
for plugin_info in plugin_list['list']:
|
||||
if x['name'] == plugin_info['name']:
|
||||
if not 'endtime' in plugin_info or plugin_info['endtime'] >= 0:
|
||||
x['isBuy'] = True
|
||||
is_check = False
|
||||
if 'dependent' in x:
|
||||
if x['dependent'] == webserver: is_check = True
|
||||
else:
|
||||
is_check = True
|
||||
if is_check:
|
||||
info = plu_panel.get_soft_find(x['name'])
|
||||
if info:
|
||||
if stype == 1:
|
||||
# if plugin_list['pro'] >= 0: continue
|
||||
if not info['setup']:
|
||||
x['install'] = info['setup']
|
||||
nList.append(x)
|
||||
else:
|
||||
x['install'] = info['setup']
|
||||
nList.append(x)
|
||||
return nList
|
||||
|
||||
def ignore_version(self, get):
|
||||
"""
|
||||
@忽略版本更新
|
||||
:param version 忽略的版本号
|
||||
"""
|
||||
version = get.version
|
||||
path = '{}/data/no_update.pl'.format(public.get_panel_path())
|
||||
try:
|
||||
data = json.loads(public.readFile(path))
|
||||
except:
|
||||
data = []
|
||||
|
||||
if not version in data: data.append(version)
|
||||
|
||||
public.writeFile(path, json.dumps(data))
|
||||
try:
|
||||
del (session['updateInfo'])
|
||||
except:
|
||||
pass
|
||||
|
||||
return public.return_msg_gettext(True, "Ignore success, this version will no longer be reminded to update.")
|
||||
+36
-36
@@ -43,7 +43,7 @@ class apache:
|
||||
try:
|
||||
workermen = int(public.ExecShell("ps aux|grep httpd|grep 'start'|awk '{memsum+=$6};END {print memsum}'")[0]) / 1024
|
||||
except:
|
||||
return public.returnMsg(False,"Get worker RAM False")
|
||||
return public.return_msg_gettext(False,"Get worker RAM False")
|
||||
for proc in psutil.process_iter():
|
||||
if proc.name() == "httpd":
|
||||
self.GetProcessCpuPercent(proc.pid,process_cpu)
|
||||
@@ -54,7 +54,7 @@ class apache:
|
||||
# 计算启动时间
|
||||
Uptime = re.search("ServerUptimeSeconds:\s+(.*)",result)
|
||||
if not Uptime:
|
||||
return public.returnMsg(False, "Get worker Uptime False")
|
||||
return public.return_msg_gettext(False, "Get worker Uptime False")
|
||||
Uptime = int(Uptime.group(1))
|
||||
min = Uptime / 60
|
||||
hours = min / 60
|
||||
@@ -65,16 +65,16 @@ class apache:
|
||||
#格式化重启时间
|
||||
restarttime = re.search("RestartTime:\s+(.*)",result)
|
||||
if not restarttime:
|
||||
return public.returnMsg(False, "Get worker Restart Time False")
|
||||
return public.return_msg_gettext(False, "Get worker Restart Time False")
|
||||
restarttime = restarttime.group(1)
|
||||
rep = "\w+,\s([\w-]+)\s([\d\:]+)\s\w+"
|
||||
date = re.search(rep,restarttime)
|
||||
if not date:
|
||||
return public.returnMsg(False, "Get worker date False")
|
||||
return public.return_msg_gettext(False, "Get worker date False")
|
||||
date = date.group(1)
|
||||
timedetail = re.search(rep,restarttime)
|
||||
if not timedetail:
|
||||
return public.returnMsg(False, "Get worker time detail False")
|
||||
return public.return_msg_gettext(False, "Get worker time detail False")
|
||||
timedetail=timedetail.group(2)
|
||||
monthen = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
|
||||
n = 0
|
||||
@@ -87,7 +87,7 @@ class apache:
|
||||
|
||||
reqpersec = re.search("ReqPerSec:\s+(.*)", result)
|
||||
if not reqpersec:
|
||||
return public.returnMsg(False, "Get worker reqpersec False")
|
||||
return public.return_msg_gettext(False, "Get worker reqpersec False")
|
||||
reqpersec = reqpersec.group(1)
|
||||
if re.match("^\.", reqpersec):
|
||||
reqpersec = "%s%s" % (0,reqpersec)
|
||||
@@ -95,20 +95,20 @@ class apache:
|
||||
data["UpTime"] = "%s day %s hour %s minute" % (str(int(days)),str(int(hours)),str(int(min)))
|
||||
total_acc = re.search("Total Accesses:\s+(\d+)",result)
|
||||
if not total_acc:
|
||||
return public.returnMsg(False, "Get worker TotalAccesses False")
|
||||
return public.return_msg_gettext(False, "Get worker TotalAccesses False")
|
||||
data["TotalAccesses"] = total_acc.group(1)
|
||||
total_kb = re.search("Total kBytes:\s+(\d+)",result)
|
||||
if not total_kb:
|
||||
return public.returnMsg(False, "Get worker TotalKBytes False")
|
||||
return public.return_msg_gettext(False, "Get worker TotalKBytes False")
|
||||
data["TotalKBytes"] = total_kb.group(1)
|
||||
data["ReqPerSec"] = round(float(reqpersec), 2)
|
||||
busywork = re.search("BusyWorkers:\s+(\d+)",result)
|
||||
if not busywork:
|
||||
return public.returnMsg(False, "Get worker BusyWorkers False")
|
||||
return public.return_msg_gettext(False, "Get worker BusyWorkers False")
|
||||
data["BusyWorkers"] = busywork.group(1)
|
||||
idlework = re.search("IdleWorkers:\s+(\d+)",result)
|
||||
if not idlework:
|
||||
return public.returnMsg(False, "Get worker IdleWorkers False")
|
||||
return public.return_msg_gettext(False, "Get worker IdleWorkers False")
|
||||
data["IdleWorkers"] = idlework.group(1)
|
||||
data["workercpu"] = round(float(process_cpu["httpd"]),2)
|
||||
data["workermem"] = "%s%s" % (int(workermen),"MB")
|
||||
@@ -120,10 +120,10 @@ class apache:
|
||||
if not "mpm_event_module" in apachempmcontent:
|
||||
return public.returnMsg(False,"mpm_event_module conf not found or /www/server/apache/conf/extra/httpd-mpm.conf is empty")
|
||||
apachempmcontent = re.search("\<IfModule mpm_event_module\>(\n|.)+?\</IfModule\>",apachempmcontent).group()
|
||||
ps = ["%s,%s" % (public.GetMsg("SECOND"),public.GetMsg("REQUEST_TIMEOUT_TIME")),
|
||||
public.GetMsg("KEEP_ALIVE"),
|
||||
"%s,%s" % (public.GetMsg("SECOND"),public.GetMsg("CONNECT_TIMEOUT_TIME")),
|
||||
public.GetMsg("MAX_KEEP_ALIVE_REQUESTS")]
|
||||
ps = ["%s,%s" % (public.get_msg_gettext('Second'),public.get_msg_gettext('Request timeout')),
|
||||
public.get_msg_gettext('Keep alive'),
|
||||
"%s,%s" % (public.get_msg_gettext('Second'),public.get_msg_gettext('Connection timeout')),
|
||||
public.get_msg_gettext('Max keep-alive requests per connection')]
|
||||
gets = ["Timeout","KeepAlive","KeepAliveTimeout","MaxKeepAliveRequests"]
|
||||
if public.get_webserver() == 'apache':
|
||||
shutil.copyfile(self.apachedefaultfile, '/tmp/apdefault_file_bk.conf')
|
||||
@@ -134,34 +134,34 @@ class apache:
|
||||
rep = "(%s)\s+(\w+)" % i
|
||||
k = re.search(rep, apachedefaultcontent)
|
||||
if not k:
|
||||
return public.returnMsg(False, "Get Key {} False".format(k))
|
||||
return public.return_msg_gettext(False, "Get Key {} False",(i,))
|
||||
k = k.group(1)
|
||||
v = re.search(rep, apachedefaultcontent)
|
||||
if not v:
|
||||
return public.returnMsg(False, "Get Value {} False".format(v))
|
||||
return public.return_msg_gettext(False, "Get Value {} False",(v,))
|
||||
v = v.group(2)
|
||||
psstr = ps[n]
|
||||
kv = {"name":k,"value":v,"ps":psstr}
|
||||
conflist.append(kv)
|
||||
n += 1
|
||||
|
||||
ps = [public.GetMsg("DEFUALT_PROCESSES"),
|
||||
public.GetMsg("MAX_SPARE_THREADS"),
|
||||
public.GetMsg("MIN_SPARE_THREADS"),
|
||||
public.GetMsg("THREADS_PER_CHILD"),
|
||||
public.GetMsg("MAX_REQUEST_WORKERS"),
|
||||
public.GetMsg("MaxConnectionsPerChild")]
|
||||
ps = [public.get_msg_gettext('Default processes'),
|
||||
public.get_msg_gettext('Maximum number of idle threads'),
|
||||
public.get_msg_gettext('Minimum number of idle threads available to handle request spikes'),
|
||||
public.get_msg_gettext('Number of threads created by each child process'),
|
||||
public.get_msg_gettext('Maximum number of connections that will be processed simultaneously'),
|
||||
public.get_msg_gettext('Limit on the number of connections that an individual child server will handle during its life')]
|
||||
gets = ["StartServers","MaxSpareThreads","MinSpareThreads","ThreadsPerChild","MaxRequestWorkers","MaxConnectionsPerChild"]
|
||||
n = 0
|
||||
for i in gets:
|
||||
rep = "(%s)\s+(\w+)" % i
|
||||
k = re.search(rep, apachempmcontent)
|
||||
if not k:
|
||||
return public.returnMsg(False, "Get Key {} False".format(k))
|
||||
return public.return_msg_gettext(False, "Get Key {} False",(i,))
|
||||
k = k.group(1)
|
||||
v = re.search(rep, apachempmcontent)
|
||||
if not v:
|
||||
return public.returnMsg(False, "Get Value {} False".format(v))
|
||||
return public.return_msg_gettext(False, "Get Value {} False",(v,))
|
||||
v = v.group(2)
|
||||
psstr = ps[n]
|
||||
kv = {"name": k, "value": v, "ps": psstr}
|
||||
@@ -173,7 +173,7 @@ class apache:
|
||||
apachedefaultcontent = public.readFile(self.apachedefaultfile)
|
||||
apachempmcontent = public.readFile(self.apachempmfile)
|
||||
if not "mpm_event_module" in apachempmcontent:
|
||||
return public.returnMsg(False,"mpm_event_module conf not found or /www/server/apache/conf/extra/httpd-mpm.conf is empty")
|
||||
return public.return_msg_gettext(False,"mpm_event_module conf not found or /www/server/apache/conf/extra/httpd-mpm.conf is empty")
|
||||
conflist = []
|
||||
getdict = get.__dict__
|
||||
for i in getdict.keys():
|
||||
@@ -186,12 +186,12 @@ class apache:
|
||||
for c in conflist:
|
||||
if c["name"] == "KeepAlive":
|
||||
if not re.search("on|off", c["value"]):
|
||||
return public.returnMsg(False, "INIT_ARGS_ERR")
|
||||
return public.return_msg_gettext(False, 'Parameter ERROR!')
|
||||
else:
|
||||
print(c["value"])
|
||||
if not re.search("\d+", c["value"]):
|
||||
print(c["name"],c["value"])
|
||||
return public.returnMsg(False, 'INIT_ARGS_ERR')
|
||||
return public.return_msg_gettext(False, 'Parameter ERROR!')
|
||||
|
||||
rep = "%s\s+\w+" % c["name"]
|
||||
if re.search(rep,apachedefaultcontent):
|
||||
@@ -206,10 +206,10 @@ class apache:
|
||||
if (isError != True):
|
||||
shutil.copyfile('/tmp/_file_bk.conf', self.apachedefaultfile)
|
||||
shutil.copyfile('/tmp/proxyfile_bk.conf', self.apachempmfile)
|
||||
return public.returnMsg(False, 'ERROR: %s<br><a style="color:red;">' % public.GetMsg("CONFIG_ERROR") + isError.replace("\n",
|
||||
return public.returnMsg(False, 'ERROR: %s<br><a style="color:red;">' % public.get_msg_gettext('Configuration ERROR') + isError.replace("\n",
|
||||
'<br>') + '</a>')
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
def add_httpd_access_log_format(self,args):
|
||||
'''
|
||||
@@ -232,12 +232,12 @@ class apache:
|
||||
self.del_httpd_access_log_format(args)
|
||||
conf = public.readFile(self.httpdconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False,'CONF_FILE_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False,'Configuration file not exist')
|
||||
reg = '<IfModule log_config_module>'
|
||||
conf = re.sub(reg,'<IfModule log_config_module>'+data,conf)
|
||||
public.writeFile(self.httpdconf,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
except:
|
||||
return public.returnMsg(False, str(public.get_error_info()))
|
||||
|
||||
@@ -249,13 +249,13 @@ class apache:
|
||||
'''
|
||||
conf = public.readFile(self.httpdconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'CONF_FILE_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Configuration file not exist')
|
||||
reg = '\s*#LOG_FORMAT_BEGIN_{n}(\n|.)+#LOG_FORMAT_END_{n}\n?'.format(n=args.log_format_name)
|
||||
conf = re.sub(reg,'',conf)
|
||||
self._del_format_log_of_website(args.log_format_name)
|
||||
public.writeFile(self.httpdconf,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
def del_all_log_format(self,args):
|
||||
all_format = self.get_httpd_access_log_format(args)
|
||||
@@ -318,7 +318,7 @@ class apache:
|
||||
reg = "#LOG_FORMAT_BEGIN.*"
|
||||
conf = public.readFile(self.httpdconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'CONF_FILE_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Configuration file not exist')
|
||||
data = re.findall(reg,conf)
|
||||
format_name = [i.split('LOG_FORMAT_BEGIN_')[-1] for i in data]
|
||||
format_log = {}
|
||||
@@ -349,7 +349,7 @@ class apache:
|
||||
website_conf_file = '/www/server/panel/vhost/apache/{}.conf'.format(site['name'])
|
||||
conf = public.readFile(website_conf_file)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'CONF_FILE_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Configuration file not exist')
|
||||
format_exist_reg = '(CustomLog\s+"/www.*\_log).*'
|
||||
access_log = re.search(format_exist_reg, conf).groups()[0] + '" ' + args.log_format_name
|
||||
if site['name'] not in sites and re.search(format_exist_reg,conf):
|
||||
@@ -360,7 +360,7 @@ class apache:
|
||||
conf = re.sub(format_exist_reg,access_log,conf)
|
||||
public.writeFile(website_conf_file,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
except:
|
||||
return public.returnMsg(False, str(public.get_error_info()))
|
||||
|
||||
|
||||
+71
-44
@@ -40,6 +40,7 @@ class SimpleCache(BaseCache):
|
||||
toremove.append(key)
|
||||
for key in toremove:
|
||||
self._cache.pop(key, None)
|
||||
self.del_session_by_file(key)
|
||||
|
||||
|
||||
def _normalize_timeout(self, timeout):
|
||||
@@ -48,70 +49,87 @@ class SimpleCache(BaseCache):
|
||||
timeout = time() + timeout
|
||||
return timeout
|
||||
|
||||
def get(self, key):
|
||||
try:
|
||||
|
||||
expires, value = self._cache[key]
|
||||
if expires == 0 or expires > time():
|
||||
return pickle.loads(value)
|
||||
|
||||
except (KeyError, pickle.PickleError):
|
||||
try:
|
||||
if key[:4] == self.__session_key:
|
||||
filename = '/'.join((self.__session_basedir,self.md5(key)))
|
||||
if not os.path.exists(filename): return None
|
||||
|
||||
with open(filename, 'rb') as fp:
|
||||
_val = fp.read()
|
||||
fp.close()
|
||||
|
||||
expires = struct.unpack('f',_val[:4])[0]
|
||||
if expires == 0 or expires > time():
|
||||
value = _val[4:]
|
||||
|
||||
self._cache[key] = (expires,value)
|
||||
return pickle.loads(value)
|
||||
except :pass
|
||||
return None
|
||||
|
||||
def set(self, key, value, timeout=None):
|
||||
|
||||
expires = self._normalize_timeout(timeout)
|
||||
self._prune()
|
||||
|
||||
_val = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
|
||||
self._cache[key] = (expires,_val)
|
||||
def get_session_by_file(self,key):
|
||||
try:
|
||||
if key[:4] == self.__session_key:
|
||||
filename = '/'.join((self.__session_basedir,self.md5(key)))
|
||||
if not os.path.exists(filename): return None
|
||||
|
||||
with open(filename, 'rb') as fp:
|
||||
_val = fp.read()
|
||||
fp.close()
|
||||
expires = struct.unpack('f',_val[:4])[0]
|
||||
if expires == 0 or expires > time():
|
||||
value = _val[4:]
|
||||
|
||||
self._cache[key] = (expires,value)
|
||||
return pickle.loads(value)
|
||||
except :pass
|
||||
|
||||
def set_session_by_file(self,key,_val,expires):
|
||||
try:
|
||||
if key[:4] == self.__session_key:
|
||||
if len(_val) < 256: return True
|
||||
if not os.path.exists(self.__session_basedir): os.makedirs(self.__session_basedir,384)
|
||||
|
||||
expires = struct.pack('f',expires)
|
||||
filename = '/'.join((self.__session_basedir,self.md5(key)))
|
||||
filename = '/'.join((self.__session_basedir,self.md5(key)))
|
||||
fp = open(filename, 'wb+')
|
||||
fp.write(expires + _val)
|
||||
fp.close()
|
||||
os.chmod(filename,384)
|
||||
except :pass
|
||||
|
||||
def del_session_by_file(self,key):
|
||||
try:
|
||||
if key[:4] == self.__session_key:
|
||||
filename = '/'.join((self.__session_basedir,self.md5(key)))
|
||||
if os.path.exists(filename): os.remove(filename)
|
||||
except : pass
|
||||
|
||||
def get(self, key):
|
||||
if not isinstance(key,str): return None
|
||||
try:
|
||||
expires, value = self._cache[key]
|
||||
if expires == 0 or expires > time():
|
||||
return pickle.loads(value)
|
||||
except (KeyError, pickle.PickleError):
|
||||
return self.get_session_by_file(key)
|
||||
|
||||
def set(self, key, value, timeout=None):
|
||||
|
||||
# 类型判断
|
||||
if not isinstance(key,str): return False
|
||||
type_list=(int,float,bool,str,list,dict,tuple,set,bytes)
|
||||
if not isinstance(value,type_list): return False
|
||||
|
||||
# 过期清理
|
||||
expires = self._normalize_timeout(timeout)
|
||||
self._prune()
|
||||
|
||||
# 转换
|
||||
_val = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
|
||||
self._cache[key] = (expires,_val)
|
||||
self.set_session_by_file(key,_val,expires)
|
||||
return True
|
||||
|
||||
def add(self, key, value, timeout=None):
|
||||
|
||||
# 类型判断
|
||||
if not isinstance(key,str): return False
|
||||
type_list=(int,float,bool,str,list,dict,tuple,set,bytes)
|
||||
if not isinstance(value,type_list): return False
|
||||
|
||||
expires = self._normalize_timeout(timeout)
|
||||
self._prune()
|
||||
item = (expires, pickle.dumps(value,
|
||||
pickle.HIGHEST_PROTOCOL))
|
||||
item = (expires, pickle.dumps(value,pickle.HIGHEST_PROTOCOL))
|
||||
if key in self._cache:
|
||||
return False
|
||||
self._cache.setdefault(key, item)
|
||||
self.set_session_by_file(key,item[1],expires)
|
||||
return True
|
||||
|
||||
def delete(self, key):
|
||||
result = self._cache.pop(key, None) is not None
|
||||
try:
|
||||
if key[:4] == self.__session_key:
|
||||
filename = '/'.join((self.__session_basedir,self.md5(key)))
|
||||
if os.path.exists(filename): os.remove(filename)
|
||||
except : pass
|
||||
self.del_session_by_file(key)
|
||||
return result
|
||||
|
||||
def has(self, key):
|
||||
@@ -119,8 +137,17 @@ class SimpleCache(BaseCache):
|
||||
expires, value = self._cache[key]
|
||||
return expires == 0 or expires > time()
|
||||
except KeyError:
|
||||
if self.get_session_by_file(key): return True
|
||||
return False
|
||||
|
||||
|
||||
def get_expire_time(self, key):
|
||||
try:
|
||||
expires, value = self._cache[key]
|
||||
return expires
|
||||
except KeyError:
|
||||
return 0
|
||||
|
||||
def md5(self,strings):
|
||||
"""
|
||||
生成MD5
|
||||
@@ -129,7 +156,7 @@ class SimpleCache(BaseCache):
|
||||
"""
|
||||
import hashlib
|
||||
m = hashlib.md5()
|
||||
|
||||
|
||||
m.update(strings.encode('utf-8'))
|
||||
return m.hexdigest()
|
||||
|
||||
|
||||
+26
-19
@@ -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.21'
|
||||
g.version = '6.8.27'
|
||||
g.title = public.GetConfigValue('title')
|
||||
g.uri = request.path
|
||||
g.debug = os.path.exists('data/debug.pl')
|
||||
@@ -98,9 +98,9 @@ class panelAdmin(panelSetup):
|
||||
if request.method == 'GET':
|
||||
g.menus = public.get_menus()
|
||||
g.yaer = datetime.now().year
|
||||
session["top_tips"] = public.GetMsg("TOP_TIPS")
|
||||
session["bt_help"] = public.GetMsg("BT_HELP")
|
||||
session["download"] = public.GetMsg("DOWNLOAD")
|
||||
session["top_tips"] = public.get_msg_gettext("The current IE browser version is too low to display some features, please use another browser. Or if you use a browser developed by a Chinese company, please switch to Extreme Mode!")
|
||||
session["bt_help"] = public.get_msg_gettext("For Support|Suggestions, please visit the aaPanel Forum")
|
||||
session["download"] = public.get_msg_gettext("Downloading:")
|
||||
if not 'brand' in session:
|
||||
session['brand'] = public.GetConfigValue('brand')
|
||||
session['product'] = public.GetConfigValue('product')
|
||||
@@ -114,7 +114,7 @@ class panelAdmin(panelSetup):
|
||||
if not 'lan' in session:
|
||||
session['lan'] = public.GetLanguage()
|
||||
if not 'home' in session:
|
||||
session['home'] = 'https://brandnew.aapanel.com'
|
||||
session['home'] = 'https://www.aapanel.com'
|
||||
return False
|
||||
|
||||
# 检查Web服务器类型
|
||||
@@ -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:
|
||||
@@ -203,54 +203,61 @@ class panelAdmin(panelSetup):
|
||||
def get_sk(self):
|
||||
save_path = '/www/server/panel/config/api.json'
|
||||
if not os.path.exists(save_path):
|
||||
return redirect('/login')
|
||||
return public.error_not_login('/login')
|
||||
|
||||
|
||||
try:
|
||||
api_config = json.loads(public.ReadFile(save_path))
|
||||
except:
|
||||
os.remove(save_path)
|
||||
return redirect('/login')
|
||||
return public.error_not_login('/login')
|
||||
|
||||
if not api_config['open']:
|
||||
return redirect('/login')
|
||||
return public.error_not_login('/login')
|
||||
from BTPanel import get_input
|
||||
get = get_input()
|
||||
client_ip = public.GetClientIp()
|
||||
if not 'client_bind_token' in get:
|
||||
if not 'request_token' in get or not 'request_time' in get:
|
||||
return redirect('/login')
|
||||
return public.error_not_login('/login')
|
||||
|
||||
num_key = client_ip + '_api'
|
||||
if not public.get_error_num(num_key,20):
|
||||
return public.returnJson(False,'AUTH_FAILED1')
|
||||
return public.returnJson(False,'20 consecutive verification failures, prohibited for 1 hour')
|
||||
|
||||
|
||||
if not client_ip in api_config['limit_addr']:
|
||||
if not public.is_api_limit_ip(api_config['limit_addr'],client_ip): #client_ip in api_config['limit_addr']:
|
||||
public.set_error_num(num_key)
|
||||
return public.returnJson(False,'%s[' % public.GetMsg("AUTH_FAILED1")+client_ip+']')
|
||||
return public.returnJson(False,'%s[' % public.get_msg_gettext("20 consecutive verification failures, prohibited for 1 hour")+client_ip+']')
|
||||
else:
|
||||
num_key = client_ip + '_app'
|
||||
if not public.get_error_num(num_key,20):
|
||||
return public.returnJson(False,'AUTH_FAILED1')
|
||||
return public.returnJson(False,'20 consecutive verification failures, prohibited for 1 hour')
|
||||
a_file = '/dev/shm/' + get.client_bind_token
|
||||
|
||||
if not public.path_safe_check(get.client_bind_token):
|
||||
public.set_error_num(num_key)
|
||||
return public.returnJson(False, 'illegal request')
|
||||
|
||||
if not os.path.exists(a_file):
|
||||
import panelApi
|
||||
if not panelApi.panelApi().get_app_find(get.client_bind_token):
|
||||
public.set_error_num(num_key)
|
||||
return public.returnJson(False,'UNBOUND_DEVICE')
|
||||
return public.returnJson(False,'Unbound device')
|
||||
public.writeFile(a_file,'')
|
||||
|
||||
if not 'key' in api_config:
|
||||
public.set_error_num(num_key)
|
||||
return public.returnJson(False, 'KEY_ERR')
|
||||
return public.returnJson(False, 'Key verification failed')
|
||||
if not 'form_data' in get:
|
||||
public.set_error_num(num_key)
|
||||
return public.returnJson(False, 'FORM_DATA_ERR')
|
||||
return public.returnJson(False, 'No form_data data found')
|
||||
|
||||
g.form_data = json.loads(public.aes_decrypt(get.form_data, api_config['key']))
|
||||
|
||||
get = get_input()
|
||||
if not 'request_token' in get or not 'request_time' in get:
|
||||
return redirect('/login')
|
||||
return public.error_not_login('/login')
|
||||
g.is_aes = True
|
||||
g.aes_key = api_config['key']
|
||||
request_token = public.md5(get.request_time + api_config['token'])
|
||||
@@ -258,7 +265,7 @@ class panelAdmin(panelSetup):
|
||||
public.set_error_num(num_key,True)
|
||||
return False
|
||||
public.set_error_num(num_key)
|
||||
return public.returnJson(False,'SECRET_KEY_CHECK_FALSE')
|
||||
return public.returnJson(False,'Secret key verification failed')
|
||||
|
||||
# 检查系统配置
|
||||
|
||||
|
||||
+534
-260
File diff suppressed because it is too large
Load Diff
+51
-51
@@ -33,27 +33,27 @@ class crontab:
|
||||
tmp = {}
|
||||
tmp=cront[i]
|
||||
if cront[i]['type']=="day":
|
||||
tmp['type']=public.getMsg('CRONTAB_TODAY')
|
||||
tmp['cycle']= public.getMsg('CRONTAB_TODAY_CYCLE',(str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
tmp['type']=public.get_msg_gettext('Per Day')
|
||||
tmp['cycle']= public.get_msg_gettext('Per Day, run at {} Hour {} Min',(str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
elif cront[i]['type']=="day-n":
|
||||
tmp['type']=public.getMsg('CRONTAB_N_TODAY',(str(cront[i]['where1']),))
|
||||
tmp['cycle']=public.getMsg('CRONTAB_N_TODAY_CYCLE',(str(cront[i]['where1']),str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
tmp['type']=public.get_msg_gettext('Every {} Days',(str(cront[i]['where1']),))
|
||||
tmp['cycle']=public.get_msg_gettext('Every {} Days, run at {} Hour {} Min',(str(cront[i]['where1']),str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
elif cront[i]['type']=="hour":
|
||||
tmp['type']=public.getMsg('CRONTAB_HOUR')
|
||||
tmp['cycle']=public.getMsg('CRONTAB_HOUR_CYCLE',(str(cront[i]['where_minute']),))
|
||||
tmp['type']=public.get_msg_gettext('Per Hour')
|
||||
tmp['cycle']=public.get_msg_gettext('Per Hour, run at {} Min',(str(cront[i]['where_minute']),))
|
||||
elif cront[i]['type']=="hour-n":
|
||||
tmp['type']=public.getMsg('CRONTAB_N_HOUR',(str(cront[i]['where1']),))
|
||||
tmp['cycle']=public.getMsg('CRONTAB_N_HOUR_CYCLE',(str(cront[i]['where1']),str(cront[i]['where_minute'])))
|
||||
tmp['type']=public.get_msg_gettext('Every {} Hours',(str(cront[i]['where1']),))
|
||||
tmp['cycle']=public.get_msg_gettext('Every {} Hours, run at {} Min',(str(cront[i]['where1']),str(cront[i]['where_minute'])))
|
||||
elif cront[i]['type']=="minute-n":
|
||||
tmp['type']=public.getMsg('CRONTAB_N_MINUTE',(str(cront[i]['where1']),))
|
||||
tmp['cycle']=public.getMsg('CRONTAB_N_MINUTE_CYCLE',(str(cront[i]['where1']),))
|
||||
tmp['type']=public.get_msg_gettext('Every {} Minutes',(str(cront[i]['where1']),))
|
||||
tmp['cycle']=public.get_msg_gettext('Run Every {} Minutes',(str(cront[i]['where1']),))
|
||||
elif cront[i]['type']=="week":
|
||||
tmp['type']=public.getMsg('CRONTAB_WEEK')
|
||||
tmp['type']=public.get_msg_gettext('Weekly')
|
||||
if not cront[i]['where1']: cront[i]['where1'] = '0'
|
||||
tmp['cycle']= public.getMsg('CRONTAB_WEEK_CYCLE',(self.toWeek(int(cront[i]['where1'])),str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
tmp['cycle']= public.get_msg_gettext('Every {}, run at {} Hour {} Min',(self.toWeek(int(cront[i]['where1'])),str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
elif cront[i]['type']=="month":
|
||||
tmp['type']=public.getMsg('CRONTAB_MONTH')
|
||||
tmp['cycle']=public.getMsg('CRONTAB_MONTH_CYCLE',(str(cront[i]['where1']),str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
tmp['type']=public.get_msg_gettext('Monthly')
|
||||
tmp['cycle']=public.get_msg_gettext('Monthly, run on {}Day {} Hour {}Min',(str(cront[i]['where1']),str(cront[i]['where_hour']),str(cront[i]['where_minute'])))
|
||||
|
||||
log_file = '/www/server/cron/{}.log'.format(tmp['echo'])
|
||||
if os.path.exists(log_file):
|
||||
@@ -80,13 +80,13 @@ class crontab:
|
||||
#转换大写星期
|
||||
def toWeek(self,num):
|
||||
wheres={
|
||||
0 : public.getMsg('CRONTAB_SUNDAY'),
|
||||
1 : public.getMsg('CRONTAB_MONDAY'),
|
||||
2 : public.getMsg('CRONTAB_TUESDAY'),
|
||||
3 : public.getMsg('CRONTAB_WEDNESDAY'),
|
||||
4 : public.getMsg('CRONTAB_THURSDAY'),
|
||||
5 : public.getMsg('CRONTAB_FRIDAY'),
|
||||
6 : public.getMsg('CRONTAB_SATURDAY')
|
||||
0 : public.get_msg_gettext('Sunday'),
|
||||
1 : public.get_msg_gettext('Monday'),
|
||||
2 : public.get_msg_gettext('Tuesday'),
|
||||
3 : public.get_msg_gettext('Wednesday'),
|
||||
4 : public.get_msg_gettext('Thursday'),
|
||||
5 : public.get_msg_gettext('Friday'),
|
||||
6 : public.get_msg_gettext('Saturday')
|
||||
}
|
||||
try:
|
||||
return wheres[num]
|
||||
@@ -132,12 +132,12 @@ class crontab:
|
||||
|
||||
public.M('crontab').where('id=?',(id,)).setField('status',status)
|
||||
public.WriteLog('TYPE_CRON',"MODIFY_CRON_STATUS",(cronInfo['name'],str(status_msg[status])))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
#修改计划任务
|
||||
def modify_crond(self,get):
|
||||
if len(get['name'])<1:
|
||||
return public.returnMsg(False,'CRONTAB_TASKNAME_EMPTY')
|
||||
return public.return_msg_gettext(False,'Name of task cannot be empty!')
|
||||
id = get['id']
|
||||
cuonConfig,get,name = self.GetCrondCycle(get)
|
||||
cronInfo = public.M('crontab').where('id=?',(id,)).field(self.field).find()
|
||||
@@ -167,7 +167,7 @@ class crontab:
|
||||
self.remove_for_crond(cronInfo['echo'])
|
||||
self.sync_to_crond(cronInfo)
|
||||
public.WriteLog('TYPE_CRON',"MODIFY_CRON",(cronInfo['name']))
|
||||
return public.returnMsg(True,'EDIT_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
#获取指定任务数据
|
||||
@@ -196,7 +196,7 @@ class crontab:
|
||||
#添加计划任务
|
||||
def AddCrontab(self,get):
|
||||
if len(get['name'])<1:
|
||||
return public.returnMsg(False,'CRONTAB_TASKNAME_EMPTY')
|
||||
return public.return_msg_gettext(False,'Name of task cannot be empty!')
|
||||
cuonConfig,get,name = self.GetCrondCycle(get)
|
||||
cronPath=public.GetConfigValue('setup_path')+'/cron'
|
||||
cronName=self.GetShell(get)
|
||||
@@ -208,22 +208,22 @@ class crontab:
|
||||
self.CrondReload()
|
||||
columns = 'name,type,where1,where_hour,where_minute,echo,addtime,\
|
||||
status,save,backupTo,sType,sName,sBody,urladdress'
|
||||
values = (public.xssencode(get['name']),get['type'],get['where1'],get['hour'],
|
||||
values = (public.xssencode2(get['name']),get['type'],get['where1'],get['hour'],
|
||||
get['minute'],cronName,time.strftime('%Y-%m-%d %X',time.localtime()),
|
||||
1,get['save'],get['backupTo'],get['sType'],get['sName'],get['sBody'],
|
||||
get['urladdress'])
|
||||
if "save_local" in get:
|
||||
columns += ",save_local,notice,notice_channel"
|
||||
values = (public.xssencode(get['name']),get['type'],get['where1'],get['hour'],
|
||||
values = (public.xssencode2(get['name']),get['type'],get['where1'],get['hour'],
|
||||
get['minute'],cronName,time.strftime('%Y-%m-%d %X',time.localtime()),
|
||||
1,get['save'],get['backupTo'],get['sType'],get['sName'],get['sBody'],
|
||||
get['urladdress'], get["save_local"], get['notice'], get['notice_channel'])
|
||||
addData=public.M('crontab').add(columns,values)
|
||||
if addData>0:
|
||||
result = public.returnMsg(True,'ADD_SUCCESS')
|
||||
result = public.return_msg_gettext(True,'Setup successfully!')
|
||||
result['id'] = addData
|
||||
return result
|
||||
return public.returnMsg(False,'ADD_ERROR')
|
||||
return public.return_msg_gettext(False,'Failed to add')
|
||||
|
||||
#构造周期
|
||||
def GetCrondCycle(self,params):
|
||||
@@ -231,16 +231,16 @@ class crontab:
|
||||
name = ""
|
||||
if params['type']=="day":
|
||||
cuonConfig = self.GetDay(params)
|
||||
name = public.getMsg('CRONTAB_TODAY')
|
||||
name = public.get_msg_gettext('Per Day')
|
||||
elif params['type']=="day-n":
|
||||
cuonConfig = self.GetDay_N(params)
|
||||
name = public.getMsg('CRONTAB_N_TODAY',(params['where1'],))
|
||||
name = public.get_msg_gettext('Every {0} Days',(params['where1'],))
|
||||
elif params['type']=="hour":
|
||||
cuonConfig = self.GetHour(params)
|
||||
name = public.getMsg('CRONTAB_HOUR')
|
||||
name = public.get_msg_gettext('Per Hour')
|
||||
elif params['type']=="hour-n":
|
||||
cuonConfig = self.GetHour_N(params)
|
||||
name = public.getMsg('CRONTAB_HOUR')
|
||||
name = public.get_msg_gettext('Per Hour')
|
||||
elif params['type']=="minute-n":
|
||||
cuonConfig = self.Minute_N(params)
|
||||
elif params['type']=="week":
|
||||
@@ -252,36 +252,36 @@ class crontab:
|
||||
|
||||
#取任务构造Day
|
||||
def GetDay(self,param):
|
||||
cuonConfig ="{0} {1} * * * ".format(param['minute'],param['hour'])
|
||||
cuonConfig ="{} {} * * * ".format(param['minute'],param['hour'])
|
||||
return cuonConfig
|
||||
#取任务构造Day_n
|
||||
def GetDay_N(self,param):
|
||||
cuonConfig ="{0} {1} */{2} * * ".format(param['minute'],param['hour'],param['where1'])
|
||||
cuonConfig ="{} {} */{} * * ".format(param['minute'],param['hour'],param['where1'])
|
||||
return cuonConfig
|
||||
|
||||
#取任务构造Hour
|
||||
def GetHour(self,param):
|
||||
cuonConfig ="{0} * * * * ".format(param['minute'])
|
||||
cuonConfig ="{} * * * * ".format(param['minute'])
|
||||
return cuonConfig
|
||||
|
||||
#取任务构造Hour-N
|
||||
def GetHour_N(self,param):
|
||||
cuonConfig ="{0} */{1} * * * ".format(param['minute'],param['where1'])
|
||||
cuonConfig ="{} */{} * * * ".format(param['minute'],param['where1'])
|
||||
return cuonConfig
|
||||
|
||||
#取任务构造Minute-N
|
||||
def Minute_N(self,param):
|
||||
cuonConfig ="*/{0} * * * * ".format(param['where1'])
|
||||
cuonConfig ="*/{} * * * * ".format(param['where1'])
|
||||
return cuonConfig
|
||||
|
||||
#取任务构造week
|
||||
def Week(self,param):
|
||||
cuonConfig ="{0} {1} * * {2}".format(param['minute'],param['hour'],param['week'])
|
||||
cuonConfig ="{} {} * * {}".format(param['minute'],param['hour'],param['week'])
|
||||
return cuonConfig
|
||||
|
||||
#取任务构造Month
|
||||
def Month(self,param):
|
||||
cuonConfig = "{0} {1} {2} * * ".format(param['minute'],param['hour'],param['where1'])
|
||||
cuonConfig = "{} {} {} * * ".format(param['minute'],param['hour'],param['where1'])
|
||||
return cuonConfig
|
||||
|
||||
#取数据列表
|
||||
@@ -308,9 +308,9 @@ class crontab:
|
||||
id = get['id']
|
||||
echo = public.M('crontab').where("id=?",(id,)).field('echo').find()
|
||||
logFile = public.GetConfigValue('setup_path')+'/cron/'+echo['echo']+'.log'
|
||||
if not os.path.exists(logFile):return public.returnMsg(False, 'CRONTAB_TASKLOG_EMPTY')
|
||||
if not os.path.exists(logFile):return public.return_msg_gettext(False, 'log is empty')
|
||||
log = public.GetNumLines(logFile,2000)
|
||||
return public.returnMsg(True, log)
|
||||
return public.return_msg_gettext(True, log)
|
||||
|
||||
#清理任务日志
|
||||
def DelLogs(self,get):
|
||||
@@ -319,16 +319,16 @@ class crontab:
|
||||
echo = public.M('crontab').where("id=?",(id,)).getField('echo')
|
||||
logFile = public.GetConfigValue('setup_path')+'/cron/'+echo+'.log'
|
||||
os.remove(logFile)
|
||||
return public.returnMsg(True, 'CRONTAB_TASKLOG_CLOSE')
|
||||
return public.return_msg_gettext(True, 'Logs emptied')
|
||||
except:
|
||||
return public.returnMsg(False, 'CRONTAB_TASKLOG_CLOSE_ERR')
|
||||
return public.return_msg_gettext(False, 'Failed to empty task logs!')
|
||||
|
||||
#删除计划任务
|
||||
def DelCrontab(self,get):
|
||||
try:
|
||||
id = get['id']
|
||||
find = public.M('crontab').where("id=?",(id,)).field('name,echo').find()
|
||||
if not self.remove_for_crond(find['echo']): return public.returnMsg(False,'SYSSAFE_CANT_WRITE_FILE')
|
||||
if not self.remove_for_crond(find['echo']): return public.return_msg_gettext(False,'Unable to write to file, please check if system hardening is enabled!')
|
||||
cronPath = public.GetConfigValue('setup_path') + '/cron'
|
||||
sfile = cronPath + '/' + find['echo']
|
||||
if os.path.exists(sfile): os.remove(sfile)
|
||||
@@ -337,9 +337,9 @@ class crontab:
|
||||
|
||||
public.M('crontab').where("id=?",(id,)).delete()
|
||||
public.WriteLog('TYPE_CRON', 'CRONTAB_DEL',(find['name'],))
|
||||
return public.returnMsg(True, 'DEL_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Successfully deleted')
|
||||
except:
|
||||
return public.returnMsg(False, 'DEL_ERROR')
|
||||
return public.return_msg_gettext(False, 'Failed to delete')
|
||||
|
||||
#从crond删除
|
||||
def remove_for_crond(self,echo):
|
||||
@@ -419,7 +419,7 @@ echo "--------------------------------------------------------------------------
|
||||
public.ExecShell('chmod 750 ' + file)
|
||||
return cronName
|
||||
#except Exception as ex:
|
||||
#return public.returnMsg(False, 'FILE_WRITE_ERR' + str(ex))
|
||||
#return public.return_msg_gettext(False, 'Failed to write in file!' + str(ex))
|
||||
|
||||
#检查脚本
|
||||
def CheckScript(self,shell):
|
||||
@@ -443,7 +443,7 @@ echo "--------------------------------------------------------------------------
|
||||
file = self.get_cron_file()
|
||||
if not os.path.exists(file): public.writeFile(file,'')
|
||||
conf = public.readFile(file)
|
||||
if type(conf)==bool:return public.returnMsg(False,'Failed to read file!')
|
||||
if type(conf)==bool:return public.return_msg_gettext(False,'Failed to read file!')
|
||||
conf += config + "\n"
|
||||
if public.writeFile(file,conf):
|
||||
if not os.path.exists(u_file):
|
||||
@@ -451,7 +451,7 @@ echo "--------------------------------------------------------------------------
|
||||
else:
|
||||
public.ExecShell("chmod 600 '" + file + "' && chown root.crontab " + file)
|
||||
return True
|
||||
return public.returnMsg(False,'SYSSAFE_CANT_WRITE_FILE')
|
||||
return public.return_msg_gettext(False,'Unable to write to file, please check if system hardening is enabled!')
|
||||
|
||||
#立即执行任务
|
||||
def StartTask(self,get):
|
||||
@@ -459,7 +459,7 @@ echo "--------------------------------------------------------------------------
|
||||
execstr = public.GetConfigValue('setup_path') + '/cron/' + echo
|
||||
public.ExecShell('chmod +x ' + execstr)
|
||||
public.ExecShell('nohup ' + execstr + ' >> ' + execstr + '.log 2>&1 &')
|
||||
return public.returnMsg(True,'CRONTAB_TASK_EXEC')
|
||||
return public.return_msg_gettext(True,'Task has been executed!')
|
||||
|
||||
#获取计划任务文件位置
|
||||
def get_cron_file(self):
|
||||
|
||||
+151
-59
@@ -25,10 +25,10 @@ class data:
|
||||
'''
|
||||
def setPs(self,get):
|
||||
id = get.id
|
||||
get.ps = public.xssencode(get.ps)
|
||||
get.ps = public.xssencode2(get.ps)
|
||||
if public.M(get.table).where("id=?",(id,)).setField('ps',get.ps):
|
||||
return public.returnMsg(True,'EDIT_SUCCESS')
|
||||
return public.returnMsg(False,'EDIT_ERROR')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
return public.return_msg_gettext(False,'Failed to modify')
|
||||
|
||||
#端口扫描
|
||||
def CheckPort(self,port):
|
||||
@@ -142,7 +142,7 @@ class data:
|
||||
conf = public.readFile(
|
||||
self.setupPath + '/panel/vhost/' + self.web_server + '/detail/' + siteName + '.conf')
|
||||
if self.web_server == 'nginx':
|
||||
rep = r"enable-php-(\w{2,5})\.conf"
|
||||
rep = r"enable-php-(\w{2,5})[-\w]*\.conf"
|
||||
elif self.web_server == 'apache':
|
||||
rep = r"php-cgi-(\w{2,5})\.sock"
|
||||
else:
|
||||
@@ -172,6 +172,37 @@ class data:
|
||||
except:
|
||||
return 0
|
||||
|
||||
def get_site_quota(self,path):
|
||||
'''
|
||||
@name 获取网站目录配额信息
|
||||
@author hwliang<2022-02-15>
|
||||
@param path<string> 网站目录
|
||||
@return dict
|
||||
'''
|
||||
res = {'size':0 ,'used':0 }
|
||||
try:
|
||||
from projectModel.quotaModel import main
|
||||
quota_info = main().get_quota_path_list(get_path = path)
|
||||
if isinstance(quota_info,dict):
|
||||
return quota_info
|
||||
return res
|
||||
except: return res
|
||||
|
||||
def get_database_quota(self,db_name):
|
||||
'''
|
||||
@name 获取网站目录配额信息
|
||||
@author hwliang<2022-02-15>
|
||||
@param path<string> 网站目录
|
||||
@return dict
|
||||
'''
|
||||
res = {'size':0 ,'used':0 }
|
||||
try:
|
||||
from projectModel.quotaModel import main
|
||||
quota_info = main().get_quota_mysql_list(get_name = db_name)
|
||||
if isinstance(quota_info,dict):
|
||||
return quota_info
|
||||
return res
|
||||
except: return res
|
||||
|
||||
'''
|
||||
* 取数据列表
|
||||
@@ -181,6 +212,7 @@ class data:
|
||||
* @return Json page.分页数 , count.总行数 data.取回的数据
|
||||
'''
|
||||
def getData(self,get):
|
||||
import one_key_wp
|
||||
try:
|
||||
table = get.table
|
||||
data = self.GetSql(get)
|
||||
@@ -188,29 +220,55 @@ class data:
|
||||
|
||||
if table == 'backup':
|
||||
import os
|
||||
backup_path = public.M('config').where('id=?',(1,)).getField('backup_path')
|
||||
for i in range(len(data['data'])):
|
||||
if data['data'][i]['size'] == 0:
|
||||
if os.path.exists(data['data'][i]['filename']): data['data'][i]['size'] = os.path.getsize(data['data'][i]['filename'])
|
||||
if os.path.exists(data['data'][i]['filename']):
|
||||
data['data'][i]['size'] = os.path.getsize(data['data'][i]['filename'])
|
||||
else:
|
||||
if not os.path.exists(data['data'][i]['filename']):
|
||||
if (data['data'][i]['filename'].find('/www/') != -1 or data['data'][i]['filename'].find(backup_path) != -1) and data['data'][i]['filename'][0] == '/' and data['data'][i]['filename'].find('|') == -1:
|
||||
data['data'][i]['size'] = 0
|
||||
data['data'][i]['ps'] = public.get_msg_gettext("File does not exist!")
|
||||
|
||||
elif table == 'sites' or table == 'databases':
|
||||
type = '0'
|
||||
if table == 'databases': type = '1'
|
||||
for i in range(len(data['data'])):
|
||||
data['data'][i]['backup_count'] = SQL.table('backup').where("pid=? AND type=?",(data['data'][i]['id'],type)).count()
|
||||
if table == 'databases': data['data'][i]['conn_config'] = json.loads(data['data'][i]['conn_config'])
|
||||
data['data'][i]['quota'] = self.get_database_quota(data['data'][i]['name'])
|
||||
if table == 'sites':
|
||||
for i in range(len(data['data'])):
|
||||
data['data'][i]['domain'] = SQL.table('domain').where("pid=?",(data['data'][i]['id'],)).count()
|
||||
data['data'][i]['ssl'] = self.get_site_ssl_info(data['data'][i]['name'])
|
||||
data['data'][i]['php_version'] = self.get_php_version(data['data'][i]['name'])
|
||||
data['data'][i]['attack'] = self.get_analysis(get,data['data'][i])
|
||||
data['data'][i]['project_type'] = SQL.table('sites').where('id=?',(data['data'][i]['id'])).field('project_type').find()['project_type']
|
||||
if data['data'][i]['project_type'] == 'WP':
|
||||
data['data'][i]['cache_status'] = one_key_wp.one_key_wp().get_cache_status(data['data'][i]['id'])
|
||||
if not data['data'][i]['status'] in ['0','1',0,1]:
|
||||
data['data'][i]['status'] = '1'
|
||||
data['data'][i]['quota'] = self.get_site_quota(data['data'][i]['path'])
|
||||
elif table == 'firewall':
|
||||
for i in range(len(data['data'])):
|
||||
if data['data'][i]['port'].find(':') != -1 or data['data'][i]['port'].find('.') != -1 or data['data'][i]['port'].find('-') != -1:
|
||||
data['data'][i]['status'] = -1
|
||||
else:
|
||||
data['data'][i]['status'] = self.CheckPort(int(data['data'][i]['port']))
|
||||
|
||||
|
||||
elif table == 'ftps':
|
||||
for i in range(len(data['data'])):
|
||||
data['data'][i]['quota'] = self.get_site_quota(data['data'][i]['path'])
|
||||
|
||||
try:
|
||||
for _find in data['data']:
|
||||
_keys = _find.keys()
|
||||
for _key in _keys:
|
||||
_find[_key] = public.xsssec(_find[_key])
|
||||
except:
|
||||
pass
|
||||
|
||||
#返回
|
||||
return data
|
||||
except:
|
||||
@@ -229,15 +287,21 @@ class data:
|
||||
SQL = public.M(tableName)
|
||||
where = "id=?"
|
||||
find = SQL.where(where,(id,)).field(field).find()
|
||||
try:
|
||||
_keys = find.keys()
|
||||
for _key in _keys:
|
||||
find[_key] = public.xsssec(find[_key])
|
||||
except:
|
||||
pass
|
||||
return find
|
||||
|
||||
|
||||
|
||||
|
||||
'''
|
||||
* 取字段值
|
||||
* @param String _GET['tab'] 数据库表名
|
||||
* @param String _GET['key'] 字段
|
||||
* @param String _GET['id'] 条件ID
|
||||
* @return String
|
||||
* @return String
|
||||
'''
|
||||
def getKey(self,get):
|
||||
tableName = get.table
|
||||
@@ -246,7 +310,7 @@ class data:
|
||||
SQL = db.Sql().table(tableName)
|
||||
where = "id=?"
|
||||
retuls = SQL.where(where,(id,)).getField(keyName)
|
||||
return retuls
|
||||
return public.xsssec(retuls)
|
||||
|
||||
'''
|
||||
* 获取数据与分页
|
||||
@@ -259,117 +323,138 @@ class data:
|
||||
def GetSql(self,get,result = '1,2,3,4,5,8'):
|
||||
#判断前端是否传入参数
|
||||
order = "id desc"
|
||||
if hasattr(get,'order'):
|
||||
order = get.order
|
||||
|
||||
if hasattr(get,'order'):
|
||||
# 验证参数格式
|
||||
if re.match(r"^[\w\s\-\.]+$",get.order):
|
||||
order = get.order
|
||||
|
||||
limit = 20
|
||||
if hasattr(get,'limit'):
|
||||
if hasattr(get,'limit'):
|
||||
limit = int(get.limit)
|
||||
|
||||
if hasattr(get,'result'):
|
||||
result = get.result
|
||||
|
||||
if limit < 1: limit = 20
|
||||
|
||||
if hasattr(get,'result'):
|
||||
# 验证参数格式
|
||||
if re.match(r"^[\d\,]+$",get.result):
|
||||
result = get.result
|
||||
|
||||
SQL = db.Sql()
|
||||
data = {}
|
||||
#取查询条件
|
||||
where = ''
|
||||
param = ()
|
||||
if hasattr(get,'search'):
|
||||
if sys.version_info[0] == 2: get.search = get.search.encode('utf-8')
|
||||
where = self.GetWhere(get.table,get.search)
|
||||
where,param = self.GetWhere(get.table,get.search)
|
||||
if get.table == 'backup':
|
||||
where += " and type='" + get.type+"'"
|
||||
|
||||
where += " and type='{}'".format(int(get.type))
|
||||
|
||||
if get.table == 'sites' and get.search:
|
||||
pid = SQL.table('domain').where("name LIKE '%"+get.search+"%'",()).getField('pid')
|
||||
pid = SQL.table('domain').where("name LIKE ?",("%{}%".format(get.search),)).getField('pid')
|
||||
if pid:
|
||||
if where:
|
||||
where += " or id=" + str(pid)
|
||||
else:
|
||||
where += "id=" + str(pid)
|
||||
|
||||
if get.table == 'sites' and hasattr(get,'type'):
|
||||
if get.type != '-1':
|
||||
type_where = "type_id=%s" % get.type
|
||||
if where == '':
|
||||
where = type_where
|
||||
else:
|
||||
where += " and " + type_where
|
||||
if get.table == 'sites':
|
||||
if where:
|
||||
where = "({}) AND project_type='PHP'".format(where)
|
||||
else:
|
||||
where = "project_type='PHP'"
|
||||
where = "(project_type='PHP' OR project_type='WP')"
|
||||
|
||||
if hasattr(get,'type'):
|
||||
if get.type != '-1':
|
||||
where += " AND type_id={}".format(int(get.type))
|
||||
|
||||
if get.table == 'databases':
|
||||
if hasattr(get,'db_type'):
|
||||
if where:
|
||||
where += " AND db_type='{}'".format(int(get.db_type))
|
||||
else:
|
||||
where = "db_type='{}'".format(int(get.db_type))
|
||||
if hasattr(get,'sid'):
|
||||
if where:
|
||||
where += " AND sid='{}'".format(int(get.sid))
|
||||
else:
|
||||
where = "sid='{}'".format(int(get.sid))
|
||||
|
||||
field = self.GetField(get.table)
|
||||
#实例化数据库对象
|
||||
|
||||
|
||||
|
||||
|
||||
#是否直接返回所有列表
|
||||
if hasattr(get,'list'):
|
||||
data = SQL.table(get.table).where(where,()).field(field).order(order).select()
|
||||
data = SQL.table(get.table).where(where,param).field(field).order(order).select()
|
||||
return data
|
||||
|
||||
|
||||
#取总行数
|
||||
count = SQL.table(get.table).where(where,()).count()
|
||||
count = SQL.table(get.table).where(where,param).count()
|
||||
#get.uri = get
|
||||
#包含分页类
|
||||
import page
|
||||
#实例化分页类
|
||||
page = page.Page()
|
||||
|
||||
|
||||
info = {}
|
||||
info['count'] = count
|
||||
info['row'] = limit
|
||||
|
||||
|
||||
info['p'] = 1
|
||||
if hasattr(get,'p'):
|
||||
info['p'] = int(get['p'])
|
||||
info['uri'] = get
|
||||
if info['p'] <1: info['p'] = 1
|
||||
|
||||
try:
|
||||
from flask import request
|
||||
info['uri'] = public.url_encode(request.full_path)
|
||||
except:
|
||||
info['uri'] = ''
|
||||
info['return_js'] = ''
|
||||
if hasattr(get,'tojs'):
|
||||
info['return_js'] = get.tojs
|
||||
|
||||
if re.match(r"^[\w\.\-]+$",get.tojs):
|
||||
info['return_js'] = get.tojs
|
||||
|
||||
data['where'] = where
|
||||
|
||||
|
||||
#获取分页数据
|
||||
data['page'] = page.GetPage(info,result)
|
||||
#取出数据
|
||||
data['data'] = SQL.table(get.table).where(where,()).order(order).field(field).limit(str(page.SHIFT)+','+str(page.ROW)).select()
|
||||
data['data'] = SQL.table(get.table).where(where,param).order(order).field(field).limit(str(page.SHIFT)+','+str(page.ROW)).select()
|
||||
return data
|
||||
|
||||
|
||||
#获取条件
|
||||
def GetWhere(self,tableName,search):
|
||||
if not search: return ""
|
||||
def GetWhere(self,tableName,search):
|
||||
if not search: return "",()
|
||||
|
||||
if type(search) == bytes: search = search.encode('utf-8').strip()
|
||||
try:
|
||||
search = re.search(r"[\w\x80-\xff\.]+",search).group()
|
||||
search = re.search(r"[\w\x80-\xff\.\_\-]+",search).group()
|
||||
except:
|
||||
return ''
|
||||
return '',()
|
||||
wheres = {
|
||||
'sites' : "id='"+search+"' or name like '%"+search+"%' or status like '%"+search+"%' or ps like '%"+search+"%'",
|
||||
'ftps' : "id='"+search+"' or name like '%"+search+"%' or ps like '%"+search+"%'",
|
||||
'databases' : "id='"+search+"' or name like '%"+search+"%' or ps like '%"+search+"%'",
|
||||
'logs' : "uid='"+search+"' or username='"+search+"' or type like '%"+search+"%' or log like '%"+search+"%' or addtime like '%"+search+"%'",
|
||||
'backup' : "pid="+search+"",
|
||||
'users' : "id='"+search+"' or username='"+search+"'",
|
||||
'domain' : "pid='"+search+"' or name='"+search+"'",
|
||||
'tasks' : "status='"+search+"' or type='"+search+"'"
|
||||
'sites' : ("name LIKE ? OR ps LIKE ?",('%'+search+'%','%'+search+'%')),
|
||||
'ftps' : ("name LIKE ? OR ps LIKE ?",('%'+search+'%','%'+search+'%')),
|
||||
'databases' : ("(name LIKE ? OR ps LIKE ?)",("%"+search+"%","%"+search+"%")),
|
||||
'logs' : ("username=? OR type LIKE ? OR log LIKE ?",(search,'%'+search+'%','%'+search+'%')),
|
||||
'backup' : ("pid=?",(search,)),
|
||||
'users' : ("id='?' OR username=?",(search,search)),
|
||||
'domain' : ("pid=? OR name=?",(search,search)),
|
||||
'tasks' : ("status=? OR type=?",(search,search)),
|
||||
}
|
||||
try:
|
||||
return wheres[tableName]
|
||||
except:
|
||||
return ''
|
||||
|
||||
return '',()
|
||||
|
||||
# 获取返回的字段
|
||||
def GetField(self,tableName):
|
||||
fields = {
|
||||
'sites' : "id,name,path,status,ps,addtime,edate",
|
||||
'ftps' : "id,pid,name,password,status,ps,addtime,path",
|
||||
'databases' : "id,pid,name,username,password,accept,ps,addtime",
|
||||
'databases' : "id,sid,pid,name,username,password,accept,ps,addtime,db_type,conn_config",
|
||||
'logs' : "id,uid,username,type,log,addtime",
|
||||
'backup' : "id,pid,name,filename,addtime,size",
|
||||
'backup' : "id,pid,name,filename,addtime,size,ps",
|
||||
'users' : "id,username,phone,email,login_ip,login_time",
|
||||
'firewall' : "id,port,ps,addtime",
|
||||
'domain' : "id,pid,name,port,addtime",
|
||||
@@ -379,3 +464,10 @@ class data:
|
||||
return fields[tableName]
|
||||
except:
|
||||
return ''
|
||||
|
||||
def get_analysis(self,get,i):
|
||||
import log_analysis
|
||||
get.path = '/www/wwwlogs/{}.log'.format(i['name'])
|
||||
get.action = 'get_result'
|
||||
data = log_analysis.log_analysis().get_result(get)
|
||||
return int(data['php']) + int(data['san']) + int(data['sql']) + int(data['xss'])
|
||||
+630
-287
File diff suppressed because it is too large
Load Diff
+10
-8
@@ -25,17 +25,17 @@ class datatools:
|
||||
for d in ds:
|
||||
if size < 1024: return ('%.2f' % size) + d
|
||||
size = size / 1024
|
||||
return '0b';
|
||||
return '0b'
|
||||
|
||||
# 获取当前数据库信息
|
||||
def GetdataInfo(self,get):
|
||||
'''
|
||||
传递一个数据库名称即可 get.databases
|
||||
'''
|
||||
if not self.DB_MySQL:self.DB_MySQL = panelMysql.panelMysql()
|
||||
db_name=get.db_name
|
||||
|
||||
db_name=get.db_name
|
||||
if not db_name:return False
|
||||
if not self.DB_MySQL:self.DB_MySQL = public.get_mysql_obj(db_name)
|
||||
ret = {}
|
||||
tables = self.map_to_list(self.DB_MySQL.query('show tables from `%s`' % db_name))
|
||||
if type(tables) == list:
|
||||
@@ -50,7 +50,7 @@ class datatools:
|
||||
|
||||
ret3 = []
|
||||
for i in tables:
|
||||
if i == 1049: return public.returnMsg(False,'DB_NOT_EXIST')
|
||||
if i == 1049: return public.return_msg_gettext(False,'Database does NOT exist!')
|
||||
if type(i) == int: continue
|
||||
table = self.map_to_list(self.DB_MySQL.query("show table status from `%s` where name = '%s'" % (db_name, i[0])))
|
||||
if not table: continue
|
||||
@@ -80,7 +80,9 @@ class datatools:
|
||||
db_name = get.db_name
|
||||
tables = json.loads(get.tables)
|
||||
if not db_name or not tables: return False
|
||||
if not self.DB_MySQL:self.DB_MySQL = panelMysql.panelMysql()
|
||||
if not self.DB_MySQL:self.DB_MySQL = public.get_mysql_obj(db_name)
|
||||
m_version = self.DB_MySQL.query('select version();')[0][0]
|
||||
if m_version.find('5.1.')!=-1:return public.return_msg_gettext(False,"Nonsupport mysql5.1!")
|
||||
mysql_table = self.map_to_list(self.DB_MySQL.query('show tables from `%s`' % db_name))
|
||||
ret=[]
|
||||
if type(mysql_table)==list:
|
||||
@@ -112,10 +114,11 @@ class datatools:
|
||||
db_name=web
|
||||
tables=['web1','web2']
|
||||
'''
|
||||
if not self.DB_MySQL:self.DB_MySQL = panelMysql.panelMysql()
|
||||
|
||||
db_name = get.db_name
|
||||
tables = json.loads(get.tables)
|
||||
if not db_name or not tables: return False
|
||||
if not self.DB_MySQL:self.DB_MySQL = public.get_mysql_obj(db_name)
|
||||
mysql_table = self.map_to_list(self.DB_MySQL.query('show tables from `%s`' % db_name))
|
||||
ret=[]
|
||||
if type(mysql_table) == list:
|
||||
@@ -138,13 +141,12 @@ class datatools:
|
||||
table_type=innodb
|
||||
tables=['web1','web2']
|
||||
'''
|
||||
if not self.DB_MySQL:self.DB_MySQL = panelMysql.panelMysql()
|
||||
db_name = get.db_name
|
||||
table_type = get.table_type
|
||||
tables = json.loads(get.tables)
|
||||
|
||||
if not db_name or not tables: return False
|
||||
|
||||
if not self.DB_MySQL:self.DB_MySQL = public.get_mysql_obj(db_name)
|
||||
mysql_table = self.map_to_list(self.DB_MySQL.query('show tables from `%s`' % db_name))
|
||||
ret=[]
|
||||
if type(mysql_table)==list:
|
||||
|
||||
+15
-12
@@ -304,23 +304,26 @@ class Sql():
|
||||
|
||||
#是否有锁
|
||||
def is_lock(self):
|
||||
n = 0
|
||||
while os.path.exists(self.__LOCK):
|
||||
n+=1
|
||||
if n > 100:
|
||||
self.rm_lock()
|
||||
break
|
||||
time.sleep(0.01)
|
||||
return
|
||||
# n = 0
|
||||
# while os.path.exists(self.__LOCK):
|
||||
# n+=1
|
||||
# if n > 100:
|
||||
# self.rm_lock()
|
||||
# break
|
||||
# time.sleep(0.01)
|
||||
#写锁
|
||||
def write_lock(self):
|
||||
self.is_lock()
|
||||
with open(self.__LOCK,'wb+') as f:
|
||||
f.close()
|
||||
return
|
||||
# self.is_lock()
|
||||
# with open(self.__LOCK,'wb+') as f:
|
||||
# f.close()
|
||||
|
||||
#解锁
|
||||
def rm_lock(self):
|
||||
if os.path.exists(self.__LOCK):
|
||||
os.remove(self.__LOCK)
|
||||
return
|
||||
# if os.path.exists(self.__LOCK):
|
||||
# os.remove(self.__LOCK)
|
||||
|
||||
def query(self,sql,param = ()):
|
||||
#执行SQL语句返回数据集
|
||||
|
||||
+54
-48
@@ -6,73 +6,74 @@
|
||||
# +-------------------------------------------------------------------
|
||||
# | Author: hwliang <hwl@bt.cn>
|
||||
# +-------------------------------------------------------------------
|
||||
import re, os, sys, public, json
|
||||
|
||||
import re,os,sys,public,json
|
||||
import pymysql
|
||||
|
||||
|
||||
class mysql:
|
||||
__DB_PASS = ''
|
||||
__DB_USER = ''
|
||||
__DB_NAME = ''
|
||||
class panelMysql:
|
||||
__DB_PASS = None
|
||||
__DB_USER = 'root'
|
||||
__DB_NAME = None
|
||||
__DB_PORT = 3306
|
||||
__DB_HOST = 'localhost'
|
||||
__DB_PREFIX = ''
|
||||
__DB_CONN = None
|
||||
__DB_CUR = None
|
||||
__DB_ERR = None
|
||||
__DB_NET = None
|
||||
__DB_TABLE = "" # 被操作的表名称
|
||||
__OPT_WHERE = "" # where条件
|
||||
__OPT_LIMIT = "" # limit条件
|
||||
__OPT_ORDER = "" # order条件
|
||||
__OPT_FIELD = "*" # field条件
|
||||
__OPT_PARAM = () # where值
|
||||
__DB_CUR = None
|
||||
__DB_ERR = None
|
||||
__DB_TABLE = "" # 被操作的表名称
|
||||
__OPT_WHERE = "" # where条件
|
||||
__OPT_LIMIT = "" # limit条件
|
||||
__OPT_ORDER = "" # order条件
|
||||
__OPT_FIELD = "*" # field条件
|
||||
__OPT_PARAM = () # where值
|
||||
_USER = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def set_name(self, name):
|
||||
self.__DB_NAME = name
|
||||
def set_name(self,name):
|
||||
self.__DB_NAME = str(name)
|
||||
return self
|
||||
|
||||
def set_host(self, host, port, name, username, password, prefix=''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = port
|
||||
self.__DB_NAME = name
|
||||
self.__DB_USER = username
|
||||
self.__DB_PASS = password
|
||||
def set_prefix(self,prefix):
|
||||
self.__DB_PREFIX = prefix
|
||||
return self
|
||||
|
||||
def set_host(self,host,port,name,username,password,prefix = ''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_NAME = name
|
||||
if self.__DB_NAME: self.__DB_NAME = str(self.__DB_NAME)
|
||||
self.__DB_USER = str(username)
|
||||
self._USER = str(username)
|
||||
self.__DB_PASS = str(password)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__GetConn()
|
||||
return self
|
||||
|
||||
#连接MYSQL数据库
|
||||
def __GetConn(self):
|
||||
if self.__DB_NET: return True
|
||||
try:
|
||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST,
|
||||
port=self.__DB_PORT,
|
||||
user=self.__DB_USER,
|
||||
passwd=self.__DB_PASS)
|
||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST,user=self.__DB_USER,passwd=str(self.__DB_PASS),db=self.__DB_NAME,port=self.__DB_PORT,connect_timeout=15,read_timeout=60,write_timeout=60)
|
||||
except:
|
||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST,user=self.__DB_USER,passwd=str(self.__DB_PASS),db=self.__DB_NAME,port=self.__DB_PORT)
|
||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
||||
return True
|
||||
|
||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
||||
self.__DB_NET = True
|
||||
return True
|
||||
except pymysql.Error as e:
|
||||
self.__DB_ERR = e
|
||||
return False
|
||||
|
||||
def table(self, table):
|
||||
def table(self,table):
|
||||
#设置表名
|
||||
self.__DB_TABLE = self.__DB_PREFIX + table
|
||||
return self
|
||||
|
||||
def where(self, where, param):
|
||||
|
||||
def where(self,where,param):
|
||||
#WHERE条件
|
||||
if where:
|
||||
self.__OPT_WHERE = " WHERE " + where
|
||||
self.__OPT_PARAM = self.__to_tuple(param)
|
||||
return self
|
||||
|
||||
def __to_tuple(self, param):
|
||||
def __to_tuple(self,param):
|
||||
#将参数转换为tuple
|
||||
if type(param) != tuple:
|
||||
if type(param) == list:
|
||||
@@ -103,6 +104,7 @@ class mysql:
|
||||
def select(self):
|
||||
#查询数据集
|
||||
self.__GetConn()
|
||||
if not self.__DB_CUR: return self.__DB_ERR
|
||||
try:
|
||||
self.__get_columns()
|
||||
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + self.__OPT_WHERE + self.__OPT_ORDER + self.__OPT_LIMIT
|
||||
@@ -119,18 +121,18 @@ class mysql:
|
||||
tmp1[key.strip('`')] = row[i]
|
||||
i += 1
|
||||
tmp.append(tmp1)
|
||||
del (tmp1)
|
||||
del(tmp1)
|
||||
data = tmp
|
||||
del (tmp)
|
||||
del(tmp)
|
||||
else:
|
||||
#将元组转换成列表
|
||||
tmp = list(map(list, data))
|
||||
data = tmp
|
||||
del (tmp)
|
||||
del(tmp)
|
||||
self.__close()
|
||||
return data
|
||||
except Exception as ex:
|
||||
return public.get_error_info()
|
||||
return "error: " + str(ex)
|
||||
|
||||
def get(self):
|
||||
self.__get_columns()
|
||||
@@ -291,30 +293,34 @@ class mysql:
|
||||
except Exception as ex:
|
||||
return "error: " + str(ex)
|
||||
|
||||
def execute(self, sql, is_close=True):
|
||||
def execute(self,sql,param = ()):
|
||||
#执行SQL语句返回受影响行
|
||||
if not self.__GetConn(): return self.__DB_ERR
|
||||
try:
|
||||
result = self.__DB_CUR.execute(sql)
|
||||
self.__OPT_PARAM = list(self.__to_tuple(param))
|
||||
result = self.__DB_CUR.execute(sql,self.__OPT_PARAM)
|
||||
self.__DB_CONN.commit()
|
||||
if is_close: self.__close()
|
||||
self.__close()
|
||||
return result
|
||||
except Exception as ex:
|
||||
return ex
|
||||
|
||||
def query(self, sql, is_close=True):
|
||||
|
||||
def query(self,sql,is_close=True,param=()):
|
||||
#执行SQL语句返回数据集
|
||||
if not self.__GetConn(): return self.__DB_ERR
|
||||
try:
|
||||
self.__DB_CUR.execute(sql)
|
||||
self.__OPT_PARAM = list(self.__to_tuple(param))
|
||||
self.__DB_CUR.execute(sql,self.__OPT_PARAM)
|
||||
result = self.__DB_CUR.fetchall()
|
||||
#将元组转换成列表
|
||||
data = list(map(list, result))
|
||||
data = list(map(list,result))
|
||||
if is_close: self.__Close()
|
||||
return data
|
||||
except Exception as ex:
|
||||
return ex
|
||||
|
||||
|
||||
#关闭连接
|
||||
def __Close(self):
|
||||
self.__DB_CUR.close()
|
||||
|
||||
+12
-10
@@ -51,7 +51,7 @@ class FileExecuteDeny:
|
||||
deny_name.append(tmp[-1])
|
||||
result = []
|
||||
for i in deny_name:
|
||||
reg = '#BEGIN_DENY_{}\n\s*location\s*\~\*\s*\^(.*)\.\*.*\((.*)\)\$'.format(i)
|
||||
reg = '#BEGIN_DENY_{}\n\s*location\s*\~\*\s*\^(.*)\.\*.*\((.*)\)\$'.format(i.replace("|","\|"))
|
||||
deny_directory = re.search(reg,conf).groups()[0]
|
||||
deny_suffix = re.search(reg,conf).groups()[1]
|
||||
result.append({'name':i,'dir':deny_directory,'suffix':deny_suffix})
|
||||
@@ -71,7 +71,7 @@ class FileExecuteDeny:
|
||||
deny_name.append(tmp[-1])
|
||||
result = []
|
||||
for i in deny_name:
|
||||
reg = '#BEGIN_DENY_{}\n\s*<Directory\s*\~\s*"(.*)\.\*.*\((.*)\)\$'.format(i)
|
||||
reg = '#BEGIN_DENY_{}\n\s*<Directory\s*\~\s*"(.*)\.\*.*\((.*)\)\$'.format(i.replace("|","\|"))
|
||||
deny_directory = re.search(reg,conf).groups()[0]
|
||||
deny_suffix = re.search(reg,conf).groups()[1]
|
||||
result.append({'name':i,'dir':deny_directory,'suffix':deny_suffix})
|
||||
@@ -91,7 +91,7 @@ class FileExecuteDeny:
|
||||
deny_name.append(tmp[-1])
|
||||
result = []
|
||||
for i in deny_name:
|
||||
reg = '#BEGIN_DENY_{}\n\s*rules\s*RewriteRule\s*\^(.*)\.\*.*\((.*)\)\$'.format(i)
|
||||
reg = '#BEGIN_DENY_{}\n\s*rules\s*RewriteRule\s*\^(.*)\.\*.*\((.*)\)\$'.format(i.replace("|","\|"))
|
||||
deny_directory = re.search(reg, conf).groups()[0]
|
||||
deny_suffix = re.search(reg,conf).groups()[1]
|
||||
result.append({'name':i,'dir':deny_directory,'suffix':deny_suffix})
|
||||
@@ -116,6 +116,8 @@ class FileExecuteDeny:
|
||||
dir = args.dir
|
||||
suffix = args.suffix
|
||||
website = args.website
|
||||
if suffix[-1] == "|":
|
||||
suffix = suffix[:-1]
|
||||
self._init_conf(website)
|
||||
conf = public.readFile(self.ng_website_conf)
|
||||
if not conf:
|
||||
@@ -124,16 +126,16 @@ class FileExecuteDeny:
|
||||
exist_deny_name = [i.split('_')[-1] for i in data]
|
||||
if args.act == 'edit':
|
||||
if deny_name not in exist_deny_name:
|
||||
return public.returnMsg(False, 'The specify rule name is not exists! [ {} ]'.format(deny_name))
|
||||
return public.return_msg_gettext(False, 'The specify rule name is not exists! [ {} ]'.format(deny_name))
|
||||
self.del_file_deny(args)
|
||||
else:
|
||||
if deny_name in exist_deny_name:
|
||||
return public.returnMsg(False,'The specify rule name is already exists! [ {} ]'.format(deny_name))
|
||||
return public.return_msg_gettext(False,'The specify rule name is already exists! [ {} ]'.format(deny_name))
|
||||
self._set_nginx_file_deny(deny_name,dir,suffix)
|
||||
self._set_apache_file_deny(deny_name,dir,suffix)
|
||||
self._set_ols_file_deny(deny_name,dir,suffix)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'Add Successfully')
|
||||
return public.returnMsg(True,'Setup successfully!')
|
||||
|
||||
def _set_nginx_file_deny(self,name,dir=None,suffix=None):
|
||||
conf = public.readFile(self.ng_website_conf)
|
||||
@@ -216,16 +218,16 @@ class FileExecuteDeny:
|
||||
self._set_apache_file_deny(deny_name)
|
||||
self._set_ols_file_deny(deny_name)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'Delete Successfully')
|
||||
return public.returnMsg(True,'Successfully deleted!')
|
||||
|
||||
# 检查传入参数
|
||||
def _check_args(self,args):
|
||||
if hasattr(args,'deny_name'):
|
||||
if len(args.deny_name) < 3:
|
||||
return public.returnMsg(False, 'Rule name needs to be greater than 3 bytes')
|
||||
return public.return_msg_gettext(False, 'Rule name needs to be greater than 3 bytes')
|
||||
if hasattr(args,'suffix'):
|
||||
if not args.suffix:
|
||||
return public.returnMsg(False, 'File suffix cannot be empty')
|
||||
return public.return_msg_gettext(False, 'File suffix cannot be empty')
|
||||
if hasattr(args,'dir'):
|
||||
if not args.dir:
|
||||
return public.returnMsg(False, 'Directory cannot be empty')
|
||||
return public.return_msg_gettext(False, 'Directory cannot be empty')
|
||||
+609
-333
File diff suppressed because it is too large
Load Diff
+43
-43
@@ -139,9 +139,9 @@ class firewalls:
|
||||
import time
|
||||
import re
|
||||
rep = "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\/\d{1,2})?$"
|
||||
if not re.search(rep,get.port): return public.returnMsg(False,'FIREWALL_IP_FORMAT');
|
||||
if not re.search(rep,get.port): return public.return_msg_gettext(False,'IP address youve entered is illegal!');
|
||||
address = get.port
|
||||
if public.M('firewall').where("port=?",(address,)).count() > 0: return public.returnMsg(False,'FIREWALL_IP_EXISTS')
|
||||
if public.M('firewall').where("port=?",(address,)).count() > 0: return public.return_msg_gettext(False,'The IP exists in block list, no need to repeat processing!')
|
||||
if self.__isUfw:
|
||||
public.ExecShell('ufw deny from ' + address + ' to any');
|
||||
else:
|
||||
@@ -154,11 +154,11 @@ class firewalls:
|
||||
else:
|
||||
public.ExecShell('iptables -I INPUT -s '+address+' -j DROP')
|
||||
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_DROP_IP',(address,))
|
||||
public.write_log_gettext("Firewall manager", 'Successfully blocked IP [{}]!',(address,))
|
||||
addtime = time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
public.M('firewall').add('port,ps,addtime',(address,get.ps,addtime))
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True,'ADD_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Successfully added')
|
||||
|
||||
|
||||
|
||||
@@ -178,11 +178,11 @@ class firewalls:
|
||||
else:
|
||||
public.ExecShell('iptables -D INPUT -s '+address+' -j DROP')
|
||||
|
||||
public.WriteLog("TYPE_FIREWALL",'FIREWALL_ACCEPT_IP',(address,))
|
||||
public.write_log_gettext("Firewall manager",'Unblocked IP [{}]!',(address,))
|
||||
public.M('firewall').where("id=?",(id,)).delete()
|
||||
|
||||
self.FirewallReload();
|
||||
return public.returnMsg(True,'DEL_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Successfully deleted')
|
||||
|
||||
|
||||
#添加放行端口
|
||||
@@ -190,28 +190,28 @@ class firewalls:
|
||||
flag=False
|
||||
import re
|
||||
rep = "^\d{1,5}(:\d{1,5})?$"
|
||||
if not re.search(rep,get.port): return public.returnMsg(False,'PORT_CHECK_RANGE');
|
||||
if not re.search(rep,get.port): return public.return_msg_gettext(False,'Port range is incorrect!');
|
||||
import time
|
||||
port = get.port
|
||||
ps = get.ps
|
||||
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', '7800']
|
||||
if types not in type_list:return public.return_msg_gettext(False, 'The port exists, no need to repeat the release!')
|
||||
notudps = ['80', '443', '8888', '888', '39000:40000', '21', '22']
|
||||
if port in notudps:flag=True
|
||||
#return public.M('firewall').where("port=?", (port,)).count()
|
||||
if types=='tcp':
|
||||
if flag:
|
||||
if public.M('firewall').where("port=?", (port,)).count() > 0: return public.returnMsg(False, 'FIREWALL_PORT_EXISTS')
|
||||
if public.M('firewall').where("port=?", (port,)).count() > 0: return public.return_msg_gettext(False, 'The port exists, no need to repeat the release!')
|
||||
else:
|
||||
if public.M('firewall').where("port=? and type='tcp'",(port,)).count() > 0: return public.returnMsg(False,'FIREWALL_PORT_EXISTS')
|
||||
if public.M('firewall').where("port=? and type='tcp'",(port,)).count() > 0: return public.return_msg_gettext(False,'The port exists, no need to repeat the release!')
|
||||
elif types=='udp':
|
||||
if flag:
|
||||
if public.M('firewall').where("port=?", (port,)).count() > 0: return public.returnMsg( False, 'FIREWALL_PORT_EXISTS')
|
||||
if public.M('firewall').where("port=?", (port,)).count() > 0: return public.return_msg_gettext( False, 'The port exists, no need to repeat the release!')
|
||||
else:
|
||||
if public.M('firewall').where("port=? and type='udp'", (port,)).count() > 0: return public.returnMsg(False,'FIREWALL_PORT_EXISTS')
|
||||
if public.M('firewall').where("port=? and type='udp'", (port,)).count() > 0: return public.return_msg_gettext(False,'The port exists, no need to repeat the release!')
|
||||
else:
|
||||
return public.returnMsg(False, 'FIREWALL_PORT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'The port exists, no need to repeat the release!')
|
||||
|
||||
if self.__isUfw:
|
||||
if port in notudps:
|
||||
@@ -231,12 +231,12 @@ class firewalls:
|
||||
else:
|
||||
public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m ' + types +' --dport ' + port + ' -j ACCEPT' )
|
||||
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_ACCEPT_PORT',(port,))
|
||||
public.write_log_gettext("Firewall manager", 'Successfully accepted port [{}]!',(port,))
|
||||
addtime = time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
result = public.M('firewall').add('port,ps,addtime,types',(port,ps,addtime,types))
|
||||
#return result
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True,'ADD_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
#删除放行端口
|
||||
@@ -245,9 +245,9 @@ class firewalls:
|
||||
id = get.id
|
||||
types=get.type
|
||||
type_list = ['tcp', 'udp']
|
||||
if not types in type_list: return public.returnMsg(False, 'FIREWALL_PORT_EXISTS')
|
||||
if not types in type_list: return public.return_msg_gettext(False, 'The port exists, no need to repeat the release!')
|
||||
try:
|
||||
if(port == public.GetHost(True)): return public.returnMsg(False,'FIREWALL_PORT_PANEL')
|
||||
if(port == public.GetHost(True)): return public.return_msg_gettext(False,'Failed,cannot delete current port of the panel!')
|
||||
if self.__isUfw:
|
||||
public.ExecShell('ufw delete allow ' + port + '/' + types+ '');
|
||||
else:
|
||||
@@ -255,13 +255,13 @@ class firewalls:
|
||||
public.ExecShell('firewall-cmd --permanent --zone=public --remove-port='+port+'/' + types + '')
|
||||
else:
|
||||
public.ExecShell('iptables -D INPUT -p tcp -m state --state NEW -m ' + types +' --dport '+port+' -j ACCEPT')
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_DROP_PORT',(port,))
|
||||
public.write_log_gettext("Firewall manager", 'Successfully deleted accepted port [{}] on firewall!',(port,))
|
||||
public.M('firewall').where("id=?",(id,)).delete()
|
||||
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True,'DEL_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Successfully deleted')
|
||||
except:
|
||||
return public.returnMsg(False,'DEL_ERROR')
|
||||
return public.return_msg_gettext(False,'Failed to delete')
|
||||
|
||||
|
||||
|
||||
@@ -269,10 +269,10 @@ class firewalls:
|
||||
def SetSshStatus(self,get):
|
||||
version = public.readFile('/etc/redhat-release')
|
||||
if int(get['status'])==1:
|
||||
msg = public.getMsg('FIREWALL_SSH_STOP')
|
||||
msg = public.get_msg_gettext('SSH service turned off')
|
||||
act = 'stop'
|
||||
else:
|
||||
msg = public.getMsg('FIREWALL_SSH_START')
|
||||
msg = public.get_msg_gettext('SSH service turned on')
|
||||
act = 'start'
|
||||
|
||||
if not os.path.exists('/etc/redhat-release'):
|
||||
@@ -282,8 +282,8 @@ class firewalls:
|
||||
else:
|
||||
public.ExecShell("/etc/init.d/sshd "+act)
|
||||
|
||||
public.WriteLog("TYPE_FIREWALL", msg)
|
||||
return public.returnMsg(True,'SUCCESS')
|
||||
public.write_log_gettext("Firewall manager", msg)
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ class firewalls:
|
||||
|
||||
public.writeFile(filename,conf)
|
||||
public.ExecShell('sysctl -p')
|
||||
return public.returnMsg(True,'SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
|
||||
@@ -313,9 +313,9 @@ class firewalls:
|
||||
def SetSshPort(self,get):
|
||||
#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', '7800']
|
||||
if port in ports: return public.returnMsg(False,'');
|
||||
if int(port) < 22 or int(port) > 65535: return public.return_msg_gettext(False,'Port range must be between 22 and 65535!');
|
||||
ports = ['21','25','80','443','8080','888','8888'];
|
||||
if port in ports: return public.return_msg_gettext(False,'');
|
||||
|
||||
file = '/etc/ssh/sshd_config'
|
||||
conf = public.readFile(file)
|
||||
@@ -337,9 +337,9 @@ class firewalls:
|
||||
public.ExecShell("/etc/init.d/sshd restart")
|
||||
|
||||
self.FirewallReload()
|
||||
public.M('firewall').where("ps=?",(public.GetMsg("SSH_SERVER"),)).setField('port',port)
|
||||
public.WriteLog("TYPE_FIREWALL", "FIREWALL_SSH_PORT",(port,))
|
||||
return public.returnMsg(True,'EDIT_SUCCESS')
|
||||
public.M('firewall').where("ps=?",(public.get_msg_gettext('SSH Server'),)).setField('port',port)
|
||||
public.write_log_gettext("Firewall manager", "Successfully changed SSH port to [{}]!",(port,))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
#取SSH信息
|
||||
def GetSshInfo(self,get):
|
||||
@@ -398,11 +398,11 @@ class firewalls:
|
||||
import re
|
||||
# 判断端口是否正确
|
||||
rep = "^\d{1,5}(:\d{1,5})?$"
|
||||
if not re.search(rep, get.port): return public.returnMsg(False, 'PORT_CHECK_RANGE');
|
||||
if not re.search(rep, get.port): return public.return_msg_gettext(False, 'Port range is incorrect! should be between 100-65535');
|
||||
|
||||
# 判断IP是否正确
|
||||
rep2 = "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\/\d{1,2})?$"
|
||||
if not re.search(rep2, get.address): return public.returnMsg(False, 'FIREWALL_IP_FORMAT');
|
||||
if not re.search(rep2, get.address): return public.return_msg_gettext(False, 'IP address is illegal!');
|
||||
import time
|
||||
ports = get.port
|
||||
ps = get.ps
|
||||
@@ -414,19 +414,19 @@ class firewalls:
|
||||
type_list=['reject','accept']
|
||||
# 判断type类型是否正确
|
||||
|
||||
if types not in type_list:return public.returnMsg(False, 'FIREWALL_PORT_EXISTS')
|
||||
if types not in type_list:return public.return_msg_gettext(False, 'The port exists, no need to repeat the release!')
|
||||
# 判断protocol 类型是否正确
|
||||
|
||||
if protocol not in protocol_list: return public.returnMsg(False, 'FIREWALL_PORT_EXISTS')
|
||||
if protocol not in protocol_list: return public.return_msg_gettext(False, 'The port exists, no need to repeat the release!')
|
||||
|
||||
notudps = ['80', '443', '8888', '888', '39000:40000', '21', '22','7800']
|
||||
notudps = ['80', '443', '8888', '888', '39000:40000', '21', '22']
|
||||
if ports in notudps: flag = True
|
||||
|
||||
# sql 查询
|
||||
#sql="select * from firewall where ports='%s' and address_ip='%s' and protocol='%s' and types='%s';" % (str(ports), str(address_ip), str(protocol), str(types))
|
||||
query_result = public.M('firewall').where('ports=? and address_ip=? and protocol=? and types=?',(ports, address_ip, protocol, types)).count()
|
||||
# 这里大于0 表示存在
|
||||
if query_result > 0 : return public.returnMsg(False,'FIREWALL_PORT_EXISTS')
|
||||
if query_result > 0 : return public.return_msg_gettext(False,'The port exists, no need to repeat the release!')
|
||||
|
||||
if self.__isUfw:
|
||||
if type=='accept':
|
||||
@@ -447,11 +447,11 @@ class firewalls:
|
||||
'iptables -I INPUT -s ' + address_ip + ' -p ' + protocol + ' --dport ' + ports + ' -j DROP')
|
||||
|
||||
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_ACCEPT_PORT', (ports,))
|
||||
public.write_log_gettext("Firewall manager", 'Successfully accepted port [{}]!', (ports,))
|
||||
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
result = public.M('firewall').add('protocol,types,port,address_ip,ps,addtime', (protocol,types,ports,address_ip,ps,addtime))
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True, 'ADD_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
# 删除指定放行端口
|
||||
def DelSpecifiesIp(self, get):
|
||||
@@ -470,7 +470,7 @@ class firewalls:
|
||||
address_ip=get.address
|
||||
protocol_list = ['tcp', 'udp']
|
||||
id = get.id
|
||||
if protocol not in protocol_list: return public.returnMsg(False, 'DESIGNATED_POROTOCOL_NOT_EXIST')
|
||||
if protocol not in protocol_list: return public.return_msg_gettext(False, 'Specified protocol does NOT exist!')
|
||||
if self.__isUfw:
|
||||
if type=='accept':
|
||||
public.ExecShell('ufw delete allow proto ' + protocol + ' from ' + address_ip + ' to any port ' + ports + '')
|
||||
@@ -485,10 +485,10 @@ class firewalls:
|
||||
public.ExecShell('iptables -D INPUT -s ' + address_ip + ' -p ' + protocol + ' --dport ' + ports + ' -j ACCEPT')
|
||||
else:
|
||||
public.ExecShell('iptables -D INPUT -s ' + address_ip + ' -p ' + protocol + ' --dport ' + ports + ' -j DROP')
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_DROP_PORT', (ports,))
|
||||
public.write_log_gettext("Firewall manager", 'FIREWALL_DROP_PORT', (ports,))
|
||||
public.M('firewall').where("id=?", (id,)).delete()
|
||||
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True, 'DEL_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Successfully deleted')
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -321,7 +321,7 @@ class firewalld:
|
||||
# 服务控制
|
||||
def FirewalldService(self, type):
|
||||
public.ExecShell('systemctl ' + type + ' firewalld.service')
|
||||
return public.returnMsg(True, 'SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
# 保存配置
|
||||
def Save(self):
|
||||
|
||||
+135
-97
@@ -11,10 +11,13 @@ class firewalls:
|
||||
__isFirewalld = False
|
||||
__isUfw = False
|
||||
__Obj = None
|
||||
__ufw_exec = 'ufw'
|
||||
|
||||
def __init__(self):
|
||||
if os.path.exists('/usr/sbin/firewalld'): self.__isFirewalld = True
|
||||
if os.path.exists('/usr/sbin/ufw'): self.__isUfw = True
|
||||
if os.path.exists('/usr/sbin/ufw'):
|
||||
self.__ufw_exec = '/usr/sbin/ufw'
|
||||
self.__isUfw = True
|
||||
if self.__isFirewalld:
|
||||
try:
|
||||
self.__Obj = firewalld.firewalld()
|
||||
@@ -53,38 +56,76 @@ class firewalls:
|
||||
#重载防火墙配置
|
||||
def FirewallReload(self):
|
||||
if self.__isUfw:
|
||||
public.ExecShell('/usr/sbin/ufw reload')
|
||||
public.ExecShell('{} reload &'.format(self.__ufw_exec))
|
||||
return
|
||||
if self.__isFirewalld:
|
||||
public.ExecShell('firewall-cmd --reload')
|
||||
else:
|
||||
public.ExecShell('/etc/init.d/iptables save')
|
||||
public.ExecShell('/etc/init.d/iptables restart')
|
||||
public.ExecShell('/etc/init.d/iptables save &')
|
||||
public.ExecShell('/etc/init.d/iptables restart &')
|
||||
|
||||
#取防火墙状态
|
||||
def CheckFirewallStatus(self):
|
||||
if self.__isUfw:
|
||||
return 1
|
||||
# if self.__isUfw:
|
||||
# res = public.ExecShell('ufw status verbose')[0]
|
||||
# if res.find('inactive') != -1: return False
|
||||
# return True
|
||||
|
||||
# if self.__isFirewalld:
|
||||
# res = public.ExecShell("systemctl status firewalld")[0]
|
||||
# if res.find('active (running)') != -1: return True
|
||||
# if res.find('disabled') != -1: return False
|
||||
# if res.find('inactive (dead)') != -1: return False
|
||||
# else:
|
||||
# res = public.ExecShell("/etc/init.d/iptables status")[0]
|
||||
# if res.find('not running') != -1: return False
|
||||
# return True
|
||||
return public.get_firewall_status() == 1
|
||||
|
||||
def SetFirewallStatus(self,get=None):
|
||||
'''
|
||||
@name 设置系统防火墙状态
|
||||
@author hwliang<2022-01-13>
|
||||
'''
|
||||
status = not self.CheckFirewallStatus()
|
||||
status_msg = {False: 'Close', True: 'Open'}
|
||||
if self.__isUfw:
|
||||
if status:
|
||||
public.ExecShell('echo y|{} enable'.format(self.__ufw_exec))
|
||||
else:
|
||||
public.ExecShell('echo y|{} disable'.format(self.__ufw_exec))
|
||||
if self.__isFirewalld:
|
||||
res = public.ExecShell("systemctl status firewalld")[0]
|
||||
if res.find('active (running)') != -1: return 1
|
||||
if res.find('disabled') != -1: return -1
|
||||
if res.find('inactive (dead)') != -1: return 0
|
||||
if status:
|
||||
public.ExecShell('systemctl enable firewalld')
|
||||
public.ExecShell('systemctl start firewalld')
|
||||
else:
|
||||
public.ExecShell('systemctl disable firewalld')
|
||||
public.ExecShell('systemctl stop firewalld')
|
||||
else:
|
||||
return 1
|
||||
if status:
|
||||
public.ExecShell("chkconfig iptables on")
|
||||
public.ExecShell('/etc/init.d/iptables start')
|
||||
else:
|
||||
public.ExecShell("chkconfig iptables off")
|
||||
public.ExecShell('/etc/init.d/iptables stop')
|
||||
public.write_log_gettext('Firewall manager','{} system firewall!',(status_msg[status],))
|
||||
return public.return_msg_gettext(True,'{} system firewall!',(status_msg[status],))
|
||||
|
||||
#添加屏蔽IP
|
||||
def AddDropAddress(self,get):
|
||||
if not self.CheckFirewallStatus(): return public.return_msg_gettext(False,'The system firewall is not open')
|
||||
import time
|
||||
import re
|
||||
ip_format = get.port.split('/')[0]
|
||||
if not public.check_ip(ip_format): return public.returnMsg(False,'FIREWALL_IP_FORMAT')
|
||||
if ip_format in ['0.0.0.0','127.0.0.0',"::1"]: return public.returnMsg(False,'请不要花样作死!')
|
||||
if not public.check_ip(ip_format): return public.return_msg_gettext(False,'IP address you entered is illegal!')
|
||||
if ip_format in ['0.0.0.0','127.0.0.0',"::1"]: return public.return_msg_gettext(False,'Disabling this IP will cause your server to fail')
|
||||
address = get.port
|
||||
if public.M('firewall').where("port=?",(address,)).count() > 0: return public.returnMsg(False,'FIREWALL_IP_EXISTS')
|
||||
if public.M('firewall').where("port=?",(address,)).count() > 0: return public.return_msg_gettext(False,'The IP exists in block list, no need to repeat processing!')
|
||||
if self.__isUfw:
|
||||
public.ExecShell('ufw insert 1 deny from ' + address + ' to any')
|
||||
if public.is_ipv6(ip_format):
|
||||
public.ExecShell('{} deny from '.format(self.__ufw_exec) + address + ' to any')
|
||||
else:
|
||||
public.ExecShell('{} insert 1 deny from '.format(self.__ufw_exec) + address + ' to any')
|
||||
else:
|
||||
if self.__isFirewalld:
|
||||
#self.__Obj.AddDropAddress(address)
|
||||
@@ -93,26 +134,26 @@ class firewalls:
|
||||
else:
|
||||
public.ExecShell('firewall-cmd --permanent --add-rich-rule=\'rule family=ipv4 source address="'+ address +'" drop\'')
|
||||
else:
|
||||
if public.is_ipv6(ip_format): return public.returnMsg(False,'FIREWALL_IP_FORMAT')
|
||||
if public.is_ipv6(ip_format): return public.return_msg_gettext(False,'IP address is illegal!')
|
||||
public.ExecShell('iptables -I INPUT -s '+address+' -j DROP')
|
||||
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_DROP_IP',(address,))
|
||||
addtime = time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
public.M('firewall').add('port,ps,addtime',(address,get.ps,addtime))
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True,'ADD_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
#删除IP屏蔽
|
||||
def DelDropAddress(self,get):
|
||||
if not self.CheckFirewallStatus(): return public.return_msg_gettext(False,'The system firewall is not open')
|
||||
address = get.port
|
||||
id = get.id
|
||||
ip_format = get.port.split('/')[0]
|
||||
if self.__isUfw:
|
||||
public.ExecShell('ufw delete deny from ' + address + ' to any')
|
||||
public.ExecShell('{} delete deny from '.format(self.__ufw_exec) + address + ' to any')
|
||||
else:
|
||||
if self.__isFirewalld:
|
||||
#self.__Obj.DelDropAddress(address)
|
||||
if public.is_ipv6(ip_format):
|
||||
public.ExecShell('firewall-cmd --permanent --remove-rich-rule=\'rule family=ipv6 source address="'+ address +'" drop\'')
|
||||
else:
|
||||
@@ -124,73 +165,81 @@ class firewalls:
|
||||
public.M('firewall').where("id=?",(id,)).delete()
|
||||
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True,'DEL_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Successfully deleted')
|
||||
|
||||
|
||||
#添加放行端口
|
||||
def AddAcceptPort(self,get):
|
||||
if not self.CheckFirewallStatus(): return public.return_msg_gettext(False,'The system firewall is not open')
|
||||
import re
|
||||
src_port = get.port
|
||||
get.port = get.port.replace('-',':')
|
||||
rep = r"^\d{1,5}(:\d{1,5})?$"
|
||||
if not re.search(rep,get.port):
|
||||
return public.returnMsg(False,'PORT_CHECK_RANGE')
|
||||
return public.return_msg_gettext(False,'Port range must be between 22 and 65535!')
|
||||
|
||||
import time
|
||||
port = get.port
|
||||
ps = public.xssencode(get.ps)
|
||||
ps = ""
|
||||
if get.ps:
|
||||
ps = public.xssencode2(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','7800']
|
||||
if is_exists: return public.return_msg_gettext(False,'The port exists, no need to repeat the release!')
|
||||
notudps = ['80','443','8888','888','39000:40000','21','22']
|
||||
if self.__isUfw:
|
||||
public.ExecShell('ufw allow ' + port + '/tcp')
|
||||
if not port in notudps: public.ExecShell('ufw allow ' + port + '/udp')
|
||||
public.ExecShell('{} allow '.format(self.__ufw_exec) + port + '/tcp')
|
||||
# if not port in notudps: public.ExecShell('ufw allow ' + port + '/udp')
|
||||
else:
|
||||
if self.__isFirewalld:
|
||||
#self.__Obj.AddAcceptPort(port)
|
||||
port = port.replace(':','-')
|
||||
public.ExecShell('firewall-cmd --permanent --zone=public --add-port='+port+'/tcp')
|
||||
if not port in notudps: public.ExecShell('firewall-cmd --permanent --zone=public --add-port='+port+'/udp')
|
||||
# if not port in notudps: public.ExecShell('firewall-cmd --permanent --zone=public --add-port='+port+'/udp')
|
||||
else:
|
||||
public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport '+port+' -j ACCEPT')
|
||||
if not port in notudps: public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m udp --dport '+port+' -j ACCEPT')
|
||||
# if not port in notudps: public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m udp --dport '+port+' -j ACCEPT')
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_ACCEPT_PORT',(port,))
|
||||
addtime = time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
if not is_exists: public.M('firewall').add('port,ps,addtime',(port,ps,addtime))
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True,'ADD_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
#添加放行端口
|
||||
def AddAcceptPortAll(self,port,ps):
|
||||
if not self.CheckFirewallStatus(): return public.return_msg_gettext(False,'The system firewall is not open')
|
||||
import re
|
||||
port = port.replace('-',':')
|
||||
rep = r"^\d{1,5}(:\d{1,5})?$"
|
||||
if not re.search(rep,port):
|
||||
return False
|
||||
if self.__isUfw:
|
||||
public.ExecShell('ufw allow ' + port + '/tcp')
|
||||
public.ExecShell('ufw allow ' + port + '/udp')
|
||||
public.ExecShell('{} allow '.format(self.__ufw_exec) + port + '/tcp')
|
||||
# public.ExecShell('ufw allow ' + port + '/udp')
|
||||
else:
|
||||
if self.__isFirewalld:
|
||||
port = port.replace(':','-')
|
||||
public.ExecShell('firewall-cmd --permanent --zone=public --add-port='+port+'/tcp')
|
||||
public.ExecShell('firewall-cmd --permanent --zone=public --add-port='+port+'/udp')
|
||||
# public.ExecShell('firewall-cmd --permanent --zone=public --add-port='+port+'/udp')
|
||||
else:
|
||||
public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport '+port+' -j ACCEPT')
|
||||
public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m udp --dport '+port+' -j ACCEPT')
|
||||
# public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m udp --dport '+port+' -j ACCEPT')
|
||||
return True
|
||||
|
||||
|
||||
#删除放行端口
|
||||
def DelAcceptPort(self,get):
|
||||
if not self.CheckFirewallStatus(): return public.return_msg_gettext(False,'The system firewall is not open')
|
||||
port = get.port
|
||||
id = get.id
|
||||
|
||||
if public.is_ipv6(str(port)): return self.DelDropAddress(get) # 如果是ipv6地址,则调用DelDropAddress
|
||||
|
||||
try:
|
||||
if(port == public.GetHost(True) or port == public.readFile('data/port.pl').strip()):
|
||||
return public.returnMsg(False,'FIREWALL_PORT_PANEL')
|
||||
return public.return_msg_gettext(False,'Failed,cannot delete current port of the panel')
|
||||
if self.__isUfw:
|
||||
public.ExecShell('ufw delete allow ' + port + '/tcp')
|
||||
public.ExecShell('ufw delete allow ' + port + '/udp')
|
||||
public.ExecShell('{} delete allow '.format(self.__ufw_exec) + port + '/tcp')
|
||||
public.ExecShell('{} delete allow '.format(self.__ufw_exec) + port + '/udp')
|
||||
else:
|
||||
if self.__isFirewalld:
|
||||
#self.__Obj.DelAcceptPort(port)
|
||||
@@ -201,35 +250,42 @@ class firewalls:
|
||||
public.ExecShell('iptables -D INPUT -p tcp -m state --state NEW -m udp --dport '+port+' -j ACCEPT')
|
||||
public.WriteLog("TYPE_FIREWALL", 'FIREWALL_DROP_PORT',(port,))
|
||||
public.M('firewall').where("id=?",(id,)).delete()
|
||||
|
||||
|
||||
self.FirewallReload()
|
||||
return public.returnMsg(True,'DEL_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Successfully deleted')
|
||||
except:
|
||||
return public.returnMsg(False,'DEL_ERROR')
|
||||
return public.return_msg_gettext(False,'Failed to delete')
|
||||
|
||||
#设置远程端口状态
|
||||
def SetSshStatus(self,get):
|
||||
version = public.readFile('/etc/redhat-release')
|
||||
# version = public.readFile('/etc/redhat-release')
|
||||
if int(get['status'])==1:
|
||||
msg = public.getMsg('FIREWALL_SSH_STOP')
|
||||
msg = public.get_msg_gettext('SSH service turned off')
|
||||
act = 'stop'
|
||||
else:
|
||||
msg = public.getMsg('FIREWALL_SSH_START')
|
||||
msg = public.get_msg_gettext('SSH service turned on')
|
||||
act = 'start'
|
||||
|
||||
if not os.path.exists('/etc/redhat-release'):
|
||||
public.ExecShell('service ssh ' + act)
|
||||
elif version.find(' 7.') != -1 or version.find(' 8.') != -1 or version.find('Fedora') != -1:
|
||||
public.ExecShell("systemctl "+act+" sshd.service")
|
||||
else:
|
||||
public.ExecShell("/etc/init.d/sshd "+act)
|
||||
|
||||
public.WriteLog("TYPE_FIREWALL", msg)
|
||||
return public.returnMsg(True,'SUCCESS')
|
||||
|
||||
|
||||
|
||||
|
||||
# if not os.path.exists('/etc/redhat-release'):
|
||||
# public.ExecShell('service ssh ' + act)
|
||||
# elif version.find(' 7.') != -1 or version.find(' 8.') != -1 or version.find('Fedora') != -1:
|
||||
# public.ExecShell("systemctl "+act+" sshd")
|
||||
# else:
|
||||
# 全试一次?
|
||||
public.ExecShell("/etc/init.d/sshd "+act)
|
||||
public.ExecShell('service ssh ' + act)
|
||||
public.ExecShell("systemctl "+act+" sshd")
|
||||
public.ExecShell("systemctl "+act+" ssh")
|
||||
if act in ['start'] and not public.get_sshd_status():
|
||||
msg = 'Service SSHD start failed!'
|
||||
public.WriteLog("TYPE_FIREWALL", msg)
|
||||
return public.returnMsg(False,msg)
|
||||
public.WriteLog("TYPE_FIREWALL", msg)
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
|
||||
|
||||
#设置ping
|
||||
def SetPing(self,get):
|
||||
if get.status == '1':
|
||||
@@ -243,20 +299,27 @@ class firewalls:
|
||||
conf = re.sub(rep,'net.ipv4.icmp_echo_ignore_all='+get.status,conf)
|
||||
else:
|
||||
conf += "\nnet.ipv4.icmp_echo_ignore_all="+get.status
|
||||
|
||||
|
||||
public.writeFile(filename,conf)
|
||||
public.ExecShell('sysctl -p')
|
||||
return public.returnMsg(True,'SUCCESS')
|
||||
|
||||
|
||||
|
||||
|
||||
if public.writeFile(filename,conf):
|
||||
public.ExecShell('sysctl -p')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
else:
|
||||
return public.returnMsg(False,'Setup failed!')
|
||||
|
||||
|
||||
|
||||
#改远程端口
|
||||
def SetSshPort(self,get):
|
||||
port = get.port
|
||||
if int(port) < 22 or int(port) > 65535: return public.returnMsg(False,'FIREWALL_SSH_PORT_ERR')
|
||||
if not port:
|
||||
return public.return_msg_gettext(False, 'Port range must be between 22 and 65535!')
|
||||
try:
|
||||
if int(port) < 22 or int(port) > 65535: return public.return_msg_gettext(False,'Port range must be between 22 and 65535!')
|
||||
except:
|
||||
return public.return_msg_gettext(False, 'Port range must be between 22 and 65535!')
|
||||
ports = ['21','25','80','443','8080','888','8888','7800']
|
||||
if port in ports: return public.returnMsg(False,'DONT_USE_PORT')
|
||||
if port in ports: return public.return_msg_gettext(False,'Do NOT use common default port!')
|
||||
file = '/etc/ssh/sshd_config'
|
||||
conf = public.readFile(file)
|
||||
|
||||
@@ -270,47 +333,22 @@ class firewalls:
|
||||
public.ExecShell('sed -i "s#SELINUX=enforcing#SELINUX=disabled#" /etc/selinux/config')
|
||||
public.ExecShell("systemctl restart sshd.service")
|
||||
elif self.__isUfw:
|
||||
public.ExecShell('ufw allow ' + port + '/tcp')
|
||||
public.ExecShell('{} allow '.format(self.__ufw_exec) + port + '/tcp')
|
||||
public.ExecShell("service ssh restart")
|
||||
else:
|
||||
public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport '+port+' -j ACCEPT')
|
||||
public.ExecShell("/etc/init.d/sshd restart")
|
||||
|
||||
|
||||
self.FirewallReload()
|
||||
public.M('firewall').where("ps=? or ps=? or port=?",('SSH remote management service','SSH remote service',port)).delete()
|
||||
public.M('firewall').add('port,ps,addtime',(port,'SSH remote service',time.strftime('%Y-%m-%d %X',time.localtime())))
|
||||
public.WriteLog("TYPE_FIREWALL", "FIREWALL_SSH_PORT",(port,))
|
||||
return public.returnMsg(True,'EDIT_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
#取SSH信息
|
||||
def GetSshInfo(self,get):
|
||||
port = public.get_ssh_port()
|
||||
|
||||
pid_file = '/run/sshd.pid'
|
||||
if os.path.exists(pid_file):
|
||||
pid = int(public.readFile(pid_file))
|
||||
status = public.pid_exists(pid)
|
||||
else:
|
||||
import system
|
||||
panelsys = system.system()
|
||||
|
||||
version = panelsys.GetSystemVersion()
|
||||
if os.path.exists('/usr/bin/apt-get'):
|
||||
if os.path.exists('/etc/init.d/sshd'):
|
||||
status = public.ExecShell("service sshd status | grep -P '(dead|stop)'|grep -v grep")
|
||||
else:
|
||||
status = public.ExecShell("service ssh status | grep -P '(dead|stop)'|grep -v grep")
|
||||
else:
|
||||
if version.find(' 7.') != -1 or version.find(' 8.') != -1 or version.find('Fedora') != -1:
|
||||
status = public.ExecShell("systemctl status sshd.service | grep 'dead'|grep -v grep")
|
||||
else:
|
||||
status = public.ExecShell("/etc/init.d/sshd status | grep -e 'stopped' -e '已停'|grep -v grep")
|
||||
|
||||
# return status;
|
||||
if len(status[0]) > 3:
|
||||
status = False
|
||||
else:
|
||||
status = True
|
||||
port = public.get_sshd_port()
|
||||
status = public.get_sshd_status()
|
||||
isPing = True
|
||||
try:
|
||||
file = '/etc/sysctl.conf'
|
||||
@@ -325,6 +363,6 @@ class firewalls:
|
||||
data['port'] = port
|
||||
data['status'] = status
|
||||
data['ping'] = isPing
|
||||
data['firewall_status'] = self.CheckFirewallStatus()
|
||||
return data
|
||||
|
||||
|
||||
|
||||
|
||||
+20
-2
@@ -2,7 +2,7 @@ import sys,os
|
||||
from gzip import GzipFile
|
||||
from io import BytesIO
|
||||
|
||||
from flask import request, current_app,session,Response,g
|
||||
from flask import request, current_app,session,Response,g,abort
|
||||
|
||||
|
||||
if sys.version_info[:2] == (2, 6):
|
||||
@@ -80,7 +80,8 @@ class Compress(object):
|
||||
accept_encoding = request.headers.get('Accept-Encoding', '')
|
||||
response.headers['Server'] = 'nginx'
|
||||
response.headers['Connection'] = 'keep-alive'
|
||||
|
||||
if not 'tmp_login' in session:
|
||||
response.headers["X-Frame-Options"] = "SAMEORIGIN"
|
||||
if 'dologin' in g and app.config['SSL']:
|
||||
try:
|
||||
for k,v in request.cookies.items():
|
||||
@@ -104,6 +105,23 @@ class Compress(object):
|
||||
if request_token:
|
||||
response.set_cookie('request_token',request_token,path='/',max_age=86400 * 30)
|
||||
|
||||
if response.content_length is not None:
|
||||
if response.content_length < 512:
|
||||
if not session.get('login',None) or g.get('api_request',None):
|
||||
import public
|
||||
default_pl = "{}/default.pl".format(public.get_panel_path())
|
||||
default_body = public.readFile(default_pl,'rb')
|
||||
|
||||
if default_body:
|
||||
if not default_body: default_body = b""
|
||||
resp_body = response.get_data()
|
||||
|
||||
if default_body and resp_body.find(default_body.strip()) != -1:
|
||||
result = b'{"status":false,"msg":"Error: 403 Forbidden"}'
|
||||
response.set_data(result)
|
||||
response.headers['Content-Length'] = len(result)
|
||||
return response
|
||||
|
||||
|
||||
if (response.mimetype not in app.config['COMPRESS_MIMETYPES'] or
|
||||
'gzip' not in accept_encoding.lower() or
|
||||
|
||||
@@ -286,25 +286,21 @@ class MemcachedSessionInterface(SessionInterface):
|
||||
session_id = self._get_signer(app).sign(want_bytes(session.sid))
|
||||
else:
|
||||
session_id = session.sid
|
||||
from BTPanel import request, g, get_input
|
||||
from BTPanel import request,g,get_input
|
||||
if 'auth_error' in g: return
|
||||
if request.path in ['/', '/tips','/robots.txt']: return
|
||||
if request.path in ['/', '/tips', '/robots.txt', '/favicon.ico', '/hook', '/close', '/down/']: return
|
||||
if request.path in ['/public']:
|
||||
get = get_input()
|
||||
if 'get_ping' in get: return
|
||||
if not '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
|
||||
if response.status_code not in [200,308]: return
|
||||
else:
|
||||
if response.status_code not in [302, 301]: return
|
||||
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:
|
||||
samesite = 'None'
|
||||
secure = True
|
||||
response.set_cookie(app.session_cookie_name, session_id,
|
||||
expires=expires, httponly=httponly,
|
||||
domain=domain, path=path, secure=secure,samesite=samesite)
|
||||
|
||||
+96
-42
@@ -20,94 +20,100 @@ class ftp:
|
||||
#添加FTP
|
||||
def AddUser(self,get):
|
||||
try:
|
||||
if not os.path.exists('/www/server/pure-ftpd/sbin/pure-ftpd'): return public.returnMsg(False,'Please install the Pure-FTPd service in the software store first.')
|
||||
if not os.path.exists('/www/server/pure-ftpd/sbin/pure-ftpd'): return public.return_msg_gettext(False,'Please install the Pure-FTPd service in the software store first.')
|
||||
import files,time
|
||||
fileObj=files.files()
|
||||
if re.search("\W + ",get['ftp_username']): return {'status':False,'code':501,'msg':public.getMsg('FTP_USERNAME_ERR_T')}
|
||||
if len(get['ftp_username']) < 3: return {'status':False,'code':501,'msg':public.getMsg('FTP_USERNAME_ERR_LEN')}
|
||||
if not fileObj.CheckDir(get['path']): return {'status':False,'code':501,'msg':public.getMsg('FTP_USERNAME_ERR_DIR')}
|
||||
if public.M('ftps').where('name=?',(get.ftp_username.strip(),)).count(): return public.returnMsg(False,'FTP_USERNAME_ERR_EXISTS',(get.ftp_username,))
|
||||
username = get['ftp_username'].replace(' ','')
|
||||
password = get['ftp_password']
|
||||
if get['ftp_username'].strip().find(' ') != -1: return public.returnMsg(False,'Username cannot contain spaces')
|
||||
if re.search("\W + ",get['ftp_username']): return {'status':False,'code':501,'msg':public.get_msg_gettext('Username is illegal, special characters are NOT allowed!')}
|
||||
if len(get['ftp_username']) < 3: return {'status':False,'code':501,'msg':public.get_msg_gettext('Username is illegal, cannot be less than 3 characters!')}
|
||||
if not fileObj.CheckDir(get['path']): return {'status':False,'code':501,'msg':public.get_msg_gettext('System critical directory cannot be used as FTP directory!')}
|
||||
if public.M('ftps').where('name=?',(get.ftp_username.strip(),)).count(): return public.return_msg_gettext(False,'User [{}] exists!',(get.ftp_username,))
|
||||
username = get['ftp_username'].strip()
|
||||
if re.search("[\/\\\:\*\?\"\'\<\>\|]+",username):
|
||||
return public.return_msg_gettext(False,"Name cannot contain /\:*?\"<>| symbol")
|
||||
password = get['ftp_password'].strip()
|
||||
if len(password) < 6: return public.return_msg_gettext(False, 'Password must be at least [{}] characters',("6",))
|
||||
get.path = get['path'].replace(' ','')
|
||||
get.path = get.path.replace("\\", "/")
|
||||
fileObj.CreateDir(get)
|
||||
public.ExecShell('chown www.www ' + get.path)
|
||||
public.ExecShell(self.__runPath + '/pure-pw useradd ' + username + ' -u www -d ' + get.path + '<<EOF \n' + password + '\n' + password + '\nEOF')
|
||||
public.ExecShell(self.__runPath + '/pure-pw useradd "' + username + '" -u www -d ' + get.path + '<<EOF \n' + password + '\n' + password + '\nEOF')
|
||||
self.FtpReload()
|
||||
ps=public.xssencode(get['ps'])
|
||||
if get['ps']=='': ps= public.getMsg('INPUT_PS');
|
||||
ps = public.xssencode2(get['ps'])
|
||||
if get['ps']=='': ps= public.get_msg_gettext('Edit notes');
|
||||
addtime=time.strftime('%Y-%m-%d %X',time.localtime())
|
||||
|
||||
pid = 0
|
||||
if hasattr(get,'pid'): pid = get.pid
|
||||
public.M('ftps').add('pid,name,password,path,status,ps,addtime',(pid,username,password,get.path,1,ps,addtime))
|
||||
public.WriteLog('TYPE_FTP', 'FTP_ADD_SUCCESS',(username,))
|
||||
return public.returnMsg(True,'ADD_SUCCESS')
|
||||
public.write_log_gettext('FTP manager', 'Successfully added FTP user [{}]!',(username,))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
except Exception as ex:
|
||||
public.WriteLog('TYPE_FTP', 'FTP_ADD_ERR',(username,str(ex)))
|
||||
return public.returnMsg(False,'ADD_ERROR')
|
||||
public.write_log_gettext('FTP manager', 'Failed to add FTP user[{}]! => {}',(username,str(ex)))
|
||||
return public.return_msg_gettext(False,'Failed to add')
|
||||
|
||||
#删除用户
|
||||
def DeleteUser(self,get):
|
||||
try:
|
||||
username = get['username']
|
||||
id = get['id']
|
||||
public.ExecShell(self.__runPath + '/pure-pw userdel ' + username)
|
||||
public.ExecShell(self.__runPath + '/pure-pw userdel "' + username + '"')
|
||||
self.FtpReload()
|
||||
public.M('ftps').where("id=?",(id,)).delete()
|
||||
public.WriteLog('TYPE_FTP', 'FTP_DEL_SUCCESS',(username,))
|
||||
return public.returnMsg(True, "DEL_SUCCESS")
|
||||
public.write_log_gettext('FTP manager', 'Successfully deleted FTP user[{}]!',(username,))
|
||||
return public.return_msg_gettext(True, 'Successfully deleted')
|
||||
except Exception as ex:
|
||||
public.WriteLog('TYPE_FTP', 'FTP_DEL_ERR',(username,str(ex)))
|
||||
return public.returnMsg(False,'DEL_ERROR')
|
||||
public.write_log_gettext('FTP manager', 'Faided to delete FTP user[{}]! => {}',(username,str(ex)))
|
||||
return public.return_msg_gettext(False,'Failed to delete')
|
||||
|
||||
|
||||
#修改用户密码
|
||||
def SetUserPassword(self,get):
|
||||
try:
|
||||
id = get['id']
|
||||
username = get['ftp_username']
|
||||
password = get['new_password']
|
||||
public.ExecShell(self.__runPath + '/pure-pw passwd ' + username + '<<EOF \n' + password + '\n' + password + '\nEOF')
|
||||
username = get['ftp_username'].strip()
|
||||
password = get['new_password'].strip()
|
||||
if len(password) < 6: return public.return_msg_gettext(False,'Password must be at least [{}] characters',("6",))
|
||||
public.ExecShell(self.__runPath + '/pure-pw passwd "' + username + '"<<EOF \n' + password + '\n' + password + '\nEOF')
|
||||
self.FtpReload()
|
||||
public.M('ftps').where("id=?",(id,)).setField('password',password)
|
||||
public.WriteLog('TYPE_FTP', 'FTP_PASS_SUCCESS',(username,))
|
||||
return public.returnMsg(True,'EDIT_SUCCESS')
|
||||
public.write_log_gettext('FTP manager', 'Successfully changed password for FTP user[{}]!',(username,))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
except Exception as ex:
|
||||
public.WriteLog('TYPE_FTP', 'FTP_PASS_ERR',(username,str(ex)))
|
||||
return public.returnMsg(False,'EDIT_ERROR')
|
||||
public.write_log_gettext('FTP manager', 'Failed to change password FTP user[{}]! => {}',(username,str(ex)))
|
||||
return public.return_msg_gettext(False,'Failed to modify')
|
||||
|
||||
|
||||
#设置用户状态
|
||||
def SetStatus(self,get):
|
||||
msg = public.getMsg('OFF');
|
||||
if get.status != '0': msg = public.getMsg('ON');
|
||||
msg = public.get_msg_gettext('Turn off');
|
||||
if get.status != '0': msg = public.get_msg_gettext('Turn on');
|
||||
try:
|
||||
id = get['id']
|
||||
username = get['username']
|
||||
status = get['status']
|
||||
if int(status)==0:
|
||||
public.ExecShell(self.__runPath + '/pure-pw usermod ' + username + ' -r 1')
|
||||
public.ExecShell(self.__runPath + '/pure-pw usermod "' + username + '" -r 1')
|
||||
else:
|
||||
public.ExecShell(self.__runPath + '/pure-pw usermod ' + username + " -r ''")
|
||||
public.ExecShell(self.__runPath + '/pure-pw usermod "' + username + "\" -r ''")
|
||||
self.FtpReload()
|
||||
public.M('ftps').where("id=?",(id,)).setField('status',status)
|
||||
public.WriteLog('TYPE_FTP','FTP_STATUS', (msg,username))
|
||||
return public.returnMsg(True, 'SUCCESS')
|
||||
public.write_log_gettext('FTP manager','Successfully {} FTP user [{}]!', (msg,username))
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
except Exception as ex:
|
||||
public.WriteLog('TYPE_FTP','FTP_STATUS_ERR', (msg,username,str(ex)))
|
||||
return public.returnMsg(False,'FTP_STATUS_ERR',(msg,))
|
||||
public.write_log_gettext('FTP manager','Failed to {} FTP user [{}]! => {}', (msg,username,str(ex)))
|
||||
return public.return_msg_gettext(False,'{} FTP user failed!',(msg,))
|
||||
|
||||
'''
|
||||
* 设置FTP端口
|
||||
* @param Int _GET['port'] 端口号
|
||||
* @param Int _GET['port'] 端口号
|
||||
* @return bool
|
||||
'''
|
||||
def setPort(self,get):
|
||||
try:
|
||||
port = get['port']
|
||||
if int(port) < 1 or int(port) > 65535: return public.returnMsg(False,'PORT_CHECK_RANGE')
|
||||
port = get['port'].strip()
|
||||
if not port: return public.returnMsg(False,'Please enter an integer for the port')
|
||||
if int(port) < 1 or int(port) > 65535: return public.return_msg_gettext(False,'Port range is incorrect!')
|
||||
file = '/www/server/pure-ftpd/etc/pure-ftpd.conf'
|
||||
conf = public.readFile(file)
|
||||
rep = u"\n#?\s*Bind\s+[0-9]+\.[0-9]+\.[0-9]+\.+[0-9]+,([0-9]+)"
|
||||
@@ -115,18 +121,66 @@ class ftp:
|
||||
conf = re.sub(rep,"\nBind 0.0.0.0," + port,conf)
|
||||
public.writeFile(file,conf)
|
||||
public.ExecShell('/etc/init.d/pure-ftpd restart')
|
||||
public.WriteLog('TYPE_FTP', "FTP_PORT",(port,))
|
||||
public.write_log_gettext('FTP manager', "Successfully modified FTP port to [{}]!",(port,))
|
||||
#添加防火墙
|
||||
#data = ftpinfo(port=port,ps = 'FTP端口')
|
||||
get.port=port
|
||||
get.ps = public.getMsg('FTP_PORT_PS');
|
||||
get.ps = public.get_msg_gettext('FTP port');
|
||||
firewalls.firewalls().AddAcceptPort(get)
|
||||
session['port']=port
|
||||
return public.returnMsg(True, 'EDIT_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
except Exception as ex:
|
||||
public.WriteLog('TYPE_FTP', 'FTP_PORT_ERR',(str(ex),))
|
||||
return public.returnMsg(False,'EDIT_ERROR')
|
||||
public.write_log_gettext('FTP manager', 'Failed to modify FTP port! => {}',(str(ex),))
|
||||
return public.return_msg_gettext(False,'Failed to modify')
|
||||
|
||||
#重载配置
|
||||
def FtpReload(self):
|
||||
public.ExecShell(self.__runPath + '/pure-pw mkdb /www/server/pure-ftpd/etc/pureftpd.pdb')
|
||||
|
||||
#修改用户密码
|
||||
def set_user_home(self,get):
|
||||
"""
|
||||
change user home
|
||||
id: ftp id
|
||||
path: the new ftp user home
|
||||
ftp_username: ftp username
|
||||
migrate: migrate ftp user data to the new home
|
||||
|
||||
"""
|
||||
try:
|
||||
id = get['id']
|
||||
path = get['path']
|
||||
username = get['ftp_username']
|
||||
# get the old path in the panel sqlite db
|
||||
old_path = public.M("ftps").where("id=?",(id,)).getField('path')
|
||||
# check the auth ftp user if exists
|
||||
auth_conf_file = '/www/server/pure-ftpd/etc/pureftpd.passwd'
|
||||
auth_conf = public.readFile(auth_conf_file)
|
||||
if not auth_conf:
|
||||
return public.returnMsg(False,'FTP account has not been set up')
|
||||
# get the user specified conf
|
||||
auth_conf_list = [i for i in auth_conf.split('\n')]
|
||||
rep = '^{}:.*'.format(username)
|
||||
macth_conf = [i for i in auth_conf_list if re.search(rep,i)]
|
||||
if not macth_conf:
|
||||
return public.returnMsg(False, 'FTP account has not been set up1')
|
||||
if len(macth_conf) > 1:
|
||||
return public.returnMsg(False, 'Matching multiple configurations, this operation has been stopped!')
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
public.ExecShell('chown www.www ' + path)
|
||||
# replace the old path
|
||||
result = macth_conf[0]
|
||||
specified_user_conf = result.replace(old_path,path)
|
||||
auth_conf = auth_conf.replace(result,specified_user_conf)
|
||||
public.writeFile(auth_conf_file,auth_conf)
|
||||
if get.migrate == '1':
|
||||
public.ExecShell('cp -rp {}/* {}'.format(old_path,path))
|
||||
self.FtpReload()
|
||||
public.M('ftps').where("id=?",(id,)).setField('path',path)
|
||||
public.write_log_gettext('FTP manager', 'Successfully changed password for FTP user[{}]!',(path,))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
except Exception as ex:
|
||||
return public.get_error_info()
|
||||
public.write_log_gettext('FTP manager', 'FTP_PASS_ERR',(path,str(ex)))
|
||||
return public.returnMsg(False,'EDIT_ERROR')
|
||||
+83
-29
@@ -14,22 +14,31 @@ import os,sys,re
|
||||
import ssl
|
||||
import public
|
||||
import json
|
||||
import socket
|
||||
import requests
|
||||
import requests.packages.urllib3.util.connection as urllib3_conn
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
class http:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get(self,url,timeout = 60,headers = {},verify = False,type = 'python'):
|
||||
url = self.quote(url)
|
||||
if type == 'python':
|
||||
old_family = urllib3_conn.allowed_gai_family
|
||||
try:
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
from requests import get as req_get
|
||||
return req_get(url,timeout=timeout,headers=get_headers(headers),verify=verify)
|
||||
# 默认使用IPv4
|
||||
urllib3_conn.allowed_gai_family = lambda: socket.AF_INET
|
||||
return requests.get(url,timeout=timeout,headers=get_headers(headers),verify=verify)
|
||||
except:
|
||||
result = self._get_curl(url,timeout,headers,verify)
|
||||
try:
|
||||
# IPV6?
|
||||
urllib3_conn.allowed_gai_family = lambda: socket.AF_INET6
|
||||
return requests.get(url,timeout=timeout,headers=get_headers(headers),verify=verify)
|
||||
except:
|
||||
# 使用CURL
|
||||
result = self._get_curl(url,timeout,headers,verify)
|
||||
urllib3_conn.allowed_gai_family = old_family
|
||||
|
||||
elif type == 'curl':
|
||||
result = self._get_curl(url,timeout,headers,verify)
|
||||
elif type == 'php':
|
||||
@@ -44,14 +53,20 @@ class http:
|
||||
def post(self,url,data,timeout = 60,headers = {},verify = False,type = 'python'):
|
||||
url = self.quote(url)
|
||||
if type == 'python':
|
||||
old_family = urllib3_conn.allowed_gai_family
|
||||
try:
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
from requests import post as req_post
|
||||
return req_post(url,data,timeout=timeout,headers=headers,verify=verify)
|
||||
urllib3_conn.allowed_gai_family = lambda: socket.AF_INET
|
||||
return requests.post(url,data,timeout=timeout,headers=headers,verify=verify)
|
||||
except:
|
||||
result = self._post_curl(url,data,timeout,headers,verify)
|
||||
try:
|
||||
# IPV6?
|
||||
urllib3_conn.allowed_gai_family = lambda: socket.AF_INET6
|
||||
return requests.post(url,data,timeout=timeout,headers=headers,verify=verify)
|
||||
except:
|
||||
# 使用CURL
|
||||
result = self._post_curl(url,data,timeout,headers,verify)
|
||||
urllib3_conn.allowed_gai_family = old_family
|
||||
|
||||
elif type == 'curl':
|
||||
result = self._post_curl(url,data,timeout,headers,verify)
|
||||
elif type == 'php':
|
||||
@@ -63,6 +78,30 @@ class http:
|
||||
result = self._post_py3(url,data,timeout,headers,verify)
|
||||
return result
|
||||
|
||||
|
||||
def download_file(self,url,filename,data = None,timeout = 1800,speed_file='/dev/shm/download_speed.pl'):
|
||||
'''
|
||||
@name 下载文件
|
||||
@author hwliang<2021-07-08>
|
||||
@param url<string> 下载地址
|
||||
@param filename<string> 保存路径
|
||||
@param data<dict> POST参数,不传则使用GET方法,否则使用POST方法
|
||||
@param timeout<int> 超时时间,默认1800秒
|
||||
@param speed_file<string>
|
||||
'''
|
||||
import requests
|
||||
from requests.packages.urllib3.exceptions import InsecureRequestWarning
|
||||
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
|
||||
headers = public.get_requests_headers()
|
||||
if data is None:
|
||||
res = requests.get(url,headers=headers,timeout=timeout,stream=True)
|
||||
else:
|
||||
res = requests.post(url,data,headers=headers,timeout=timeout,stream=True)
|
||||
with open(filename,"wb") as f:
|
||||
for _chunk in res.iter_content(chunk_size=8192):
|
||||
f.write(_chunk)
|
||||
|
||||
|
||||
#POST请求 Python2
|
||||
def _post_py2(self,url,data,timeout,headers,verify):
|
||||
import urllib2
|
||||
@@ -114,18 +153,21 @@ class http:
|
||||
raise Exception('No PHP version available!')
|
||||
tmp_file = '/dev/shm/http.php'
|
||||
http_php = '''<?php
|
||||
if(isset($_POST['data'])){
|
||||
error_reporting(E_ERROR);
|
||||
if(isset($_POST['data'])){{
|
||||
$data = json_decode($_POST['data'],1);
|
||||
}else{
|
||||
$data = json_decode(getopt('',array('post:'))['post'],1);
|
||||
}
|
||||
}}else{{
|
||||
$s = getopt('',array('post:'));
|
||||
$data = json_decode($s['post'],1);
|
||||
}}
|
||||
$url = $data['url'];
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER,$data['headers']);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, TRUE);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data['data']));
|
||||
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data['data']);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $data['verify']);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $data['verify']);
|
||||
@@ -145,10 +187,13 @@ exit($header."\r\n\r\n".json_encode($body));
|
||||
# data = json.dumps(pdata)
|
||||
|
||||
data = json.dumps({"url":url,"timeout":timeout,"verify":verify,"headers":self._php_headers(headers),"data":data})
|
||||
if php_version in ['53']:
|
||||
php_version = '/www/server/php/' + php_version + '/bin/php'
|
||||
if php_version.find('/www/server/php') != -1:
|
||||
result = public.ExecShell(php_version + ' ' + tmp_file + " --post='" + data + "'" )[0]
|
||||
else:
|
||||
result = public.request_php(php_version,'/http.php','/dev/shm','POST',{"data":data})
|
||||
if isinstance(result,bytes): result = result.decode('utf-8')
|
||||
|
||||
if os.path.exists(tmp_file): os.remove(tmp_file)
|
||||
r_body,r_headers,r_status_code = self._curl_format(result)
|
||||
@@ -209,7 +254,7 @@ exit($header."\r\n\r\n".json_encode($body));
|
||||
headers_str = self._str_headers(headers)
|
||||
_ssl_verify = ''
|
||||
if not verify: _ssl_verify = ' -k'
|
||||
result = public.ExecShell("{} -sS -i --connect-timeout {} {} {} 2>&1".format(self._curl_bin() + _ssl_verify,timeout,headers_str,url))[0]
|
||||
result = public.ExecShell("{} -sS -i --connect-timeout {} {} {} 2>&1".format(self._curl_bin() + ' ' + str(_ssl_verify),timeout,headers_str,url))[0]
|
||||
r_body,r_headers,r_status_code = self._curl_format(result)
|
||||
return response(r_body,r_status_code,r_headers)
|
||||
|
||||
@@ -220,11 +265,13 @@ exit($header."\r\n\r\n".json_encode($body));
|
||||
raise Exception('No PHP version available!')
|
||||
tmp_file = '/dev/shm/http.php'
|
||||
http_php = '''<?php
|
||||
if(isset($_POST['data'])){
|
||||
error_reporting(E_ERROR);
|
||||
if(isset($_POST['data'])){{
|
||||
$data = json_decode($_POST['data'],1);
|
||||
}else{
|
||||
$data = json_decode(getopt('',array('post:'))['post'],1);
|
||||
}
|
||||
}}else{{
|
||||
$s = getopt('',array('post:'));
|
||||
$data = json_decode($s['post'],1);
|
||||
}}
|
||||
$url = $data['url'];
|
||||
$ch = curl_init();
|
||||
$user_agent = "BT-Panel";
|
||||
@@ -247,10 +294,14 @@ exit($header."\r\n\r\n".json_encode($body));
|
||||
?>'''
|
||||
public.writeFile(tmp_file,http_php)
|
||||
data = json.dumps({"url":url,"timeout":timeout,"verify":verify,"headers":self._php_headers(headers)})
|
||||
if php_version in ['53']:
|
||||
php_version = '/www/server/php/' + php_version + '/bin/php'
|
||||
if php_version.find('/www/server/php') != -1:
|
||||
result = public.ExecShell(php_version + ' ' + tmp_file + " --post='" + data + "'" )[0]
|
||||
else:
|
||||
result = public.request_php(php_version,'/http.php','/dev/shm','POST',{"data":data})
|
||||
if isinstance(result,bytes): result = result.decode('utf-8')
|
||||
|
||||
if os.path.exists(tmp_file): os.remove(tmp_file)
|
||||
r_body,r_headers,r_status_code = self._curl_format(result)
|
||||
return response(json.loads(r_body).strip(),r_status_code,r_headers)
|
||||
@@ -259,7 +310,8 @@ exit($header."\r\n\r\n".json_encode($body));
|
||||
|
||||
#取可用的PHP版本
|
||||
def _get_php_version(self):
|
||||
php_versions = ['52','53','54','55','56','70','71','72','73','74','80']
|
||||
php_versions = public.get_php_versions()
|
||||
php_versions = sorted(php_versions,reverse=True)
|
||||
php_path = '/www/server/php/{}/sbin/php-fpm'
|
||||
php_sock = '/tmp/php-cgi-{}.sock'
|
||||
for pv in php_versions:
|
||||
@@ -276,9 +328,11 @@ exit($header."\r\n\r\n".json_encode($body));
|
||||
#取CURL路径
|
||||
def _curl_bin(self):
|
||||
c_bin = ['/usr/local/curl2/bin/curl','/usr/local/curl/bin/curl','/usr/local/bin/curl','/usr/bin/curl']
|
||||
curl_bin = 'curl'
|
||||
for cb in c_bin:
|
||||
if os.path.exists(cb): curl_bin = cb
|
||||
if os.path.exists(cb): return cb
|
||||
return 'curl'
|
||||
return curl_bin
|
||||
|
||||
#格式化CURL响应头
|
||||
def _curl_format(self,req):
|
||||
@@ -396,7 +450,7 @@ class response:
|
||||
return self.text
|
||||
|
||||
DEFAULT_HEADERS = {"Content-type":"application/x-www-form-urlencoded","User-Agent":"BT-Panel"}
|
||||
s_types = ['python','php','curl']
|
||||
s_types = ['python','php','curl','src']
|
||||
DEFAULT_TYPE = 'python'
|
||||
__version__ = 1.0
|
||||
|
||||
|
||||
+75
-4
@@ -48,6 +48,19 @@ def control_init():
|
||||
if not public.M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'sites','%project_config%')).count():
|
||||
public.M('sites').execute("alter TABLE sites add project_config STRING DEFAULT '{}'",())
|
||||
|
||||
if not public.M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'backup','%ps%')).count():
|
||||
public.M('backup').execute("alter TABLE backup add ps STRING DEFAULT 'No'",())
|
||||
|
||||
if not public.M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'databases','%db_type%')).count():
|
||||
public.M('databases').execute("alter TABLE databases add db_type integer DEFAULT '0'",())
|
||||
|
||||
if not public.M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'databases','%conn_config%')).count():
|
||||
public.M('databases').execute("alter TABLE databases add conn_config STRING DEFAULT '{}'",())
|
||||
|
||||
if not public.M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'databases','%sid%')).count():
|
||||
public.M('databases').execute("alter TABLE databases add sid integer DEFAULT 0",())
|
||||
|
||||
|
||||
sql = db.Sql()
|
||||
if not sql.table('sqlite_master').where('type=? AND name=?', ('table', 'site_types')).count():
|
||||
csql = '''CREATE TABLE IF NOT EXISTS `site_types` (
|
||||
@@ -94,6 +107,18 @@ def control_init():
|
||||
`logout_time` INTEGER,
|
||||
`expire` INTEGER,
|
||||
`addtime` INTEGER
|
||||
)'''
|
||||
sql.execute(csql,())
|
||||
|
||||
if not sql.table('sqlite_master').where('type=? AND name=?', ('table', 'database_servers')).count():
|
||||
csql = '''CREATE TABLE IF NOT EXISTS `database_servers` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`db_host` REAL,
|
||||
`db_port` REAL,
|
||||
`db_user` INTEGER,
|
||||
`db_password` INTEGER,
|
||||
`ps` REAL,
|
||||
`addtime` INTEGER
|
||||
)'''
|
||||
sql.execute(csql,())
|
||||
|
||||
@@ -161,10 +186,19 @@ def control_init():
|
||||
public.ExecShell("rm -rf /www/server/panel/adminer")
|
||||
if os.path.exists('/dev/shm/session.db'):
|
||||
os.remove('/dev/shm/session.db')
|
||||
|
||||
node_service_bin = '/usr/bin/nodejs-service'
|
||||
node_service_src = '/www/server/panel/script/nodejs-service.py'
|
||||
if os.path.exists(node_service_src): public.ExecShell("chmod 700 " + node_service_src)
|
||||
if not os.path.exists(node_service_bin):
|
||||
if os.path.exists(node_service_src):
|
||||
public.ExecShell("ln -sf {} {}".format(node_service_src,node_service_bin))
|
||||
|
||||
#disable_putenv('putenv')
|
||||
#clean_session()
|
||||
#set_crond()
|
||||
test_ping()
|
||||
set_wp_cache_dir()
|
||||
clean_max_log('/www/server/panel/plugin/rsync/lsyncd.log')
|
||||
clean_max_log('/var/log/rsyncd.log',1024*1024*10)
|
||||
clean_max_log('/root/.pm2/pm2.log',1024*1024*20)
|
||||
@@ -182,7 +216,12 @@ def control_init():
|
||||
update_py37()
|
||||
run_script()
|
||||
set_php_cli_env()
|
||||
check_enable_php()
|
||||
|
||||
def set_wp_cache_dir():
|
||||
import one_key_wp
|
||||
one_key_wp.fast_cgi().set_nginx_conf()
|
||||
public.ExecShell("/etc/init.d/nginx restart")
|
||||
|
||||
def set_php_cli_env():
|
||||
'''
|
||||
@@ -209,7 +248,7 @@ def set_php_cli_env():
|
||||
|
||||
|
||||
# 设置所有已安装的PHP版本环境变量和别名
|
||||
php_versions_list = ['52','53','54','55','56','70','71','72','73','74','80','81','82','83','84','90','91']
|
||||
php_versions_list = public.get_php_versions()
|
||||
for php_version in php_versions_list:
|
||||
php_ini = "{}/{}/etc/php.ini".format(php_path,php_version)
|
||||
php_cli_ini = "{}/{}/etc/php-cli.ini".format(php_path,php_version)
|
||||
@@ -244,6 +283,30 @@ def set_php_cli_env():
|
||||
public.writeFile(bashrc,bashrc_body)
|
||||
|
||||
|
||||
def check_enable_php():
|
||||
'''
|
||||
@name 检查nginx下的php配置文件
|
||||
'''
|
||||
php_versions = public.get_php_versions()
|
||||
ngx_php_conf = public.get_setup_path() + '/nginx/conf/enable-php-00.conf'
|
||||
public.writeFile(ngx_php_conf,'')
|
||||
for php_v in php_versions:
|
||||
ngx_php_conf = public.get_setup_path() + '/nginx/conf/enable-php-{}.conf'.format(php_v)
|
||||
if os.path.exists(ngx_php_conf): continue
|
||||
enable_conf = '''
|
||||
location ~ [^/]\.php(/|$)
|
||||
{{
|
||||
try_files $uri =404;
|
||||
fastcgi_pass unix:/tmp/php-cgi-{}.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi.conf;
|
||||
include pathinfo.conf;
|
||||
}}
|
||||
'''.format(php_v)
|
||||
public.writeFile(ngx_php_conf,enable_conf)
|
||||
|
||||
|
||||
|
||||
def write_run_script_log(_log,rn='\n'):
|
||||
_log_file = '/www/server/panel/logs/run_script.log'
|
||||
public.writeFile(_log_file,_log + rn,'a+')
|
||||
@@ -319,7 +382,6 @@ def files_set_mode():
|
||||
["/www/server/stop","","root",755,True],
|
||||
["/www/server/redis","","redis",700,True],
|
||||
["/www/server/redis/redis.conf","","redis",600,False],
|
||||
["/www/Recycle_bin","","root",600,True],
|
||||
["/www/server/panel/class","","root",600,True],
|
||||
["/www/server/panel/data","","root",600,True],
|
||||
["/www/server/panel/plugin","","root",600,False],
|
||||
@@ -345,6 +407,10 @@ def files_set_mode():
|
||||
["/www/server/coll","","root",700,True]
|
||||
]
|
||||
|
||||
recycle_list = public.get_recycle_bin_list()
|
||||
for recycle_path in recycle_list:
|
||||
m_paths.append([recycle_path,'','root',600,True])
|
||||
|
||||
for m in m_paths:
|
||||
if not os.path.exists(m[0]): continue
|
||||
path = m[0] + m[1]
|
||||
@@ -409,7 +475,7 @@ def set_pma_access():
|
||||
|
||||
#尝试升级到独立环境
|
||||
def update_py37():
|
||||
pyenv='/www/server/panel/pyenv/bin/python'
|
||||
pyenv='/www/server/panel/pyenv/bin/python3'
|
||||
pyenv_exists='/www/server/panel/data/pyenv_exists.pl'
|
||||
if os.path.exists(pyenv) or os.path.exists(pyenv_exists): return False
|
||||
download_url = public.get_url()
|
||||
@@ -552,7 +618,7 @@ def disable_putenv(fun_name):
|
||||
try:
|
||||
is_set_disable = '/www/server/panel/data/disable_%s' % fun_name
|
||||
if os.path.exists(is_set_disable): return True
|
||||
php_vs = ('52','53','54','55','56','70','71','72','73','74')
|
||||
php_vs = public.get_php_versions()
|
||||
php_ini = "/www/server/php/{0}/etc/php.ini"
|
||||
rep = "disable_functions\s*=\s*.*"
|
||||
for pv in php_vs:
|
||||
@@ -619,3 +685,8 @@ def clean_session():
|
||||
except:return False
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
control_init()
|
||||
|
||||
|
||||
|
||||
+130
-6
@@ -12,6 +12,7 @@ import json
|
||||
import time
|
||||
import datetime
|
||||
import re
|
||||
import sqlite3
|
||||
|
||||
import public
|
||||
|
||||
@@ -40,6 +41,43 @@ class Monitor:
|
||||
return sites
|
||||
|
||||
def _statuscode_distribute_site(self, site_name):
|
||||
|
||||
try:
|
||||
day_401 = 0
|
||||
day_500 = 0
|
||||
day_502 = 0
|
||||
day_503 = 0
|
||||
conn = None
|
||||
ts = None
|
||||
start_date, end_date = self.get_time_interval(time.localtime())
|
||||
select_sql = "select time/100 as time1, sum(status_401), sum(status_500), sum(status_502), sum(status_503) from request_stat where time between {} and {}"\
|
||||
.format(start_date, end_date)
|
||||
|
||||
db_path = os.path.join("/www/server/total/", "logs/{}/logs.db".format(site_name))
|
||||
if os.path.isfile(db_path):
|
||||
conn = sqlite3.connect(db_path)
|
||||
ts = conn.cursor()
|
||||
ts.execute(select_sql)
|
||||
results = ts.fetchall()
|
||||
|
||||
if type(results) == list:
|
||||
for result in results:
|
||||
time_key = str(result[0])
|
||||
day_401 = result[1]
|
||||
day_500 = result[2]
|
||||
day_502 = result[3]
|
||||
day_503 = result[4]
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
if ts:
|
||||
ts.close()
|
||||
if conn:
|
||||
conn.close()
|
||||
|
||||
return day_401, day_500, day_502, day_503
|
||||
|
||||
def _statuscode_distribute_site_old(self, site_name):
|
||||
today = time.strftime('%Y-%m-%d', time.localtime())
|
||||
path = '/www/server/total/total/' + site_name + '/request/' + today + '.json'
|
||||
|
||||
@@ -52,10 +90,10 @@ class Monitor:
|
||||
|
||||
for c in spdata.values():
|
||||
for d in c:
|
||||
if '401' == d: day_401 += c['401']
|
||||
if '500' == d: day_500 += c['500']
|
||||
if '502' == d: day_502 += c['502']
|
||||
if '503' == d: day_503 += c['503']
|
||||
if '401' == d: day_401 += c['401'] or 0
|
||||
if '500' == d: day_500 += c['500'] or 0
|
||||
if '502' == d: day_502 += c['502'] or 0
|
||||
if '503' == d: day_503 += c['503'] or 0
|
||||
|
||||
return day_401, day_500, day_502, day_503
|
||||
|
||||
@@ -66,6 +104,10 @@ class Monitor:
|
||||
for site in sites:
|
||||
site_name = site['name']
|
||||
day_401, day_500, day_502, day_503 = self._statuscode_distribute_site(site_name)
|
||||
day_401 = day_401 or 0
|
||||
day_500 = day_500 or 0
|
||||
day_502 = day_502 or 0
|
||||
day_503 = day_503 or 0
|
||||
count_401 += day_401
|
||||
count_500 += day_500
|
||||
count_502 += day_502
|
||||
@@ -177,8 +219,45 @@ class Monitor:
|
||||
data.update(statuscode_distribute)
|
||||
return data
|
||||
|
||||
# 获取蜘蛛数量分布
|
||||
def get_spider(self, args):
|
||||
request_data = {}
|
||||
sites = public.M('sites').field('name').order("addtime").select();
|
||||
for site_info in sites:
|
||||
ts = None
|
||||
conn = None
|
||||
try:
|
||||
site_name = site_info["name"]
|
||||
start_date, end_date = self.get_time_interval(time.localtime())
|
||||
select_sql = "select time, spider from request_stat where time between {} and {}"\
|
||||
.format(start_date, end_date)
|
||||
|
||||
db_path = os.path.join("/www/server/total/", "logs/{}/logs.db".format(site_name))
|
||||
if not os.path.isfile(db_path): continue
|
||||
conn = sqlite3.connect(db_path)
|
||||
ts = conn.cursor()
|
||||
ts.execute(select_sql)
|
||||
results = ts.fetchall()
|
||||
|
||||
if type(results) == list:
|
||||
for result in results:
|
||||
time_key = str(result[0])
|
||||
hour = time_key[len(time_key)-2:]
|
||||
value = result[1]
|
||||
if hour not in request_data:
|
||||
request_data[hour] = value
|
||||
else:
|
||||
request_data[hour] += value
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
if ts:
|
||||
ts.close()
|
||||
if conn:
|
||||
conn.close()
|
||||
return request_data
|
||||
|
||||
# 获取蜘蛛数量分布
|
||||
def get_spider_old(self, args):
|
||||
today = time.strftime('%Y-%m-%d', time.localtime())
|
||||
sites = self._get_site_list()
|
||||
|
||||
@@ -210,8 +289,53 @@ class Monitor:
|
||||
|
||||
return {'load_five': load_five, 'cpu_count': cpu_count, 'up_flow': up_flow}
|
||||
|
||||
# 取每小时的请求数
|
||||
def get_time_interval(self, local_time):
|
||||
start = None
|
||||
end = None
|
||||
time_key_format = "%Y%m%d00"
|
||||
start = int(time.strftime(time_key_format, local_time))
|
||||
time_key_format = "%Y%m%d23"
|
||||
end = int(time.strftime(time_key_format, local_time))
|
||||
return start, end
|
||||
|
||||
def get_request_count_by_hour(self, args):
|
||||
# 获取站点每小时的请求数据
|
||||
request_data = {}
|
||||
import sqlite3
|
||||
sites = public.M('sites').field('name').order("addtime").select();
|
||||
for site_info in sites:
|
||||
ts = None
|
||||
conn = None
|
||||
try:
|
||||
site_name = site_info["name"]
|
||||
start_date, end_date = self.get_time_interval(time.localtime())
|
||||
select_sql = "select time, req from request_stat where time between {} and {}"\
|
||||
.format(start_date, end_date)
|
||||
db_path = os.path.join("/www/server/total/", "logs/{}/logs.db".format(site_name))
|
||||
if not os.path.isfile(db_path): continue
|
||||
conn = sqlite3.connect(db_path)
|
||||
ts = conn.cursor()
|
||||
ts.execute(select_sql)
|
||||
results = ts.fetchall()
|
||||
if type(results) == list:
|
||||
for result in results:
|
||||
time_key = str(result[0])
|
||||
hour = time_key[len(time_key)-2:]
|
||||
value = result[1]
|
||||
if hour not in request_data:
|
||||
request_data[hour] = value
|
||||
else:
|
||||
request_data[hour] += value
|
||||
except: pass
|
||||
finally:
|
||||
if ts:
|
||||
ts.close()
|
||||
if conn:
|
||||
conn.close()
|
||||
return request_data
|
||||
|
||||
# 取每小时的请求数
|
||||
def get_request_count_by_hour_old(self, args):
|
||||
today = time.strftime('%Y-%m-%d', time.localtime())
|
||||
|
||||
request_data = {}
|
||||
|
||||
+29
-30
@@ -23,29 +23,29 @@ class nginx:
|
||||
proxycontent = public.readFile(self.proxyfile)
|
||||
for i in [[ngconfcontent,self.nginxconf],[proxycontent,self.proxyfile]]:
|
||||
if not i[0]:
|
||||
return public.returnMsg(False,"Can not find nginx config file [ {} ]".format(i[1]))
|
||||
return public.return_msg_gettext(False,"Can not find nginx config file [ {} ]".format(i[1]))
|
||||
unitrep = "[kmgKMG]"
|
||||
conflist = []
|
||||
ps = ["%s,%s" % (public.GetMsg("WORKER_PROCESSES"),public.GetMsg("WORKER_PROCESSES_AUTO")),
|
||||
public.GetMsg("WORKER_CONNECTIONS"),
|
||||
public.GetMsg("CONNECT_TIMEOUT_TIME"),
|
||||
public.GetMsg("NGINX_ZIP"),
|
||||
public.GetMsg("NGINX_ZIP_MIN"),
|
||||
public.GetMsg("ZIP_COMP_LEVEL"),
|
||||
public.GetMsg("UPLOAD_MAX_FILE"),
|
||||
public.GetMsg("SERVER_NAME_HASH"),
|
||||
public.GetMsg("CLIENT_HEADER_BUFF")]
|
||||
ps = ["%s,%s" % (public.get_msg_gettext('Worker processes'),public.get_msg_gettext('Auto means automatic')),
|
||||
public.get_msg_gettext('Worker connections'),
|
||||
public.get_msg_gettext('Connection timeout'),
|
||||
public.get_msg_gettext('Whether to enable compressed transmission'),
|
||||
public.get_msg_gettext('Minimum file to compress'),
|
||||
public.get_msg_gettext('Compression level'),
|
||||
public.get_msg_gettext('Maximum file to upload'),
|
||||
public.get_msg_gettext('Hash table size of server name'),
|
||||
public.get_msg_gettext('Client header buffer size')]
|
||||
gets = ["worker_processes","worker_connections","keepalive_timeout","gzip","gzip_min_length","gzip_comp_level","client_max_body_size","server_names_hash_bucket_size","client_header_buffer_size"]
|
||||
n = 0
|
||||
for i in gets:
|
||||
rep = "(%s)\s+(\w+)" % i
|
||||
k = re.search(rep, ngconfcontent)
|
||||
if not k:
|
||||
return public.returnMsg(False,"Get key {} False".format(k))
|
||||
return public.return_msg_gettext(False,"Get key {} False".format(k))
|
||||
k = k.group(1)
|
||||
v = re.search(rep, ngconfcontent)
|
||||
if not v:
|
||||
return public.returnMsg(False,"Get value {} False".format(v))
|
||||
return public.return_msg_gettext(False,"Get value {} False".format(v))
|
||||
v = v.group(2)
|
||||
if re.search(unitrep,v):
|
||||
u = str.upper(v[-1])
|
||||
@@ -60,18 +60,18 @@ class nginx:
|
||||
kv = {"name":k,"value":v,"unit":u,"ps":psstr}
|
||||
conflist.append(kv)
|
||||
n += 1
|
||||
ps = [public.GetMsg("CLIENT_BODY_BUFF")]
|
||||
ps = [public.get_msg_gettext('Client body buffer')]
|
||||
gets = ["client_body_buffer_size"]
|
||||
n = 0
|
||||
for i in gets:
|
||||
rep = "(%s)\s+(\w+)" % i
|
||||
k = re.search(rep, proxycontent)
|
||||
if not k:
|
||||
return public.returnMsg(False,"Get key {} False".format(k))
|
||||
return public.return_msg_gettext(False,"Get key {} False".format(k))
|
||||
k=k.group(1)
|
||||
v = re.search(rep, proxycontent)
|
||||
if not v:
|
||||
return public.returnMsg(False,"Get value {} False".format(v))
|
||||
return public.return_msg_gettext(False,"Get value {} False".format(v))
|
||||
v = v.group(2)
|
||||
if re.search(unitrep, v):
|
||||
u = str.upper(v[-1])
|
||||
@@ -86,7 +86,6 @@ class nginx:
|
||||
kv = {"name":k, "value":v, "unit":u,"ps":psstr}
|
||||
conflist.append(kv)
|
||||
n+=1
|
||||
print(conflist)
|
||||
return conflist
|
||||
|
||||
def SetNginxValue(self,get):
|
||||
@@ -109,10 +108,10 @@ class nginx:
|
||||
rep = "%s\s+[^kKmMgG\;\n]+" % c["name"]
|
||||
if c["name"] == "worker_processes" or c["name"] == "gzip":
|
||||
if not re.search("auto|on|off|\d+", c["value"]):
|
||||
return public.returnMsg(False, 'INIT_ARGS_ERR')
|
||||
return public.return_msg_gettext(False, 'Parameter ERROR!')
|
||||
else:
|
||||
if not re.search("\d+", c["value"]):
|
||||
return public.returnMsg(False, 'INIT_ARGS_ERR')
|
||||
return public.return_msg_gettext(False, 'Parameter ERROR!')
|
||||
if re.search(rep,ngconfcontent):
|
||||
newconf = "%s %s" % (c["name"],c["value"])
|
||||
ngconfcontent = re.sub(rep,newconf,ngconfcontent)
|
||||
@@ -125,10 +124,10 @@ class nginx:
|
||||
if (isError != True):
|
||||
shutil.copyfile('/tmp/ng_file_bk.conf', self.nginxconf)
|
||||
shutil.copyfile('/tmp/proxyfile_bk.conf', self.proxyfile)
|
||||
return public.returnMsg(False, 'ERROR: <br><a style="color:red;">' + isError.replace("\n",
|
||||
return public.return_msg_gettext(False, 'ERROR: <br><a style="color:red;">' + isError.replace("\n",
|
||||
'<br>') + '</a>')
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
def add_nginx_access_log_format(self,args):
|
||||
'''
|
||||
@@ -151,14 +150,14 @@ class nginx:
|
||||
self.del_nginx_access_log_format(args)
|
||||
conf = public.readFile(self.nginxconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False,'NGINX_CONF_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False,'Nginx configuration file does not exist!')
|
||||
reg = 'http(\n|\s)+{'
|
||||
conf = re.sub(reg,'http\n\t{'+data,conf)
|
||||
public.writeFile(self.nginxconf,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
except:
|
||||
return public.returnMsg(False, str(public.get_error_info()))
|
||||
return public.return_msg_gettext(False, str(public.get_error_info()))
|
||||
|
||||
def del_nginx_access_log_format(self,args):
|
||||
'''
|
||||
@@ -169,13 +168,13 @@ class nginx:
|
||||
log_format_name = args.log_format_name
|
||||
conf = public.readFile(self.nginxconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'NGINX_CONF_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Nginx configuration file does not exist!')
|
||||
reg = '\s*#LOG_FORMAT_BEGIN_{n}(\n|.)+#LOG_FORMAT_END_{n}\n?'.format(n=args.log_format_name)
|
||||
conf = re.sub(reg,'',conf)
|
||||
self._del_format_log_of_website(log_format_name)
|
||||
public.writeFile(self.nginxconf,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
def del_all_log_format(self,args):
|
||||
all_format = self.get_nginx_access_log_format(args)
|
||||
@@ -223,7 +222,7 @@ class nginx:
|
||||
reg = "#LOG_FORMAT_BEGIN.*"
|
||||
conf = public.readFile(self.nginxconf)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'NGINX_CONF_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Nginx configuration file does not exist!')
|
||||
data = re.findall(reg,conf)
|
||||
format_name = [i.split('LOG_FORMAT_BEGIN_')[-1] for i in data]
|
||||
format_log = {}
|
||||
@@ -236,7 +235,7 @@ class nginx:
|
||||
format_log[i] = self._process_log_format(tmp)
|
||||
return format_log
|
||||
except:
|
||||
return public.returnMsg(False,public.get_error_info())
|
||||
return public.return_msg_gettext(False,public.get_error_info())
|
||||
|
||||
def set_format_log_to_website(self,args):
|
||||
'''
|
||||
@@ -254,7 +253,7 @@ class nginx:
|
||||
website_conf_file = '/www/server/panel/vhost/nginx/{}.conf'.format(site['name'])
|
||||
conf = public.readFile(website_conf_file)
|
||||
if not conf:
|
||||
return public.returnMsg(False, 'NGINX_CONF_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Nginx configuration file does not exist!')
|
||||
format_exist_reg = '(access_log\s+/www.*\.log).*;'
|
||||
access_log = self.get_nginx_access_log(conf)
|
||||
if not access_log:
|
||||
@@ -267,9 +266,9 @@ class nginx:
|
||||
continue
|
||||
conf = re.sub(format_exist_reg,access_log,conf)
|
||||
public.writeFile(website_conf_file,conf)
|
||||
return public.returnMsg(True, 'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
except:
|
||||
return public.returnMsg(False, str(public.get_error_info()))
|
||||
return public.return_msg_gettext(False, str(public.get_error_info()))
|
||||
|
||||
def get_nginx_access_log(self,nginx_conf):
|
||||
try:
|
||||
|
||||
+5
-5
@@ -51,7 +51,7 @@ class ols:
|
||||
conf = conf + '\n{} {}'.format(k,data[k])
|
||||
public.writeFile(self._main_conf_path,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,"Setup Successfully")
|
||||
return public.return_msg_gettext(True,"Setup Successfully!")
|
||||
|
||||
# 获取站点静态文件缓存配置
|
||||
def get_static_cache(self,get):
|
||||
@@ -101,7 +101,7 @@ class ols:
|
||||
conf = conf.replace(old_cache,new_cache)
|
||||
public.writeFile(self._detail_conf_path.format(sitename),conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'Setup Successfully')
|
||||
return public.return_msg_gettext(True,'Setup Successfully!')
|
||||
except Exception as e:
|
||||
return e
|
||||
|
||||
@@ -180,14 +180,14 @@ RewriteRule (.*\.php)?$ - [E=Cache-Control:private]
|
||||
f.write(conf)
|
||||
f.close()
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'Open successfully')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
else:
|
||||
bt_conf_rep = '#.*BTLSCACHE_BEGIN(.|\n)+BTLSCACHE_END#*\n'
|
||||
conf = re.sub(bt_conf_rep,'',conf)
|
||||
print(conf)
|
||||
public.writeFile(file,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'Close successfully')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
def set_private_cache(self,get):
|
||||
"""
|
||||
@@ -215,7 +215,7 @@ RewriteRule (.*\.php)?$ - [E=Cache-Control:private]
|
||||
conf = re.sub(bt_conf_rep,bt_conf,conf)
|
||||
public.writeFile(file_name,conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'Setup Successfully')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
def _get_site_domain(self):
|
||||
site = []
|
||||
|
||||
+43
-43
@@ -12,14 +12,14 @@ class Page():
|
||||
#--------------------------
|
||||
# 分页类 - JS回调版
|
||||
#--------------------------
|
||||
__PREV = public.GetMsg("PAGE")["PREV"]
|
||||
__NEXT = public.GetMsg("PAGE")["NEXT"]
|
||||
__START = public.GetMsg("PAGE")["START"]
|
||||
__END = public.GetMsg("PAGE")["END"]
|
||||
__COUNT_START = public.GetMsg("PAGE")["COUNT_START"]
|
||||
__COUNT_END = public.GetMsg("PAGE")["COUNT_END"]
|
||||
__FO = public.GetMsg("PAGE")["FO"]
|
||||
__LINE = public.GetMsg("PAGE")["LINE"]
|
||||
__PREV = public.get_msg_gettext('Prev')
|
||||
__NEXT = public.get_msg_gettext('Next')
|
||||
__START = public.get_msg_gettext('Start')
|
||||
__END = public.get_msg_gettext('Last')
|
||||
__COUNT_START = public.get_msg_gettext('Total')
|
||||
__COUNT_END = ''
|
||||
__FO = public.get_msg_gettext('From')
|
||||
__LINE = ''
|
||||
__LIST_NUM = 4
|
||||
SHIFT = None #偏移量
|
||||
ROW = None #每页行数
|
||||
@@ -30,18 +30,19 @@ class Page():
|
||||
__RTURN_JS = False #是否返回JS回调
|
||||
__START_NUM = None #起始行
|
||||
__END_NUM = None #结束行
|
||||
|
||||
|
||||
def __init__(self):
|
||||
tmp = public.GetMsg('PAGE');
|
||||
if tmp:
|
||||
self.__PREV = tmp['PREV'];
|
||||
self.__NEXT = tmp['NEXT'];
|
||||
self.__START = tmp['START'];
|
||||
self.__END = tmp['END'];
|
||||
self.__COUNT_START = tmp['COUNT_START'];
|
||||
self.__COUNT_END = tmp['COUNT_END'];
|
||||
self.__FO = tmp['FO'];
|
||||
self.__LINE = tmp['LINE'];
|
||||
pass
|
||||
# tmp = public.get_msg_gettext('Depends on the following software, please install [{1}] first')
|
||||
# if tmp:
|
||||
# self.__PREV = tmp['Prev']
|
||||
# self.__NEXT = tmp['Next']
|
||||
# self.__START = tmp['Start']
|
||||
# self.__END = tmp['Last']
|
||||
# self.__COUNT_START = tmp['Total']
|
||||
# self.__COUNT_END = tmp['']
|
||||
# self.__FO = tmp['From']
|
||||
# self.__LINE = tmp['']
|
||||
|
||||
def GetPage(self,pageInfo,limit = '1,2,3,4,5,6,7,8'):
|
||||
# 取分页信息
|
||||
@@ -56,9 +57,9 @@ class Page():
|
||||
self.__COUNT_PAGE = self.__GetCountPage()
|
||||
self.__URI = self.__SetUri(pageInfo['uri'])
|
||||
self.SHIFT = self.__START_NUM - 1
|
||||
|
||||
|
||||
keys = limit.split(',')
|
||||
|
||||
|
||||
pages = {}
|
||||
#起始页
|
||||
pages['1'] = self.__GetStart()
|
||||
@@ -70,23 +71,22 @@ class Page():
|
||||
pages['4'] = self.__GetNext()
|
||||
#尾页
|
||||
pages['5'] = self.__GetEnd()
|
||||
|
||||
|
||||
#当前显示页与总页数
|
||||
pages['6'] = "<span class='Pnumber'>" + str(self.__C_PAGE) + "/" + str(self.__COUNT_PAGE) + "</span>"
|
||||
#本页显示开始与结束行
|
||||
pages['7'] = "<span class='Pline'>" + self.__FO + str(self.__START_NUM) + "-" + str(self.__END_NUM) + self.__LINE + "</span>"
|
||||
#行数
|
||||
pages['8'] = "<span class='Pcount'>" + self.__COUNT_START + str(self.__COUNT_ROW) + self.__COUNT_END + "</span>"
|
||||
|
||||
pages['8'] = "<span class='Pcount'>" + self.__COUNT_START +' '+ str(self.__COUNT_ROW) + self.__COUNT_END + "</span>"
|
||||
#构造返回数据
|
||||
retuls = '<div>';
|
||||
for value in keys:
|
||||
retuls += pages[value]
|
||||
retuls +='</div>';
|
||||
|
||||
|
||||
#返回分页数据
|
||||
return retuls;
|
||||
|
||||
|
||||
def __GetEnd(self):
|
||||
#构造尾页
|
||||
endStr = ""
|
||||
@@ -98,7 +98,7 @@ class Page():
|
||||
else:
|
||||
endStr = "<a class='Pend' onclick='" + self.__RTURN_JS + "(" + str(self.__COUNT_PAGE) + ")'>" + self.__END + "</a>"
|
||||
return endStr
|
||||
|
||||
|
||||
def __GetNext(self):
|
||||
#构造下一页
|
||||
nextStr = ""
|
||||
@@ -107,11 +107,11 @@ class Page():
|
||||
else:
|
||||
if self.__RTURN_JS == "":
|
||||
nextStr = "<a class='Pnext' href='" + self.__URI + "p=" + str(self.__C_PAGE + 1) + "'>" + self.__NEXT + "</a>"
|
||||
else:
|
||||
else:
|
||||
nextStr = "<a class='Pnext' onclick='" + self.__RTURN_JS + "(" + str(self.__C_PAGE + 1) + ")'>" + self.__NEXT + "</a>"
|
||||
|
||||
|
||||
return nextStr
|
||||
|
||||
|
||||
def __GetPages(self):
|
||||
#构造分页
|
||||
pages = ''
|
||||
@@ -130,11 +130,11 @@ class Page():
|
||||
pages += "<a class='Pnum' href='" + self.__URI + "p=" + str(page) + "'>" + str(page) + "</a>"
|
||||
else:
|
||||
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + "(" + str(page) + ")'>" + str(page) + "</a>"
|
||||
|
||||
|
||||
#当前页
|
||||
if self.__C_PAGE > 0:
|
||||
pages += "<span class='Pcurrent'>" + str(self.__C_PAGE) + "</span>"
|
||||
|
||||
|
||||
#当前页之后
|
||||
if self.__C_PAGE <= self.__LIST_NUM:
|
||||
num = self.__LIST_NUM + (self.__LIST_NUM - self.__C_PAGE) + 1
|
||||
@@ -148,11 +148,11 @@ class Page():
|
||||
break;
|
||||
if self.__RTURN_JS == "":
|
||||
pages += "<a class='Pnum' href='" + self.__URI + "p=" + str(page) + "'>" + str(page) + "</a>"
|
||||
else:
|
||||
else:
|
||||
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + "(" + str(page) + ")'>" + str(page) + "</a>"
|
||||
|
||||
|
||||
return pages;
|
||||
|
||||
|
||||
def __GetPrev(self):
|
||||
#构造上一页
|
||||
startStr = ''
|
||||
@@ -161,10 +161,10 @@ class Page():
|
||||
else:
|
||||
if self.__RTURN_JS == "":
|
||||
startStr = "<a class='Ppren' href='" + self.__URI + "p=" + str(self.__C_PAGE - 1) + "'>" + self.__PREV + "</a>"
|
||||
else:
|
||||
else:
|
||||
startStr = "<a class='Ppren' onclick='" + self.__RTURN_JS + "(" + str(self.__C_PAGE - 1) + ")'>" + self.__PREV + "</a>"
|
||||
return startStr
|
||||
|
||||
|
||||
def __GetStart(self):
|
||||
#构造起始分页
|
||||
startStr = ''
|
||||
@@ -176,27 +176,27 @@ class Page():
|
||||
else:
|
||||
startStr = "<a class='Pstart' onclick='" + self.__RTURN_JS + "(1)'>" + self.__START + "</a>"
|
||||
return startStr;
|
||||
|
||||
|
||||
def __GetCpage(self,p):
|
||||
#取当前页
|
||||
if p:
|
||||
return p
|
||||
return 1
|
||||
|
||||
|
||||
def __StartRow(self):
|
||||
#从多少行开始
|
||||
return (self.__C_PAGE - 1) * self.ROW + 1
|
||||
|
||||
|
||||
def __EndRow(self):
|
||||
#从多少行结束
|
||||
if self.ROW > self.__COUNT_ROW:
|
||||
return self.__COUNT_ROW
|
||||
return self.__C_PAGE * self.ROW
|
||||
|
||||
|
||||
def __GetCountPage(self):
|
||||
#取总页数
|
||||
return int(math.ceil(self.__COUNT_ROW / float(self.ROW)))
|
||||
|
||||
|
||||
def __SetUri(self,request_uri):
|
||||
#构造URI
|
||||
try:
|
||||
@@ -207,4 +207,4 @@ class Page():
|
||||
else:
|
||||
if request_uri[-1] != '&': request_uri += '&'
|
||||
return request_uri
|
||||
except: return '';
|
||||
except: return ''
|
||||
|
||||
+34
-20
@@ -33,13 +33,27 @@ class panelApi:
|
||||
|
||||
def login_for_app(self,get):
|
||||
from BTPanel import cache
|
||||
import uuid
|
||||
tid = get.tid
|
||||
if(len(tid) != 12): return public.returnMsg(False,'Invalid login key')
|
||||
if(len(tid) != 32): return public.return_msg_gettext(False,'Invalid login key1')
|
||||
session_id = cache.get(tid)
|
||||
if not session_id: return public.returnMsg(False,'The specified key does not exist or has expired')
|
||||
if(len(session_id) != 64): return public.returnMsg(False,'Invalid login key')
|
||||
cache.set(session_id,'True',120)
|
||||
return public.returnMsg(True,'Scan code successfully, log in!')
|
||||
if not session_id: return public.return_msg_gettext(False,'The specified key does not exist or has expired1')
|
||||
if(len(session_id) != 64): return public.return_msg_gettext(False,'Invalid login key2')
|
||||
try:
|
||||
if not os.path.exists('/www/server/panel/data/app_login_check.pl'):return public.returnMsg(False,'Invalid login key3')
|
||||
key, init_time, tid2, status = public.readFile('/www/server/panel/data/app_login_check.pl').split(':')
|
||||
if session_id!=key:return public.returnMsg(False,'Invalid login key4')
|
||||
if tid != tid2: return public.returnMsg(False, 'The specified key does not exist or has expired5')
|
||||
if time.time() - float(init_time) > 60:
|
||||
return public.returnMsg(False, 'QR code validity time expired6')
|
||||
cache.set(session_id,public.md5(uuid.UUID(int=uuid.getnode()).hex),120)
|
||||
import uuid
|
||||
data = key + ':' + init_time + ':' + tid2 + ':' + uuid.UUID(int=uuid.getnode()).hex[-12:]
|
||||
public.writeFile("/www/server/panel/data/app_login_check.pl", data)
|
||||
return public.return_msg_gettext(True,'Scan code successfully, log in!')
|
||||
except:
|
||||
os.remove("/www/server/panel/data/app_login_check.pl")
|
||||
return public.return_msg_gettext(False, 'Invalid login key')
|
||||
|
||||
def get_api_config(self):
|
||||
tmp = public.ReadFile(self.save_path)
|
||||
@@ -81,11 +95,11 @@ class panelApi:
|
||||
|
||||
bind = self.get_bind_token(args.bind_token)
|
||||
if bind['token'] != args.bind_token:
|
||||
return 'The current QR code has expired, please refresh the page and rescan the code!'
|
||||
return public.get_msg_gettext('The current QR code has expired, please refresh the page and rescan the code!')
|
||||
|
||||
apps = self.get_apps()
|
||||
if len(apps) >= self.max_bind:
|
||||
return 'This server is bound to a maximum of {} devices, which has reached the limit!'.format(self.max_bind)
|
||||
return public.get_msg_gettext('This server is bound to a maximum of {} devices, which has reached the limit!',(self.max_bind,))
|
||||
|
||||
bind['status'] = 1
|
||||
bind['brand'] = args.client_brand
|
||||
@@ -94,8 +108,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)
|
||||
if not public.cache_get(public.Md5(os.uname().version)):
|
||||
public.cache_set(public.Md5(os.uname().version),1,60)
|
||||
bind = self.get_bind_token(args.bind_token)
|
||||
return bind
|
||||
|
||||
@@ -133,10 +147,10 @@ class panelApi:
|
||||
def add_bind_app(self,args):
|
||||
bind = self.get_bind_token(args.bind_token)
|
||||
if bind['status'] == 0:
|
||||
return public.returnMsg(False,'Failed verification!')
|
||||
return public.return_msg_gettext(False,'Failed verification!')
|
||||
apps = self.get_apps()
|
||||
if len(apps) >= self.max_bind:
|
||||
return public.returnMsg(False,'A server allows up to {} device bindings!'.format(self.max_bind))
|
||||
return public.return_msg_gettext(False,'A server allows up to {} device bindings!'.format(self.max_bind))
|
||||
|
||||
args.bind_app = args.bind_token
|
||||
self.remove_bind_app(args)
|
||||
@@ -144,7 +158,7 @@ class panelApi:
|
||||
data['apps'].append(bind)
|
||||
self.save_api_config(data)
|
||||
self.remove_bind_token(args.bind_token)
|
||||
return public.returnMsg(True,'Bind successfully!')
|
||||
return public.return_msg_gettext(True,'Bind successfully!')
|
||||
|
||||
def remove_bind_token(self,bind_token):
|
||||
data = self.get_api_config()
|
||||
@@ -168,7 +182,7 @@ class panelApi:
|
||||
s_file = '/dev/shm/{}'.format(args.bind_app)
|
||||
if os.path.exists(s_file):
|
||||
os.remove(s_file)
|
||||
return public.returnMsg(True,'successfully deleted!')
|
||||
return public.return_msg_gettext(True,'Successfully deleted!')
|
||||
|
||||
def get_bind_token(self,token = None):
|
||||
data = self.get_api_config()
|
||||
@@ -203,13 +217,13 @@ class panelApi:
|
||||
|
||||
|
||||
def set_token(self,get):
|
||||
if 'request_token' in get: return public.returnMsg(False,'Cannot configure API through API interface')
|
||||
if 'request_token' in get: return public.return_msg_gettext(False,'Cannot configure API through API interface')
|
||||
data = self.get_api_config()
|
||||
if get.t_type == '1':
|
||||
token = public.GetRandomString(32)
|
||||
data['token'] = public.md5(token)
|
||||
data['token_crypt'] = public.en_crypt(data['token'],token).decode('utf-8')
|
||||
public.WriteLog('SET_API','Regenerate API-Token')
|
||||
public.write_log_gettext('API configuration','Regenerate API-Token')
|
||||
elif get.t_type == '2':
|
||||
data['open'] = not data['open']
|
||||
stats = {True:'Open',False:'Close'}
|
||||
@@ -217,19 +231,19 @@ class panelApi:
|
||||
token = public.GetRandomString(32)
|
||||
data['token'] = public.md5(token)
|
||||
data['token_crypt'] = public.en_crypt(data['token'],token).decode('utf-8')
|
||||
public.WriteLog('SET_API','%s API interface' % stats[data['open']])
|
||||
public.write_log_gettext('API configuration','{} API interface',(stats[data['open']],))
|
||||
token = stats[data['open']] + ' success!'
|
||||
elif get.t_type == '3':
|
||||
data['limit_addr'] = get.limit_addr.split('\n')
|
||||
public.WriteLog('SET_API','Change IP limit to [%s]' % get.limit_addr)
|
||||
public.write_log_gettext('API configuration','Change IP limit to [{}]',(get.limit_addr,))
|
||||
token ='Saved successfully!'
|
||||
self.save_api_config(data)
|
||||
return public.returnMsg(True,token)
|
||||
return public.return_msg_gettext(True,token)
|
||||
|
||||
def get_tmp_token(self,get):
|
||||
if not 'request_token' in get: return public.returnMsg(False,'Temporary keys can only be obtained through the API interface')
|
||||
if not 'request_token' in get: return public.return_msg_gettext(False,'Temporary keys can only be obtained through the API interface')
|
||||
data = self.get_api_config()
|
||||
data['tmp_token'] = public.GetRandomString(64)
|
||||
data['tmp_time'] = time.time()
|
||||
self.save_api_config(data)
|
||||
return public.returnMsg(True,data['tmp_token'])
|
||||
return public.return_msg_gettext(True,data['tmp_token'])
|
||||
+30
-21
@@ -23,12 +23,12 @@ class panelAuth:
|
||||
def create_serverid(self,get):
|
||||
try:
|
||||
userPath = 'data/userInfo.json'
|
||||
if not os.path.exists(userPath): return public.returnMsg(False,'LOGIN_FIRST')
|
||||
if not os.path.exists(userPath): return public.return_msg_gettext(False,'Please login with account first')
|
||||
tmp = public.readFile(userPath)
|
||||
if len(tmp) < 2: tmp = '{}'
|
||||
data = json.loads(tmp)
|
||||
data['uid'] = data['id']
|
||||
if not data: return public.returnMsg(False,'LOGIN_FIRST')
|
||||
if not data: return public.return_msg_gettext(False,'Please login with account first')
|
||||
if not 'server_id' in data:
|
||||
s1 = public.get_mac_address() + public.get_hostname()
|
||||
s2 = self.get_cpuname()
|
||||
@@ -36,7 +36,7 @@ class panelAuth:
|
||||
data['server_id'] = serverid
|
||||
public.writeFile(userPath,json.dumps(data))
|
||||
return data
|
||||
except: return public.returnMsg(False,'LOGIN_FIRST')
|
||||
except: return public.return_msg_gettext(False,'Please login with account first')
|
||||
|
||||
|
||||
def create_plugin_other_order(self,get):
|
||||
@@ -63,22 +63,24 @@ class panelAuth:
|
||||
def get_plugin_price(self, get):
|
||||
try:
|
||||
userPath = 'data/userInfo.json'
|
||||
if not 'pluginName' in get and not 'product_id' in get: return public.returnMsg(False,'INIT_ARGS_ERR')
|
||||
if not os.path.exists(userPath): return public.returnMsg(False,'LOGIN_FIRST')
|
||||
if not 'pluginName' in get and not 'product_id' in get: return public.return_msg_gettext(False,'Parameter ERROR!')
|
||||
if not os.path.exists(userPath): return public.return_msg_gettext(False,'Please login with account first')
|
||||
params = {}
|
||||
if not hasattr(get,'product_id'):
|
||||
params['product_id'] = self.get_plugin_info(get.pluginName)['id']
|
||||
else:
|
||||
params['product_id'] = get.product_id
|
||||
data = self.send_cloud('{}/api/product/prices'.format(self.__official_url), params)
|
||||
if not data:
|
||||
return public.return_msg_gettext(False, 'Please log in to your aaPanel account on the panel first!')
|
||||
if not data['success']:
|
||||
return public.returnMsg(False,data['msg'])
|
||||
return public.return_msg_gettext(False,data['msg'])
|
||||
# if len(data['res']) == 6:
|
||||
# return data['res'][3:]
|
||||
return data['res']
|
||||
except:
|
||||
del(session['get_product_list'])
|
||||
return public.returnMsg(False,'Syncing information, please try again!\n' + public.get_error_info())
|
||||
return public.return_msg_gettext(False,'Syncing information, please try again!\n {}',(public.get_error_info(),))
|
||||
|
||||
def get_plugin_info(self,pluginName):
|
||||
data = self.get_business_plugin(None)
|
||||
@@ -104,6 +106,7 @@ class panelAuth:
|
||||
params['cycle_unit'] = get.cycle_unit
|
||||
params['product_id'] = get.pid
|
||||
params['src'] = 2
|
||||
params['trigger_entry'] = get.source
|
||||
params['pay_channel'] = 2
|
||||
params['charge_type'] = get.charge_type
|
||||
env_info = public.fetch_env_info()
|
||||
@@ -111,7 +114,7 @@ class panelAuth:
|
||||
params['server_id'] = env_info['install_code']
|
||||
data = self.send_cloud('{}/api/order/product/create'.format(self.__official_url), params)
|
||||
if not data['success']:
|
||||
return public.returnMsg(False,data['res'])
|
||||
return public.return_msg_gettext(False,data['res'])
|
||||
return data['res']
|
||||
|
||||
def get_stripe_session_id(self,get):
|
||||
@@ -125,7 +128,7 @@ class panelAuth:
|
||||
params = {}
|
||||
params['id'] = get.id
|
||||
data = self.send_cloud('check_product_pays', params)
|
||||
if not data: return public.returnMsg(False,'AJAX_CONN_ERR')
|
||||
if not data: return public.return_msg_gettext(False,'Fail to connect to the server!')
|
||||
if data['status'] == True:
|
||||
self.flush_pay_status(get)
|
||||
if 'get_product_bay' in session: del(session['get_product_bay'])
|
||||
@@ -134,8 +137,8 @@ class panelAuth:
|
||||
def flush_pay_status(self,get):
|
||||
if 'get_product_bay' in session: del(session['get_product_bay'])
|
||||
data = self.get_plugin_list(get)
|
||||
if not data: return public.returnMsg(False,'AJAX_CONN_ERR')
|
||||
return public.returnMsg(True,'FLUSH_STATUS_SUCCESS')
|
||||
if not data: return public.return_msg_gettext(False,'Fail to connect to the server!')
|
||||
return public.return_msg_gettext(True,'Flush status success')
|
||||
|
||||
def get_renew_code(self):
|
||||
pass
|
||||
@@ -163,7 +166,7 @@ class panelAuth:
|
||||
params = {}
|
||||
params['pid'] = getattr(get,'pid',0)
|
||||
data = self.send_cloud('get_re_order_status', params)
|
||||
if not data: return public.returnMsg(False,'AJAX_CONN_ERR')
|
||||
if not data: return public.return_msg_gettext(False,'Fail to connect to the server!')
|
||||
if data['status'] == True:
|
||||
self.flush_pay_status(get)
|
||||
if 'get_product_bay' in session: del(session['get_product_bay'])
|
||||
@@ -192,8 +195,8 @@ class panelAuth:
|
||||
data = self.send_cloud('{}/api/order/product/create'.format(self.__official_url), params)
|
||||
session['focre_cloud'] = True
|
||||
if data['success']:
|
||||
return public.returnMsg(True,'Activate successfully')
|
||||
return public.returnMsg(False, 'Activate failed')
|
||||
return public.return_msg_gettext(True,'Activate successfully')
|
||||
return public.return_msg_gettext(False, 'Activate failed')
|
||||
|
||||
def send_cloud(self,cloudURL,params):
|
||||
try:
|
||||
@@ -293,16 +296,21 @@ class panelAuth:
|
||||
return []
|
||||
if not data['success']: return []
|
||||
data = data['res']
|
||||
return [i for i in data['list'] if i['status'] != 'activated']
|
||||
# return [i for i in data['list'] if i['status'] != 'activated' and get.pid == i['product_id']]
|
||||
res = list()
|
||||
for i in data['list']:
|
||||
if i['status'] != 'activated' and str(get.pid) == str(i['product_id']):
|
||||
res.append(i)
|
||||
return res
|
||||
|
||||
def auth_activate(self,get):
|
||||
params = {}
|
||||
params['serial_no'] = get.serial_no
|
||||
params['environment_info'] = json.dumps(public.fetch_env_info())
|
||||
data = self.send_cloud('{}/api/authorize/product/activate'.format(self.__official_url), params)
|
||||
if not data['success']: return public.returnMsg(False,'Activate Failed')
|
||||
if not data['success']: return public.return_msg_gettext(False,'Activate Failed')
|
||||
session['focre_cloud'] = True
|
||||
return public.returnMsg(True,'Activate successfully')
|
||||
return public.return_msg_gettext(True,'Activate successfully')
|
||||
|
||||
def renew_product_auth(self,get):
|
||||
params = {}
|
||||
@@ -311,6 +319,7 @@ class panelAuth:
|
||||
params['cycle'] = get.cycle
|
||||
params['cycle_unit'] = get.cycle_unit
|
||||
params['src'] = 2
|
||||
params['trigger_entry'] = get.source
|
||||
params['environment_info'] = json.dumps(public.fetch_env_info())
|
||||
if hasattr(get,'coupon_id') and get.pay_channel == '10':
|
||||
params['coupon_id'] = get.coupon_id
|
||||
@@ -319,8 +328,8 @@ class panelAuth:
|
||||
# 使用抵扣券续费直接返回续费结果
|
||||
if get.pay_channel == '10':
|
||||
if not data['success']:
|
||||
return public.returnMsg(False, 'Renew Failed')
|
||||
return public.returnMsg(True,'Renew successfully')
|
||||
return public.return_msg_gettext(False, 'Renew Failed')
|
||||
return public.return_msg_gettext(True,'Renew successfully')
|
||||
# 使用支付续费返回stripe的请求数据
|
||||
return data['res']
|
||||
|
||||
@@ -335,5 +344,5 @@ class panelAuth:
|
||||
session['focre_cloud'] = True
|
||||
# 使用抵扣券续费直接返回续费结果
|
||||
if not data['success']:
|
||||
return public.returnMsg(False, 'Apply Failed')
|
||||
return public.returnMsg(True,'Apply successfully')
|
||||
return public.return_msg_gettext(False, 'Apply Failed')
|
||||
return public.return_msg_gettext(True,'Apply successfully')
|
||||
|
||||
+117
-82
@@ -56,12 +56,12 @@ class backup:
|
||||
|
||||
def echo_start(self):
|
||||
print("="*90)
|
||||
print("|-"+public.getMsg('START_BACKUP')+"[{}]".format(public.format_date()))
|
||||
print("|-"+public.get_msg_gettext('Start backup')+"[{}]".format(public.format_date()))
|
||||
print("="*90)
|
||||
|
||||
def echo_end(self):
|
||||
print("="*90)
|
||||
print("|-"+public.getMsg('BACKUP_COMPLETED')+"[{}]".format(public.format_date()))
|
||||
print("|-"+public.get_msg_gettext('Backup completed')+"[{}]".format(public.format_date()))
|
||||
print("="*90)
|
||||
print("\n")
|
||||
|
||||
@@ -98,8 +98,8 @@ class backup:
|
||||
|
||||
def GetDiskInfo2(self):
|
||||
#取磁盘分区信息
|
||||
temp = public.ExecShell("df -T -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
|
||||
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
|
||||
temp = public.ExecShell("df -T -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev|grep -v overlay")[0]
|
||||
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev|grep -v overlay")[0]
|
||||
temp1 = temp.split('\n')
|
||||
tempInodes1 = tempInodes.split('\n')
|
||||
diskInfo = []
|
||||
@@ -154,9 +154,9 @@ class backup:
|
||||
error_msg = ""
|
||||
self.echo_start()
|
||||
if not os.path.exists(spath):
|
||||
error_msg= public.getMsg('BACKUP_DIR_NOT_EXIST',(spath,))
|
||||
error_msg= public.get_msg_gettext('The specified directory {} does not exist!',(spath,))
|
||||
self.echo_error(error_msg)
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=spath)
|
||||
return False
|
||||
|
||||
if spath[-1] == '/':
|
||||
@@ -170,25 +170,25 @@ class backup:
|
||||
if not self.backup_path_to(spath,dfile,exclude):
|
||||
if self._error_msg:
|
||||
error_msg = self._error_msg
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=spath)
|
||||
return False
|
||||
|
||||
if self._cloud:
|
||||
self.echo_info(public.getMsg("BACKUP_UPLOADING",(self._cloud._title,)))
|
||||
self.echo_info(public.get_msg_gettext('Uploading to {}, please wait ...',(self._cloud._title,)))
|
||||
if self._cloud.upload_file(dfile,'path'):
|
||||
self.echo_info(public.getMsg("BACKUP_UPLOAD_SUCCESS",(self._cloud._title,)))
|
||||
self.echo_info(public.get_msg_gettext('Successfully uploaded to {}',(self._cloud._title,)))
|
||||
else:
|
||||
if hasattr(self._cloud, "error_msg"):
|
||||
if self._cloud.error_msg:
|
||||
error_msg = self._cloud.error_msg
|
||||
if not error_msg:
|
||||
error_msg = public.getMsg('BACKUP_UPLOAD_FAILED')
|
||||
error_msg = public.get_msg_gettext('File upload failed, skip this backup!')
|
||||
self.echo_error(error_msg)
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
|
||||
remark = "Backup to " + self._cloud._title
|
||||
self.send_failture_notification(error_msg, remark=remark)
|
||||
self.send_failture_notification(error_msg, target=spath, remark=remark)
|
||||
return False
|
||||
|
||||
filename = dfile
|
||||
@@ -228,9 +228,9 @@ class backup:
|
||||
if _not_save_local:
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
self.echo_info(public.getMsg("BACKUP_DEL",(dfile,)))
|
||||
self.echo_info(public.get_msg_gettext('User settings do not retain local backups, deleted {}',(dfile,)))
|
||||
else:
|
||||
self.echo_info(public.getMsg('KEEP_LOCAL'))
|
||||
self.echo_info(public.get_msg_gettext('Local backup has been kept'))
|
||||
|
||||
if not self._cloud:
|
||||
backups = public.M('backup').where("type=? and pid=? and name=? and filename NOT LIKE '%|%'",('2',0,spath)).field('id,name,filename').select()
|
||||
@@ -239,15 +239,16 @@ class backup:
|
||||
|
||||
self.delete_old(backups,save,'path')
|
||||
self.echo_end()
|
||||
self.save_backup_status(True, target=spath)
|
||||
return dfile
|
||||
|
||||
|
||||
#清理过期备份文件
|
||||
def delete_old(self,backups,save,data_type = None):
|
||||
if type(backups) == str:
|
||||
self.echo_info(public.getMsg('BACKUP_CLEAN_ERR',(backups,)))
|
||||
self.echo_info(public.get_msg_gettext('Failed to clean expired backup, error: {}',(backups,)))
|
||||
return
|
||||
self.echo_info(public.getMsg('BACKUP_KEEP',(str(save),)))
|
||||
self.echo_info(public.get_msg_gettext('Keep the latest number of backups: {} copies',(str(save),)))
|
||||
num = len(backups) - int(save)
|
||||
if num > 0:
|
||||
self._get_local_backdir()
|
||||
@@ -264,11 +265,11 @@ class backup:
|
||||
os.remove(backup['filename'])
|
||||
except:
|
||||
pass
|
||||
self.echo_info(public.getMsg("BACKUP_CLEAN",(backup['filename'],)))
|
||||
self.echo_info(public.get_msg_gettext('Expired backup files have been cleaned from disk: {}',(backup['filename'],)))
|
||||
#尝试删除远程文件
|
||||
if self._cloud:
|
||||
self._cloud.delete_file(backup['name'],data_type)
|
||||
self.echo_info(public.getMsg("BACKUP_CLEAN_REMOVE",(self._cloud._title,backup['name'])))
|
||||
self.echo_info(public.get_msg_gettext('Expired backup files have been cleaned from {}: {}',(self._cloud._title,backup['name'])))
|
||||
|
||||
#从数据库清理
|
||||
public.M('backup').where('id=?',(backup['id'],)).delete()
|
||||
@@ -282,7 +283,7 @@ class backup:
|
||||
#压缩目录
|
||||
def backup_path_to(self,spath,dfile,exclude = [],siteName = None):
|
||||
if not os.path.exists(spath):
|
||||
self.echo_error(public.getMsg('BACKUP_DIR_NOT_EXIST',(spath,)))
|
||||
self.echo_error(public.get_msg_gettext('The specified directory {} does not exist!',(spath,)))
|
||||
return False
|
||||
|
||||
if spath[-1] == '/':
|
||||
@@ -301,55 +302,55 @@ class backup:
|
||||
exclude_config = "Not set"
|
||||
|
||||
if siteName:
|
||||
self.echo_info(public.getMsg('BACKUP_SITE',(siteName,)))
|
||||
self.echo_info(public.getMsg('WEBSITE_DIR',(spath,)))
|
||||
self.echo_info(public.get_msg_gettext('Backup site: {}',(siteName,)))
|
||||
self.echo_info(public.get_msg_gettext('Website document root: {}',(spath,)))
|
||||
else:
|
||||
self.echo_info(public.getMsg('BACKUP_DIR',(spath,)))
|
||||
self.echo_info(public.get_msg_gettext('Backup directory: {}',(spath,)))
|
||||
|
||||
self.echo_info(public.getMsg(
|
||||
"DIR_SIZE",
|
||||
self.echo_info(public.get_msg_gettext(
|
||||
'Directory size: {}',
|
||||
(str(public.to_size(p_size),))
|
||||
))
|
||||
self.echo_info(public.getMsg('BACKUP_EXCLUSION',(exclude_config,)))
|
||||
self.echo_info(public.get_msg_gettext('Exclusion setting: {}',(exclude_config,)))
|
||||
disk_path,disk_free,disk_inode = self.get_disk_free(dfile)
|
||||
self.echo_info(public.getMsg(
|
||||
"PARTITION_INFO",
|
||||
self.echo_info(public.get_msg_gettext(
|
||||
'Partition {} available disk space is: {}, available Inode is: {}',
|
||||
(disk_path,str(public.to_size(disk_free)),str(disk_inode))
|
||||
))
|
||||
if disk_path:
|
||||
if disk_free < p_size:
|
||||
self.echo_error(public.getMsg(
|
||||
"PARTITION_LESS_THEN",
|
||||
self.echo_error(public.get_msg_gettext(
|
||||
'The available disk space of the target partition is less than {}, and the backup cannot be completed. Please increase the disk capacity or change the default backup directory on the settings page!',
|
||||
(str(public.to_size(p_size)),)
|
||||
))
|
||||
return False
|
||||
|
||||
if disk_inode < self._inode_min:
|
||||
self.echo_error(public.getMsg(
|
||||
"INODE_LESS_THEN",
|
||||
self.echo_error(public.get_msg_gettext(
|
||||
'The available Inode of the target partition is less than {}, and the backup cannot be completed. Please increase the disk capacity or change the default backup directory on the settings page!',
|
||||
(str(self._inode_min,))
|
||||
))
|
||||
return False
|
||||
|
||||
stime = time.time()
|
||||
self.echo_info(public.getMsg("START_COMPRESS",(public.format_date(times=stime),)))
|
||||
self.echo_info(public.get_msg_gettext('Start compressing files: {}',(public.format_date(times=stime),)))
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
public.ExecShell("cd " + os.path.dirname(spath) + " && tar zcvf '" + dfile + "' " + self._exclude + " '" + dirname + "' 2>{err_log} 1> /dev/null".format(err_log = self._err_log))
|
||||
tar_size = os.path.getsize(dfile)
|
||||
if tar_size < 1:
|
||||
self.echo_error(public.getMsg('ZIP_ERR'))
|
||||
self.echo_error(public.get_msg_gettext('Compression failed!'))
|
||||
self.echo_info(public.readFile(self._err_log))
|
||||
return False
|
||||
compression_time = str('{:.2f}'.format(time.time() - stime))
|
||||
self.echo_info(public.getMsg(
|
||||
'COMPRESS_TIME',
|
||||
self.echo_info(public.get_msg_gettext(
|
||||
'Compression completed, took {} seconds, compressed package size: {}',
|
||||
(compression_time,str(public.to_size(tar_size)))
|
||||
))
|
||||
if siteName:
|
||||
self.echo_info(public.getMsg("WEBSITE_BACKUP_TO",(dfile,)))
|
||||
self.echo_info(public.get_msg_gettext('Site backed up to: {}',(dfile,)))
|
||||
else:
|
||||
self.echo_info(public.getMsg("DIR_BACKUP_TO",(dfile,)))
|
||||
self.echo_info(public.get_msg_gettext('Directory has been backed up to: {}',(dfile,)))
|
||||
if os.path.exists(self._err_log):
|
||||
os.remove(self._err_log)
|
||||
return dfile
|
||||
@@ -366,25 +367,25 @@ class backup:
|
||||
if not self.backup_path_to(spath,dfile,exclude,siteName=siteName):
|
||||
if self._error_msg:
|
||||
error_msg = self._error_msg
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=siteName)
|
||||
return False
|
||||
|
||||
if self._cloud:
|
||||
self.echo_info(public.getMsg("BACKUP_UPLOADING",(self._cloud._title,)))
|
||||
self.echo_info(public.get_msg_gettext('Uploading to {}, please wait ...',(self._cloud._title,)))
|
||||
if self._cloud.upload_file(dfile,'site'):
|
||||
self.echo_info(public.getMsg("BACKUP_UPLOAD_SUCCESS",(self._cloud._title,)))
|
||||
self.echo_info(public.get_msg_gettext('Successfully uploaded to {}',(self._cloud._title,)))
|
||||
else:
|
||||
if hasattr(self._cloud, "error_msg"):
|
||||
if self._cloud.error_msg:
|
||||
error_msg = self._cloud.error_msg
|
||||
if not error_msg:
|
||||
error_msg = public.getMsg('BACKUP_UPLOAD_FAILED')
|
||||
error_msg = public.get_msg_gettext('File upload failed, skip this backup!')
|
||||
self.echo_error(error_msg)
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
|
||||
remark = "Backup to " + self._cloud._title
|
||||
self.send_failture_notification(error_msg, remark=remark)
|
||||
self.send_failture_notification(error_msg, target=siteName, remark=remark)
|
||||
return False
|
||||
|
||||
filename = dfile
|
||||
@@ -424,9 +425,9 @@ class backup:
|
||||
if _not_save_local:
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
self.echo_info(public.getMsg("BACKUP_DEL",(dfile,)))
|
||||
self.echo_info(public.get_msg_gettext('User settings do not retain local backups, deleted {}',(dfile,)))
|
||||
else:
|
||||
self.echo_info(public.getMsg('KEEP_LOCAL'))
|
||||
self.echo_info(public.get_msg_gettext('Local backup has been kept'))
|
||||
|
||||
#清理多余备份
|
||||
if not self._cloud:
|
||||
@@ -450,6 +451,7 @@ class backup:
|
||||
if not result:
|
||||
failture_count += 1
|
||||
results.append((database['name'], result, self._error_msg,))
|
||||
self.save_backup_status(result, target=database['name'], msg=self._error_msg)
|
||||
|
||||
if failture_count > 0:
|
||||
self.send_all_failture_notification("database", results)
|
||||
@@ -467,6 +469,7 @@ class backup:
|
||||
if not result:
|
||||
failture_count += 1
|
||||
results.append((site['name'], result, self._error_msg,))
|
||||
self.save_backup_status(result, target=site['name'], msg=self._error_msg)
|
||||
|
||||
if failture_count > 0:
|
||||
self.send_all_failture_notification("site", results)
|
||||
@@ -519,58 +522,78 @@ class backup:
|
||||
os.makedirs(dpath,384)
|
||||
|
||||
error_msg = ""
|
||||
import panelMysql
|
||||
if not self._db_mysql:self._db_mysql = panelMysql.panelMysql()
|
||||
# ----- 判断是否为远程数据库START @author hwliang<2021-01-08>--------
|
||||
db_find = public.M('databases').where("name=?",(db_name,)).find()
|
||||
conn_config = {}
|
||||
self._db_mysql = public.get_mysql_obj(db_name)
|
||||
is_cloud_db = db_find['db_type'] in ['1',1,'2',2]
|
||||
if is_cloud_db:
|
||||
# 连接远程数据库
|
||||
if db_find['sid']:
|
||||
conn_config = public.M('database_servers').where('id=?',db_find['sid']).find()
|
||||
if not 'db_name' in conn_config: conn_config['db_name'] = None
|
||||
else:
|
||||
conn_config = json.loads(db_find['conn_config'])
|
||||
conn_config['db_port'] = str(int(conn_config['db_port']))
|
||||
self._db_mysql.set_host(conn_config['db_host'],int(conn_config['db_port']),conn_config['db_name'],conn_config['db_user'],conn_config['db_password'])
|
||||
# ----- 判断是否为远程数据库END @author hwliang<2021-01-08>------------
|
||||
d_tmp = self._db_mysql.query("select sum(DATA_LENGTH)+sum(INDEX_LENGTH) from information_schema.tables where table_schema='%s'" % db_name)
|
||||
try:
|
||||
p_size = self.map_to_list(d_tmp)[0][0]
|
||||
except:
|
||||
error_msg = public.getMsg('DB_CONN_ERR')
|
||||
error_msg = public.get_msg_gettext('The database connection is abnormal. Please check whether the root user authority or database configuration parameters are correct.')
|
||||
self.echo_error(error_msg)
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=db_name)
|
||||
return False
|
||||
|
||||
if p_size == None:
|
||||
error_msg = public.getMsg('DB_BACKUP_ERR',(db_name,))
|
||||
error_msg = public.get_msg_gettext('The specified database [ {} ] has no data!',(db_name,))
|
||||
self.echo_error(error_msg)
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=db_name)
|
||||
return False
|
||||
|
||||
character = public.get_database_character(db_name)
|
||||
|
||||
self.echo_info(public.getMsg('DB_BACKUP',(db_name,)))
|
||||
self.echo_info(public.getMsg("DB_SIZE",(public.to_size(p_size),)))
|
||||
self.echo_info(public.getMsg("DB_CHARACTER",(character,)))
|
||||
self.echo_info(public.get_msg_gettext('Backup database:{}',(db_name,)))
|
||||
self.echo_info(public.get_msg_gettext('Database size: {}',(public.to_size(p_size),)))
|
||||
self.echo_info(public.get_msg_gettext('Database character set: {}',(character,)))
|
||||
disk_path,disk_free,disk_inode = self.get_disk_free(dfile)
|
||||
self.echo_info(public.getMsg(
|
||||
"PARTITION_INFO",(
|
||||
self.echo_info(public.get_msg_gettext(
|
||||
'Partition {} available disk space is: {}, available Inode is: {}',(
|
||||
disk_path,str(public.to_size(disk_free)),str(disk_inode)
|
||||
)
|
||||
))
|
||||
if disk_path:
|
||||
if disk_free < p_size:
|
||||
error_msg = public.getMsg("PARTITION_LESS_THEN",(
|
||||
error_msg = public.get_msg_gettext('The available disk space of the target partition is less than {}, and the backup cannot be completed. Please increase the disk capacity or change the default backup directory on the settings page!',(
|
||||
str(public.to_size(p_size),)
|
||||
))
|
||||
self.echo_error(error_msg)
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=db_name)
|
||||
return False
|
||||
|
||||
if disk_inode < self._inode_min:
|
||||
error_msg = public.getMsg("INODE_LESS_THEN",(self._inode_min,))
|
||||
error_msg = public.get_msg_gettext('The available Inode of the target partition is less than {}, and the backup cannot be completed. Please increase the disk capacity or change the default backup directory on the settings page!',(self._inode_min,))
|
||||
self.echo_error(error_msg)
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=db_name)
|
||||
return False
|
||||
|
||||
stime = time.time()
|
||||
self.echo_info(public.getMsg("EXPORT_DB",(public.format_date(times=stime),)))
|
||||
self.echo_info(public.get_msg_gettext('Start exporting database: {}',(public.format_date(times=stime),)))
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
#self.mypass(True)
|
||||
mysqldump_bin = public.get_mysqldump_bin()
|
||||
try:
|
||||
password = public.M('config').where('id=?',(1,)).getField('mysql_root')
|
||||
os.environ["MYSQL_PWD"] = password
|
||||
backup_cmd = "/www/server/mysql/bin/mysqldump -E -R --default-character-set="+ character +" --force --hex-blob --opt " + db_name + " -u root" + " 2>"+self._err_log+"| gzip > " + dfile
|
||||
if not is_cloud_db:
|
||||
# 本地数据库 @author hwliang<2021-01-08>
|
||||
password = public.M('config').where('id=?',(1,)).getField('mysql_root')
|
||||
os.environ["MYSQL_PWD"] = password
|
||||
backup_cmd = mysqldump_bin + " -E -R --default-character-set="+ character +" --force --hex-blob --opt " + db_name + " -u root" + " 2>"+self._err_log+"| gzip > " + dfile
|
||||
else:
|
||||
# 远程数据库 @author hwliang<2021-01-08>
|
||||
os.environ["MYSQL_PWD"] = conn_config['db_password']
|
||||
backup_cmd = mysqldump_bin + " -h " + conn_config['db_host'] + " -P " + conn_config['db_port'] + " -E -R --default-character-set="+ character +" --force --hex-blob --opt " + db_name + " -u " + conn_config['db_user'] + " 2>"+self._err_log+"| gzip > " + dfile
|
||||
public.ExecShell(backup_cmd)
|
||||
except Exception as e:
|
||||
raise
|
||||
@@ -580,27 +603,27 @@ class backup:
|
||||
#self.mypass(False)
|
||||
gz_size = os.path.getsize(dfile)
|
||||
if gz_size < 400:
|
||||
error_msg = public.getMsg("EXPORT_DB_ERR")
|
||||
error_msg = public.get_msg_gettext('Database export failed!')
|
||||
self.echo_error(error_msg)
|
||||
self.send_failture_notification(error_msg)
|
||||
self.send_failture_notification(error_msg, target=db_name)
|
||||
self.echo_info(public.readFile(self._err_log))
|
||||
return False
|
||||
compressed_time = str('{:.2f}'.format(time.time() - stime))
|
||||
self.echo_info(
|
||||
public.getMsg("COMPRESS_TIME",(str(compressed_time),
|
||||
public.get_msg_gettext('Compression completed, took {} seconds, compressed package size: {}',(str(compressed_time),
|
||||
str(public.to_size(gz_size))
|
||||
))
|
||||
)
|
||||
if self._cloud:
|
||||
self.echo_info(public.getMsg("BACKUP_UPLOADING",(self._cloud._title,)))
|
||||
self.echo_info(public.get_msg_gettext('Uploading to {}, please wait ...',(self._cloud._title,)))
|
||||
if self._cloud.upload_file(dfile, 'database'):
|
||||
self.echo_info(public.getMsg("BACKUP_UPLOAD_SUCCESS",(self._cloud._title,)))
|
||||
self.echo_info(public.get_msg_gettext('Successfully uploaded to {}',(self._cloud._title,)))
|
||||
else:
|
||||
if hasattr(self._cloud, "error_msg"):
|
||||
if self._cloud.error_msg:
|
||||
error_msg = self._cloud.error_msg
|
||||
if not error_msg:
|
||||
error_msg = public.getMsg('BACKUP_UPLOAD_FAILED')
|
||||
error_msg = public.get_msg_gettext('File upload failed, skip this backup!')
|
||||
self.echo_error(error_msg)
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
@@ -612,7 +635,7 @@ class backup:
|
||||
filename = dfile
|
||||
if self._cloud:
|
||||
filename = dfile + '|' + self._cloud._name + '|' + fname
|
||||
self.echo_info(public.getMsg("DB_BACKUP_TO",(dfile,)))
|
||||
self.echo_info(public.get_msg_gettext('Database has been backed up to: {}',(dfile,)))
|
||||
if os.path.exists(self._err_log):
|
||||
os.remove(self._err_log)
|
||||
|
||||
@@ -651,9 +674,9 @@ class backup:
|
||||
if _not_save_local:
|
||||
if os.path.exists(dfile):
|
||||
os.remove(dfile)
|
||||
self.echo_info(public.getMsg("BACKUP_DEL",(dfile,)))
|
||||
self.echo_info(public.get_msg_gettext('User settings do not retain local backups, deleted {}',(dfile,)))
|
||||
else:
|
||||
self.echo_info(public.getMsg('KEEP_LOCAL'))
|
||||
self.echo_info(public.get_msg_gettext('Local backup has been kept'))
|
||||
|
||||
#清理多余备份
|
||||
if not self._cloud:
|
||||
@@ -662,6 +685,7 @@ class backup:
|
||||
backups = public.M('backup').where('type=? and pid=? and filename LIKE "%{}%"'.format(self._cloud._name),('1',pid)).field('id,name,filename').select()
|
||||
self.delete_old(backups,save,'database')
|
||||
self.echo_end()
|
||||
self.save_backup_status(True, target=db_name)
|
||||
return dfile
|
||||
|
||||
def generate_success_title(self, task_name):
|
||||
@@ -669,10 +693,10 @@ class backup:
|
||||
sm = send_mail()
|
||||
now = public.format_date(format="%Y-%m-%d %H:%M")
|
||||
server_ip = sm.GetLocalIp()
|
||||
title = public.getMsg("BACKUP_TASK_TITLE",(server_ip, task_name))
|
||||
title = public.get_msg_gettext('{}-{} The task was executed successfully',(server_ip, task_name))
|
||||
return title
|
||||
|
||||
def generate_failture_title(self):
|
||||
def generate_failture_title(self, task_name):
|
||||
title = "aaPanel backup task failed reminder"
|
||||
return title
|
||||
|
||||
@@ -743,13 +767,13 @@ class backup:
|
||||
""" 通过计划任务名称查找计划任务配置参数 """
|
||||
try:
|
||||
cron_info = public.M('crontab').where('echo=?',(cron_name,))\
|
||||
.field('name,save_local,notice,notice_channel').find()
|
||||
.field('name,save_local,notice,notice_channel,id').find()
|
||||
return cron_info
|
||||
except Exception as e:
|
||||
pass
|
||||
return {}
|
||||
|
||||
def send_failture_notification(self, error_msg, remark=""):
|
||||
def send_failture_notification(self, error_msg, target="", remark=""):
|
||||
"""发送任务失败消息
|
||||
|
||||
:error_msg 错误信息
|
||||
@@ -764,16 +788,18 @@ class backup:
|
||||
save_local = cron_info["save_local"]
|
||||
notice = cron_info["notice"]
|
||||
notice_channel = cron_info["notice_channel"]
|
||||
|
||||
self.save_backup_status(False, target, msg=error_msg)
|
||||
if notice == 0 or not notice_channel:
|
||||
return
|
||||
|
||||
if notice == 1 or notice == 2:
|
||||
title = self.generate_failture_title(cron_title)
|
||||
title = self.generate_failture_title()
|
||||
task_name = cron_title
|
||||
msg = self.generate_failture_notice(task_name, error_msg, remark)
|
||||
res = self.send_notification(notice_channel, title, msg)
|
||||
if res:
|
||||
self.echo_info(public.getMsg('NOTIFICATION_SENT'))
|
||||
self.echo_info(public.get_msg_gettext('Notification has been sent'))
|
||||
|
||||
def send_all_failture_notification(self, backup_type, results, remark=""):
|
||||
"""统一发送任务失败消息
|
||||
@@ -813,18 +839,18 @@ class backup:
|
||||
|
||||
if failture_count > 0:
|
||||
if self._cloud:
|
||||
remark = public.getMsg("BACKUP_MSG"),(
|
||||
remark = public.get_msg_gettext('Backup to {}, a total of {} {}, and failures {}.'),(
|
||||
self._cloud._title, total, backup_type_desc, failture_count)
|
||||
else:
|
||||
remark = public.getMsg("BACKUP_MSG1"),(
|
||||
remark = public.get_msg_gettext('Backup failed {}/total {} sites'),(
|
||||
failture_count, total, backup_type_desc)
|
||||
|
||||
msg = self.generate_all_failture_notice(task_name, content, backup_type_desc, remark)
|
||||
res = self.send_notification(notice_channel, title, msg)
|
||||
if res:
|
||||
self.echo_info(public.getMsg('NOTIFICATION_SENT'))
|
||||
self.echo_info(public.get_msg_gettext('Notification has been sent'))
|
||||
else:
|
||||
self.echo_error(public.getMsg('NOTIFICATION_ERR'))
|
||||
self.echo_error(public.get_msg_gettext('Failed to send notification'))
|
||||
|
||||
def send_notification(self, channel, title, msg = {}):
|
||||
try:
|
||||
@@ -876,5 +902,14 @@ class backup:
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
def save_backup_status(self, status, target="", msg=""):
|
||||
"""保存备份的状态"""
|
||||
try:
|
||||
if not self.cron_info:
|
||||
return
|
||||
cron_id = self.cron_info["id"]
|
||||
sql = public.M("system").dbfile("system").table("backup_status")
|
||||
sql.add("id,target,status,msg,addtime", (cron_id, target, status, msg, time.time(),))
|
||||
except Exception as e:
|
||||
print("Backup status saving error :{}.".format(e))
|
||||
|
||||
|
||||
+32
-28
@@ -34,12 +34,12 @@ import hmac
|
||||
try:
|
||||
import requests
|
||||
except:
|
||||
public.ExecShell('pip install requests')
|
||||
public.ExecShell('btpip install requests')
|
||||
import requests
|
||||
try:
|
||||
import OpenSSL
|
||||
except:
|
||||
public.ExecShell('pip install pyopenssl')
|
||||
public.ExecShell('btpip install pyOpenSSL')
|
||||
import OpenSSL
|
||||
import random
|
||||
import datetime
|
||||
@@ -97,7 +97,7 @@ class BaseDns(object):
|
||||
|
||||
class DNSPodDns(BaseDns):
|
||||
dns_provider_name = "dnspod"
|
||||
|
||||
_type = 0 # 0:lest 1:锐成
|
||||
def __init__(self, DNSPOD_ID, DNSPOD_API_KEY, DNSPOD_API_BASE_URL="https://dnsapi.cn/"):
|
||||
self.DNSPOD_ID = DNSPOD_ID
|
||||
self.DNSPOD_API_KEY = DNSPOD_API_KEY
|
||||
@@ -113,7 +113,10 @@ class DNSPodDns(BaseDns):
|
||||
|
||||
def create_dns_record(self, domain_name, domain_dns_value):
|
||||
domain_name,_,subd = extract_zone(domain_name)
|
||||
self.add_record(domain_name,subd,domain_dns_value,'TXT')
|
||||
if self._type == 1:
|
||||
self.add_record(domain_name,subd.replace('_acme-challenge.',''),domain_dns_value,'CNAME')
|
||||
else:
|
||||
self.add_record(domain_name,subd,domain_dns_value,'TXT')
|
||||
|
||||
|
||||
|
||||
@@ -177,7 +180,7 @@ class DNSPodDns(BaseDns):
|
||||
|
||||
class CloudFlareDns(BaseDns):
|
||||
dns_provider_name = "cloudflare"
|
||||
|
||||
_type = 0 # 0:lest 1:锐成
|
||||
def __init__(
|
||||
self,
|
||||
CLOUDFLARE_EMAIL,
|
||||
@@ -278,6 +281,12 @@ class CloudFlareDns(BaseDns):
|
||||
"name": "_acme-challenge" + "." + domain_name + ".",
|
||||
"content": "{0}".format(domain_dns_value),
|
||||
}
|
||||
|
||||
if self._type == 1:
|
||||
body['type'] = 'CNAME'
|
||||
root, _, acme_txt = extract_zone(domain_name)
|
||||
body['name'] = acme_txt.replace('_acme-challenge.','')
|
||||
|
||||
create_cloudflare_dns_record_response = requests.post(
|
||||
url, headers=headers, json=body, timeout=self.HTTP_TIMEOUT
|
||||
)
|
||||
@@ -326,6 +335,7 @@ class CloudFlareDns(BaseDns):
|
||||
|
||||
|
||||
class AliyunDns(object):
|
||||
_type = 0 # 0:lest 1:锐成
|
||||
def __init__(self, key, secret, ):
|
||||
self.key = str(key).strip()
|
||||
self.secret = str(secret).strip()
|
||||
@@ -359,11 +369,14 @@ class AliyunDns(object):
|
||||
|
||||
def create_dns_record(self, domain_name, domain_dns_value):
|
||||
root, _, acme_txt = extract_zone(domain_name)
|
||||
self.add_record(root,'TXT',acme_txt,domain_dns_value)
|
||||
try:
|
||||
self.add_record(root,'CAA','@',caa_value)
|
||||
except:
|
||||
pass
|
||||
if self._type == 1:
|
||||
acme_txt = acme_txt.replace('_acme-challenge.','')
|
||||
self.add_record(root,'CNAME',acme_txt,domain_dns_value)
|
||||
else:
|
||||
try:
|
||||
self.add_record(root,'CAA','@',caa_value)
|
||||
except: pass
|
||||
self.add_record(root,'TXT',acme_txt,domain_dns_value)
|
||||
|
||||
|
||||
def add_record(self,domain,s_type,host,value):
|
||||
@@ -493,17 +506,6 @@ class CloudxnsDns(object):
|
||||
req = requests.post(url=url, headers=headers, data=parameter,verify=False)
|
||||
req = req.json()
|
||||
|
||||
data = {
|
||||
"domain_id": int(domain),
|
||||
"host": '@',
|
||||
"value": caa_value,
|
||||
"type": "CAA",
|
||||
"line_id": 1,
|
||||
}
|
||||
parameter = json.dumps(data)
|
||||
headers = self.get_headers(url, parameter)
|
||||
requests.post(url=url, headers=headers, data=parameter,verify=False)
|
||||
|
||||
return req
|
||||
|
||||
def delete_dns_record(self, domain_name, domain_dns_value):
|
||||
@@ -513,10 +515,6 @@ class CloudxnsDns(object):
|
||||
headers = self.get_headers(url, )
|
||||
req = requests.delete(url=url, headers=headers, verify=False)
|
||||
req = req.json()
|
||||
|
||||
url = "https://www.cloudxns.net/api2/record/{}/{}".format(self.get_record_id(root,'CAA'), self.get_domain_id(root))
|
||||
headers = self.get_headers(url, )
|
||||
req = requests.delete(url=url, headers=headers, verify=False)
|
||||
return req
|
||||
|
||||
def get_record_id(self, domain_name,s_type = 'TXT'):
|
||||
@@ -530,12 +528,12 @@ class CloudxnsDns(object):
|
||||
return False
|
||||
|
||||
class Dns_com(object):
|
||||
|
||||
_type = 0 # 0:lest 1:锐成
|
||||
def __init__(self, key, secret, ):
|
||||
pass
|
||||
|
||||
def get_dns_obj(self):
|
||||
p_path = '/www/server/panel/plugin/model'
|
||||
p_path = '/www/server/panel/plugin/dns'
|
||||
if not os.path.exists(p_path +'/dns_main.py'): return None
|
||||
sys.path.insert(0,p_path)
|
||||
import dns_main
|
||||
@@ -544,7 +542,13 @@ class Dns_com(object):
|
||||
|
||||
def create_dns_record(self, domain_name, domain_dns_value):
|
||||
root, _, acme_txt = extract_zone(domain_name)
|
||||
result = self.get_dns_obj().add_txt(acme_txt + '.' + root,domain_dns_value)
|
||||
|
||||
if self._type == 1:
|
||||
acme_txt = acme_txt.replace('_acme-challenge.','')
|
||||
result = self.add_record(acme_txt + '.' + root,domain_dns_value)
|
||||
else:
|
||||
result = self.get_dns_obj().add_txt(acme_txt + '.' + root,domain_dns_value)
|
||||
|
||||
if result == "False":
|
||||
raise ValueError('[DNS] This domain name does not exist in the currently bound Pagoda DNS cloud resolution account. Adding parsing failed!')
|
||||
time.sleep(5)
|
||||
|
||||
+88
-88
@@ -135,51 +135,51 @@ class panelLets:
|
||||
#格式化错误输出
|
||||
def get_error(self,error):
|
||||
if error.find("Max checks allowed") >= 0 :
|
||||
return "CA can't verify your domain name, please check if the domain name resolution is correct, or wait 5-10 minutes and try again."
|
||||
return public.get_msg_gettext("CA can't verify your domain name, please check if the domain name resolution is correct, or wait 5-10 minutes and try again.")
|
||||
elif error.find("Max retries exceeded with") >= 0 or error.find('status_code=0 ') != -1:
|
||||
return "The CA server connection timed out, please try again later."
|
||||
return public.get_msg_gettext("The CA server connection timed out, please try again later.")
|
||||
elif error.find("The domain name belongs") >= 0:
|
||||
return "The domain name does not belong to this DNS service provider. Please ensure that the domain name is filled in correctly."
|
||||
return public.get_msg_gettext("The domain name does not belong to this DNS service provider. Please ensure that the domain name is filled in correctly.")
|
||||
elif error.find('login token ID is invalid') >=0:
|
||||
return 'The DNS server connection failed. Please check if the key is correct.'
|
||||
return public.get_msg_gettext('The DNS server connection failed. Please check if the key is correct.')
|
||||
elif "too many certificates already issued for exact set of domains" in error:
|
||||
return 'The signing failed, the domain name %s exceeded the weekly number of repeated issuances!' % re.findall("exact set of domains: (.+):", error)
|
||||
return public.get_msg_gettext('The signing failed, the domain name exact set of domains: (.+): {} exceeded the weekly number of repeated issuances!',(error,))
|
||||
elif "Error creating new account :: too many registrations for this IP" in error:
|
||||
return 'The signing failed, the current server IP has reached the limit of creating up to 10 accounts every 3 hours..'
|
||||
return public.get_msg_gettext('The signing failed, the current server IP has reached the limit of creating up to 10 accounts every 3 hours..')
|
||||
elif "DNS problem: NXDOMAIN looking up A for" in error:
|
||||
return 'The verification failed, the domain name was not resolved, or the resolution did not take effect.!'
|
||||
return public.get_msg_gettext('The verification failed, the domain name was not resolved, or the resolution did not take effect.!')
|
||||
elif "Invalid response from" in error:
|
||||
return 'Authentication failed, domain name resolution error or verification URL could not be accessed!'
|
||||
return public.get_msg_gettext('Authentication failed, domain name resolution error or verification URL could not be accessed!')
|
||||
elif error.find('TLS Web Server Authentication') != -1:
|
||||
public.restart_panel()
|
||||
return "Failed to connect to CA server, please try again later."
|
||||
return public.get_msg_gettext("Failed to connect to CA server, please try again later.")
|
||||
elif error.find('Name does not end in a public suffix') != -1:
|
||||
return "Unsupported domain name %s, please check if the domain name is correct!" % re.findall("Cannot issue for \"(.+)\":", error)
|
||||
return public.get_msg_gettext("Unsupported domain name {}, please check if the domain name is correct!",(re.findall("Cannot issue for \"(.+)\":", error),))
|
||||
elif error.find('No valid IP addresses found for') != -1:
|
||||
return "The domain name %s did not find a resolution record. Please check if the domain name is resolved.!" % re.findall("No valid IP addresses found for (.+)", error)
|
||||
return public.get_msg_gettext("The domain name {} did not find a resolution record. Please check if the domain name is resolved.!",(re.findall("No valid IP addresses found for (.+)", error),))
|
||||
elif error.find('No TXT record found at') != -1:
|
||||
return "If a valid TXT resolution record is not found in the domain name %s, please check if the TXT record is correctly parsed. If it is applied by DNSAPI, please try again in 10 minutes.!" % re.findall(
|
||||
"No TXT record found at (.+)", error)
|
||||
return public.get_msg_gettext("If a valid TXT resolution record is not found in the domain name {}, please check if the TXT record is correctly parsed. If it is applied by DNSAPI, please try again in 10 minutes.!",(re.findall(
|
||||
"No TXT record found at (.+)", error),))
|
||||
elif error.find('Incorrect TXT record') != -1:
|
||||
return "Found the wrong TXT record on %s: %s, please check if the TXT resolution is correct. If it is applied by DNSAPI, please try again in 10 minutes.!" % (
|
||||
re.findall("found at (.+)", error), re.findall("Incorrect TXT record \"(.+)\"", error))
|
||||
return public.get_msg_gettext("Found the wrong TXT record on {}: {}, please check if the TXT resolution is correct. If it is applied by DNSAPI, please try again in 10 minutes.!",(
|
||||
re.findall("found at (.+)", error), re.findall("Incorrect TXT record \"(.+)\"", error)))
|
||||
elif error.find('Domain not under you or your user') != -1:
|
||||
return "This domain name does not exist under this dnspod account. Adding parsing failed.!"
|
||||
return public.get_msg_gettext("This domain name does not exist under this dnspod account. Adding parsing failed.!")
|
||||
elif error.find('SERVFAIL looking up TXT for') != -1:
|
||||
return "If a valid TXT resolution record is not found in the domain name %s, please check if the TXT record is correctly parsed. If it is applied by DNSAPI, please try again in 10 minutes.!" % re.findall(
|
||||
"looking up TXT for (.+)", error)
|
||||
return public.get_msg_gettext("If a valid TXT resolution record is not found in the domain name {}, please check if the TXT record is correctly parsed. If it is applied by DNSAPI, please try again in 10 minutes.!",(re.findall(
|
||||
"looking up TXT for (.+)", error),))
|
||||
elif error.find('Timeout during connect') != -1:
|
||||
return "Connection timed out, CA server could not access your website!"
|
||||
return public.get_msg_gettext("Connection timed out, CA server could not access your website!")
|
||||
elif error.find("DNS problem: SERVFAIL looking up CAA for") != -1:
|
||||
return "The domain name %s is currently required to verify the CAA record. Please manually resolve the CAA record, or try again after 1 hour.!" % re.findall("looking up CAA for (.+)", error)
|
||||
return public.get_msg_gettext("The domain name {} is currently required to verify the CAA record. Please manually resolve the CAA record, or try again after 1 hour.!" , (re.findall("looking up CAA for (.+)", error),))
|
||||
elif error.find("Read timed out.") != -1:
|
||||
return "Verification timeout, please check whether the domain name is correctly resolved. If dns is resolved, the connection between the server and Let'sEncrypt may be abnormal. Please try again later!"
|
||||
return public.get_msg_gettext("Verification timeout, please check whether the domain name is correctly resolved. If dns is resolved, the connection between the server and Let'sEncrypt may be abnormal. Please try again later!")
|
||||
elif error.find("Error creating new order") != -1:
|
||||
return "Order creation failed, please try again later!"
|
||||
return public.get_msg_gettext("Order creation failed, please try again later!")
|
||||
elif error.find("Too Many Requests") != -1:
|
||||
return "More than 5 verification failures in 1 hour, application is temporarily banned, please try again later!"
|
||||
return public.get_msg_gettext("More than 5 verification failures in 1 hour, application is temporarily banned, please try again later!")
|
||||
elif error.find('HTTP Error 400: Bad Request') != -1:
|
||||
return "CA server denied access, please try again later!"
|
||||
return public.get_msg_gettext("CA server denied access, please try again later!")
|
||||
else:
|
||||
return error;
|
||||
|
||||
@@ -211,10 +211,10 @@ class panelLets:
|
||||
def renew_lest_cert(self,data):
|
||||
#续签网站
|
||||
path = self.setupPath + '/panel/vhost/cert/'+ data['siteName']
|
||||
if not os.path.exists(path): return public.returnMsg(False, 'RENEW_FAILED')
|
||||
if not os.path.exists(path): return public.return_msg_gettext(False, 'The renewal failed and the certificate directory does not exist.')
|
||||
|
||||
account_path = path + "/account_key.key"
|
||||
if not os.path.exists(account_path): return public.returnMsg(False, 'RENEW_FAILED1')
|
||||
if not os.path.exists(account_path): return public.return_msg_gettext(False, 'Renewal failed, missing account_key.')
|
||||
|
||||
#续签
|
||||
data['account_key'] = public.readFile(account_path)
|
||||
@@ -226,7 +226,7 @@ class panelLets:
|
||||
else:
|
||||
certificate = self.crate_let_by_file(data)
|
||||
|
||||
if not certificate['status']: return public.returnMsg(False, certificate['msg'])
|
||||
if not certificate['status']: return public.return_msg_gettext(False, certificate['msg'])
|
||||
|
||||
#存储证书
|
||||
public.writeFile(path + "/privkey.pem",certificate['key'])
|
||||
@@ -238,7 +238,7 @@ class panelLets:
|
||||
pfx_buffer = p12.export()
|
||||
public.writeFile(path + "/fullchain.pfx",pfx_buffer,'wb+')
|
||||
|
||||
return public.returnMsg(True, 'RENEW_SUCCESS1',(data['siteName'],))
|
||||
return public.return_msg_gettext(True, '[ {} ] The certificate renewal was successful.',(data['siteName'],))
|
||||
|
||||
|
||||
|
||||
@@ -249,9 +249,9 @@ class panelLets:
|
||||
data['domains'] = json.loads(get.domains)
|
||||
data['email'] = get.email
|
||||
data['dnssleep'] = get.dnssleep
|
||||
self.write_log(public.getMsg("APPLY_SSL",(data['domains'],)))
|
||||
self.write_log(public.get_msg_gettext('Ready to apply for SSL, domain name {}',(data['domains'],)))
|
||||
self.write_log("="*50)
|
||||
if len(data['domains']) <=0 : return public.returnMsg(False, 'APPLY_SSL_DOMAIN_ERR')
|
||||
if len(data['domains']) <=0 : return public.return_msg_gettext(False, 'The list of applied domain names cannot be empty.')
|
||||
|
||||
data['first_domain'] = data['domains'][0]
|
||||
|
||||
@@ -296,7 +296,7 @@ class panelLets:
|
||||
if 'status' in result and not result['status']: return result
|
||||
result['status'] = True
|
||||
public.writeFile(domain_path, json.dumps(result))
|
||||
result['msg'] = public.getMsg('MANUALLY_RESOLVE_DOMAIN')
|
||||
result['msg'] = public.get_msg_gettext('Get successful, please manually resolve the domain name')
|
||||
result['code'] = 2
|
||||
return result
|
||||
elif get.dnsapi == 'dns_bt':
|
||||
@@ -314,10 +314,10 @@ class panelLets:
|
||||
data['site_dir'] = get.site_dir
|
||||
certificate = self.crate_let_by_file(data)
|
||||
|
||||
if not certificate['status']: return public.returnMsg(False, certificate['msg'])
|
||||
if not certificate['status']: return public.return_msg_gettext(False, certificate['msg'])
|
||||
|
||||
#保存续签
|
||||
self.write_log(public.getMsg("SAVEING_SSL"))
|
||||
self.write_log(public.get_msg_gettext('|-Saving certificate..'))
|
||||
cpath = self.setupPath + '/panel/vhost/cert/crontab.json'
|
||||
config = {}
|
||||
if os.path.exists(cpath):
|
||||
@@ -341,11 +341,11 @@ class panelLets:
|
||||
public.writeFile(path + "/README","let")
|
||||
|
||||
#计划任务续签
|
||||
self.write_log(public.getMsg("SET_AUTORENEW"))
|
||||
self.write_log(public.get_msg_gettext('|-Setting up auto-renewal configuration..'))
|
||||
self.set_crond()
|
||||
self.write_log(public.getMsg("DEPLOY_SSL_TO_SITE"))
|
||||
self.write_log(public.get_msg_gettext('|-The application is successful and it is being automatically deployed to the website!'))
|
||||
self.write_log("="*50)
|
||||
return public.returnMsg(True, 'APPLY_SSL_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Application successful.')
|
||||
|
||||
#创建计划任务
|
||||
def set_crond(self):
|
||||
@@ -380,15 +380,15 @@ class panelLets:
|
||||
|
||||
#手动解析记录值
|
||||
if not 'renew' in data:
|
||||
self.write_log(public.getMsg("INIT_ACME"))
|
||||
self.write_log(public.get_msg_gettext('|-Initializing ACME protocol...'))
|
||||
BTPanel.dns_client = sewer.Client(domain_name = data['first_domain'],dns_class = None,account_key = data['account_key'],domain_alt_names = data['domains'],contact_email = str(data['email']) ,ACME_AUTH_STATUS_WAIT_PERIOD = 15,ACME_AUTH_STATUS_MAX_CHECKS = 5,ACME_REQUEST_TIMEOUT = 20,ACME_DIRECTORY_URL = self.let_url)
|
||||
domain_dns_value = "placeholder"
|
||||
dns_names_to_delete = []
|
||||
self.write_log(public.getMsg("REGISTER_ACCOUNT"))
|
||||
self.write_log(public.get_msg_gettext('|-Registering account...'))
|
||||
BTPanel.dns_client.acme_register()
|
||||
authorizations, finalize_url = BTPanel.dns_client.apply_for_cert_issuance()
|
||||
responders = []
|
||||
self.write_log(public.getMsg("GET_VERIFICATION_INFO"))
|
||||
self.write_log(public.get_msg_gettext('|-Getting verification information...'))
|
||||
for url in authorizations:
|
||||
identifier_auth = BTPanel.dns_client.get_identifier_authorization(url)
|
||||
authorization_url = identifier_auth["url"]
|
||||
@@ -413,25 +413,25 @@ class panelLets:
|
||||
dns['dns_names'] = dns_names_to_delete
|
||||
dns['responders'] = responders
|
||||
dns['finalize_url'] = finalize_url
|
||||
self.write_log(public.getMsg("RETURN_VERIFICATION_INFO"))
|
||||
self.write_log(public.get_msg_gettext('|-Return the verification information to the front end, wait for the user to manually resolve the domain name and complete the verification...'))
|
||||
return dns
|
||||
else:
|
||||
self.write_log(public.getMsg("SUBMIT_V_REQUEST"))
|
||||
self.write_log(public.get_msg_gettext('|-User submits verification request...'))
|
||||
responders = data['dns']['responders']
|
||||
dns_names_to_delete = data['dns']['dns_names']
|
||||
finalize_url = data['dns']['finalize_url']
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("CA_V_DOMAIN",(i['dns_name'],)))
|
||||
self.write_log(public.get_msg_gettext('|-Requesting CA to verify domain name [{}]...',(i['dns_name'],)))
|
||||
auth_status_response = BTPanel.dns_client.check_authorization_status(i["authorization_url"])
|
||||
if auth_status_response.json()["status"] == "pending":
|
||||
BTPanel.dns_client.respond_to_challenge(i["acme_keyauthorization"], i["dns_challenge_url"])
|
||||
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("GET_CA_V_RES",(i['dns_name'],)))
|
||||
self.write_log(public.get_msg_gettext('|-Get CA verification results [{}]...',(i['dns_name'],)))
|
||||
BTPanel.dns_client.check_authorization_status(i["authorization_url"], ["valid","invalid"])
|
||||
self.write_log(public.getMsg("ALL_DOMAIN_V_PASS"))
|
||||
self.write_log(public.get_msg_gettext('|-All domain names are verified and CSR is being sent...'))
|
||||
certificate_url = BTPanel.dns_client.send_csr(finalize_url)
|
||||
self.write_log(public.getMsg("GET_CERT_CONTENT"))
|
||||
self.write_log(public.get_msg_gettext('|-Getting certificate content...'))
|
||||
certificate = BTPanel.dns_client.download_certificate(certificate_url)
|
||||
|
||||
if certificate:
|
||||
@@ -443,10 +443,10 @@ class panelLets:
|
||||
result['status'] = True
|
||||
BTPanel.dns_client = None
|
||||
else:
|
||||
result['msg'] = public.getMsg('CERT_APPLY_ERR')
|
||||
result['msg'] = public.get_msg_gettext('Certificate acquisition failed, please try again later.')
|
||||
|
||||
except Exception as e:
|
||||
self.write_log(public.getMsg("CERT_APPLY_ERR1",(e,)))
|
||||
self.write_log(public.get_msg_gettext('|-Error: {}, exited the application process.',(e,)))
|
||||
self.write_log("=" * 50)
|
||||
res = str(e).split('>>>>')
|
||||
err = False
|
||||
@@ -461,10 +461,10 @@ class panelLets:
|
||||
def crate_let_by_dns(self,data):
|
||||
dns_class = self.get_dns_class(data)
|
||||
if not dns_class:
|
||||
self.write_log(public.getMsg("DNS_APPLY_ERR"))
|
||||
self.write_log(public.getMsg("EXIT_APPLY_PROCESS"))
|
||||
self.write_log(public.get_msg_gettext('|-Error: {}, exit the application process.'))
|
||||
self.write_log(public.get_msg_gettext('|-Exited the application process!'))
|
||||
self.write_log("="*50)
|
||||
return public.returnMsg(False, 'DNS_APPLY_ERR1')
|
||||
return public.return_msg_gettext(False, 'An error occurred while requesting a certificate using dns')
|
||||
|
||||
result = {}
|
||||
result['status'] = False
|
||||
@@ -472,16 +472,16 @@ class panelLets:
|
||||
log_level = "INFO"
|
||||
if data['account_key']: log_level = 'ERROR'
|
||||
if not data['email']: data['email'] = public.M('users').getField('email')
|
||||
self.write_log(public.getMsg("INIT_ACME"))
|
||||
self.write_log(public.get_msg_gettext('|-Initializing ACME protocol...'))
|
||||
client = sewer.Client(domain_name = data['first_domain'],domain_alt_names = data['domains'],account_key = data['account_key'],contact_email = str(data['email']),LOG_LEVEL = log_level,ACME_AUTH_STATUS_WAIT_PERIOD = 15,ACME_AUTH_STATUS_MAX_CHECKS = 5,ACME_REQUEST_TIMEOUT = 20, dns_class = dns_class,ACME_DIRECTORY_URL = self.let_url)
|
||||
domain_dns_value = "placeholder"
|
||||
dns_names_to_delete = []
|
||||
try:
|
||||
self.write_log(public.getMsg("REGISTER_ACCOUNT"))
|
||||
self.write_log(public.get_msg_gettext('|-Registering account...'))
|
||||
client.acme_register()
|
||||
authorizations, finalize_url = client.apply_for_cert_issuance()
|
||||
responders = []
|
||||
self.write_log(public.getMsg("GET_VERIFICATION_INFO"))
|
||||
self.write_log(public.get_msg_gettext('|-Getting verification information...'))
|
||||
for url in authorizations:
|
||||
identifier_auth = client.get_identifier_authorization(url)
|
||||
authorization_url = identifier_auth["url"]
|
||||
@@ -489,7 +489,7 @@ class panelLets:
|
||||
dns_token = identifier_auth["dns_token"]
|
||||
dns_challenge_url = identifier_auth["dns_challenge_url"]
|
||||
acme_keyauthorization, domain_dns_value = client.get_keyauthorization(dns_token)
|
||||
self.write_log(public.getMsg("ADD_TXT_RECORD",(dns_name,domain_dns_value)))
|
||||
self.write_log(public.get_msg_gettext('|-Adding resolution record, domain name [{}], record value [{}]...',(dns_name,domain_dns_value)))
|
||||
dns_class.create_dns_record(public.de_punycode(dns_name), domain_dns_value)
|
||||
dns_names_to_delete.append({"dns_name": public.de_punycode(dns_name), "domain_dns_value": domain_dns_value})
|
||||
responders.append({"dns_name":dns_name,"domain_dns_value":domain_dns_value,"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"dns_challenge_url": dns_challenge_url} )
|
||||
@@ -498,33 +498,33 @@ class panelLets:
|
||||
|
||||
try:
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("CHECK_TXT_RECORD",(i['dns_name'],i['domain_dns_value'])))
|
||||
self.write_log(public.get_msg_gettext('|-Attempt to verify the resolution result, domain name [{}], record value [{}]...',(i['dns_name'],i['domain_dns_value'])))
|
||||
self.check_dns(self.get_acme_name(i['dns_name']),i['domain_dns_value'])
|
||||
self.write_log(public.getMsg("CA_CHECK_RECORD",(i['dns_name'])))
|
||||
self.write_log(public.get_msg_gettext('|-Request CA to verify domain name [{}]...',(i['dns_name'])))
|
||||
auth_status_response = client.check_authorization_status(i["authorization_url"])
|
||||
r_data = auth_status_response.json()
|
||||
if r_data["status"] == "pending":
|
||||
client.respond_to_challenge(i["acme_keyauthorization"], i["dns_challenge_url"])
|
||||
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("CHECK_CA_RES",(i['dns_name'],)))
|
||||
self.write_log(public.get_msg_gettext('|-Check CA verification results [{}]...',(i['dns_name'],)))
|
||||
client.check_authorization_status(i["authorization_url"], ["valid","invalid"])
|
||||
except Exception as ex:
|
||||
self.write_log(public.getMsg("APPLY_WITH_DNS_ERR",(str(ex),)))
|
||||
self.write_log(public.get_msg_gettext('|-An error occurred, try again [{}]',(str(ex),)))
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("CHECK_TXT_RECORD",(i['dns_name'],i['domain_dns_value'])))
|
||||
self.write_log(public.get_msg_gettext('|-Attempt to verify the resolution result, domain name [{}], record value [{}]...',(i['dns_name'],i['domain_dns_value'])))
|
||||
self.check_dns(self.get_acme_name(i['dns_name']),i['domain_dns_value'])
|
||||
self.write_log(public.getMsg("CA_CHECK_RECORD",(i['dns_name'])))
|
||||
self.write_log(public.get_msg_gettext('|-Request CA to verify domain name [{}]...',(i['dns_name'])))
|
||||
auth_status_response = client.check_authorization_status(i["authorization_url"])
|
||||
r_data = auth_status_response.json()
|
||||
if r_data["status"] == "pending":
|
||||
client.respond_to_challenge(i["acme_keyauthorization"], i["dns_challenge_url"])
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("CHECK_CA_RES",(i['dns_name'],)))
|
||||
self.write_log(public.get_msg_gettext('|-Check CA verification results [{}]...',(i['dns_name'],)))
|
||||
client.check_authorization_status(i["authorization_url"], ["valid","invalid"])
|
||||
self.write_log(public.getMsg("ALL_DOMAIN_V_PASS"))
|
||||
self.write_log(public.get_msg_gettext('|-All domain names are verified and CSR is being sent...'))
|
||||
certificate_url = client.send_csr(finalize_url)
|
||||
self.write_log(public.getMsg("FETCH_CERT_CONTENT"))
|
||||
self.write_log(public.get_msg_gettext('|-Fetching certificate content...'))
|
||||
certificate = client.download_certificate(certificate_url)
|
||||
if certificate:
|
||||
certificate = self.split_ca_data(certificate)
|
||||
@@ -539,7 +539,7 @@ class panelLets:
|
||||
finally:
|
||||
try:
|
||||
for i in dns_names_to_delete:
|
||||
self.write_log(public.getMsg("CLEAR_RESOLVE_HISTORY",(i["dns_name"])))
|
||||
self.write_log(public.get_msg_gettext('|-Clearing resolve history [{}]',(i["dns_name"])))
|
||||
dns_class.delete_dns_record(i["dns_name"], i["domain_dns_value"])
|
||||
except :
|
||||
pass
|
||||
@@ -547,10 +547,10 @@ class panelLets:
|
||||
except Exception as e:
|
||||
try:
|
||||
for i in dns_names_to_delete:
|
||||
self.write_log(public.getMsg("CLEAR_RESOLVE_HISTORY",(i["dns_name"])))
|
||||
self.write_log(public.get_msg_gettext('|-Clearing resolve history [{}]',(i["dns_name"])))
|
||||
dns_class.delete_dns_record(i["dns_name"], i["domain_dns_value"])
|
||||
except:pass
|
||||
self.write_log(public.getMsg("DNS_APPLY_ERR",(str(public.get_error_info()),)))
|
||||
self.write_log(public.get_msg_gettext('|-Error: {}, exit the application process.',(str(public.get_error_info()),)))
|
||||
self.write_log("=" * 50)
|
||||
res = str(e).split('>>>>')
|
||||
err = False
|
||||
@@ -566,17 +566,17 @@ class panelLets:
|
||||
result['status'] = False
|
||||
result['clecks'] = []
|
||||
try:
|
||||
self.write_log(public.getMsg("INIT_ACME"))
|
||||
self.write_log(public.get_msg_gettext('|-Initializing ACME protocol...'))
|
||||
log_level = "INFO"
|
||||
if data['account_key']: log_level = 'ERROR'
|
||||
if not data['email']: data['email'] = public.M('users').getField('email')
|
||||
client = sewer.Client(domain_name = data['first_domain'],dns_class = None,account_key = data['account_key'],domain_alt_names = data['domains'],contact_email = str(data['email']),LOG_LEVEL = log_level,ACME_AUTH_STATUS_WAIT_PERIOD = 15,ACME_AUTH_STATUS_MAX_CHECKS = 5,ACME_REQUEST_TIMEOUT = 20,ACME_DIRECTORY_URL = self.let_url)
|
||||
self.write_log(public.getMsg("REGISTER_ACCOUNT"))
|
||||
self.write_log(public.get_msg_gettext('|-Registering account...'))
|
||||
client.acme_register()
|
||||
authorizations, finalize_url = client.apply_for_cert_issuance()
|
||||
responders = []
|
||||
sucess_domains = []
|
||||
self.write_log(public.getMsg("GET_VERIFICATION_INFO"))
|
||||
self.write_log(public.get_msg_gettext('|-Getting verification information...'))
|
||||
for url in authorizations:
|
||||
identifier_auth = self.get_identifier_authorization(client,url)
|
||||
|
||||
@@ -591,21 +591,21 @@ class panelLets:
|
||||
|
||||
#写入token
|
||||
wellknown_path = acme_dir + '/' + http_token
|
||||
self.write_log(public.getMsg("CREATE_V_FILE",(wellknown_path,)))
|
||||
self.write_log(public.get_msg_gettext('|-Writing verification file [{}]...',(wellknown_path,)))
|
||||
public.writeFile(wellknown_path,acme_keyauthorization)
|
||||
wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(http_name, http_token)
|
||||
wellknown_url = "http://{}/.well-known/acme-challenge/{}".format(http_name, http_token)
|
||||
|
||||
result['clecks'].append({'wellknown_url':wellknown_url,'http_token':http_token})
|
||||
is_check = False
|
||||
n = 0
|
||||
self.write_log(public.getMsg("CHECK_FILE_CONTENT",(wellknown_url)))
|
||||
self.write_log(public.get_msg_gettext('|-Attempt to verify file contents via HTTP [{}]...',(wellknown_url)))
|
||||
while n < 5:
|
||||
print("wait_check_authorization_status")
|
||||
try:
|
||||
retkey = public.httpGet(wellknown_url,20)
|
||||
if retkey == acme_keyauthorization:
|
||||
is_check = True
|
||||
self.write_log(public.getMsg("CHECK_FILE_CONTENT1",(retkey,)))
|
||||
self.write_log(public.get_msg_gettext('|-Verified, content [{}]...',(retkey,)))
|
||||
break
|
||||
except :
|
||||
pass
|
||||
@@ -617,18 +617,18 @@ class panelLets:
|
||||
if len(sucess_domains) > 0:
|
||||
#验证
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("CA_CHECK_RECORD",(i['http_name'],)))
|
||||
self.write_log(public.get_msg_gettext('|-Request CA to verify domain name [{}]...',(i['http_name'],)))
|
||||
auth_status_response = client.check_authorization_status(i["authorization_url"])
|
||||
if auth_status_response.json()["status"] == "pending":
|
||||
client.respond_to_challenge(i["acme_keyauthorization"], i["http_challenge_url"]).json()
|
||||
|
||||
for i in responders:
|
||||
self.write_log(public.getMsg("CHECK_CA_RES",(i['http_name'],)))
|
||||
self.write_log(public.get_msg_gettext('|-Check CA verification results [{}]...',(i['http_name'],)))
|
||||
client.check_authorization_status(i["authorization_url"], ["valid","invalid"])
|
||||
|
||||
self.write_log(public.getMsg("ALL_DOMAIN_V_PASS"))
|
||||
self.write_log(public.get_msg_gettext('|-All domain names are verified and CSR is being sent...'))
|
||||
certificate_url = client.send_csr(finalize_url)
|
||||
self.write_log(public.getMsg("GET_CERT_CONTENT"))
|
||||
self.write_log(public.get_msg_gettext('|-Getting certificate content...'))
|
||||
certificate = client.download_certificate(certificate_url)
|
||||
|
||||
if certificate:
|
||||
@@ -640,11 +640,11 @@ class panelLets:
|
||||
result['status'] = True
|
||||
|
||||
else:
|
||||
result['msg'] = public.getMsg('CERT_APPLY_ERR')
|
||||
result['msg'] = public.get_msg_gettext('Certificate acquisition failed, please try again later.')
|
||||
else:
|
||||
result['msg'] = public.getMsg("APPLY_SSL_ERROR_MSG")
|
||||
result['msg'] = public.get_msg_gettext('The signing failed, we were unable to verify your domain name:<p>1. Check if the domain name is bound to the corresponding site.</p><p>2. Check if the domain name is correctly resolved to the server, or the resolution is not fully effective.</p><p>3. If your site has a reverse proxy set up, or if you are using a CDN, please turn it off first.</p><p>4. If your site has a 301 redirect, please turn it off first</p><p>5. If the above checks confirm that there is no problem, please try to change the DNS service provider.</p>')
|
||||
except Exception as e:
|
||||
self.write_log(public.getMsg("DNS_APPLY_ERR",(str(public.get_error_info()),)))
|
||||
self.write_log(public.get_msg_gettext('|-Error: {}, exit the application process.',(str(public.get_error_info()),)))
|
||||
self.write_log("=" * 50)
|
||||
res = str(e).split('>>>>')
|
||||
err = False
|
||||
@@ -693,7 +693,7 @@ class panelLets:
|
||||
for i in j.items:
|
||||
txt_value = i.to_text().replace('"','').strip()
|
||||
if txt_value == value:
|
||||
self.write_log(public.getMsg("SUCCESS_V",(domain,type,txt_value)))
|
||||
self.write_log(public.get_msg_gettext('|-Successful verification, domain name [{}], record type [{}], record value [{}]!',(domain,type,txt_value)))
|
||||
print("Verification succeeded: %s" % txt_value)
|
||||
return True
|
||||
except:
|
||||
@@ -753,18 +753,18 @@ class panelLets:
|
||||
def renew_lets_ssl(self):
|
||||
cpath = self.setupPath + '/panel/vhost/cert/crontab.json'
|
||||
if not os.path.exists(cpath):
|
||||
print(public.getMsg("NO_ORDER_RENEW") )
|
||||
print(public.get_msg_gettext('|-There are currently no certificates to renew.') )
|
||||
else:
|
||||
old_list = json.loads(public.ReadFile(cpath))
|
||||
print('=======================================================================')
|
||||
print(public.getMsg('TOTAL_RENEW',(time.strftime('%Y-%m-%d %X',time.localtime()),str(len(old_list)))))
|
||||
print(public.get_msg_gettext('|-{} Total [{}] renewal of visa tasks',(time.strftime('%Y-%m-%d %X',time.localtime()),str(len(old_list)))))
|
||||
cron_list = self.get_renew_lets_bytimeout(old_list)
|
||||
|
||||
tlist = []
|
||||
for siteName in old_list:
|
||||
if not siteName in cron_list: tlist.append(siteName)
|
||||
print(public.getMsg('SSL_NOT_EXPIRED_OR_NOT_USE',(','.join(tlist),)))
|
||||
print(public.getMsg('WAIT_RENEW1',(time.strftime('%Y-%m-%d %X',time.localtime()),str(len(cron_list)))))
|
||||
print(public.get_msg_gettext('|-[{}] Not expired or the site does not use the Let\s Encrypt certificate.',(','.join(tlist),)))
|
||||
print(public.get_msg_gettext('|-{} Waiting for renewal [{}].',(time.strftime('%Y-%m-%d %X',time.localtime()),str(len(cron_list)))))
|
||||
|
||||
sucess_list = []
|
||||
err_list = []
|
||||
@@ -775,11 +775,11 @@ class panelLets:
|
||||
sucess_list.append(siteName)
|
||||
else:
|
||||
err_list.append({"siteName":siteName,"msg":ret['msg']})
|
||||
print(public.getMsg("RENEW_COMPLETED",(str(len(cron_list)),str(len(sucess_list)),str(len(err_list)))))
|
||||
print(public.get_msg_gettext('|-After the task is completed, a total of renewals are required.[{}], renewal success [%s], renewal failed [{}]. ',(str(len(cron_list)),str(len(sucess_list)),str(len(err_list)))))
|
||||
if len(sucess_list) > 0:
|
||||
print(public.getMsg("RENEW_SUCCESS2",(','.join(sucess_list),)))
|
||||
print(public.get_msg_gettext('|-Renewal success:{}',(','.join(sucess_list),)))
|
||||
if len(err_list) > 0:
|
||||
print(public.getMsg("RENEW_FAILED2"))
|
||||
print(public.get_msg_gettext('|-Renewal failed:'))
|
||||
for x in err_list:
|
||||
print(" %s ->> %s" % (x['siteName'],x['msg']))
|
||||
|
||||
|
||||
+29
-26
@@ -44,33 +44,36 @@ class panelMessage:
|
||||
|
||||
|
||||
"""
|
||||
获取官网推送消息,一小时获取一次
|
||||
获取官网推送消息,一天获取一次
|
||||
"""
|
||||
def get_cloud_messages(self,args):
|
||||
#ret = cache.get('get_cloud_messages')
|
||||
#if ret: return public.returnMsg(True,'同步成功1!')
|
||||
data = {}
|
||||
data['version'] = public.version()
|
||||
data['os'] = self.os
|
||||
sUrl = public.GetConfigValue('home') + '/api/wpanel/get_messages'
|
||||
import http_requests
|
||||
http_requests.DEFAULT_TYPE = 'src'
|
||||
info = http_requests.post(sUrl,data).json()
|
||||
# info = json.loads(public.httpPost(sUrl,data))
|
||||
for x in info:
|
||||
count = public.M('messages').where('level=? and msg=?',(x['level'],x['msg'],)).count()
|
||||
if count: continue
|
||||
try:
|
||||
ret = cache.get('get_cloud_messages')
|
||||
if ret: return public.returnMsg(True,'同步成功1!')
|
||||
data = {}
|
||||
data['version'] = public.version()
|
||||
data['os'] = self.os
|
||||
sUrl = public.GetConfigValue('home') + '/api/wpanel/get_messages'
|
||||
import http_requests
|
||||
http_requests.DEFAULT_TYPE = 'src'
|
||||
info = http_requests.post(sUrl,data).json()
|
||||
# info = json.loads(public.httpPost(sUrl,data))
|
||||
for x in info:
|
||||
count = public.M('messages').where('level=? and msg=?',(x['level'],x['msg'],)).count()
|
||||
if count: continue
|
||||
|
||||
pdata = {
|
||||
"level":x['level'],
|
||||
"msg":x['msg'],
|
||||
"state":1,
|
||||
"expire":int(time.time()) + (int(x['expire']) * 86400),
|
||||
"addtime": int(time.time())
|
||||
}
|
||||
public.M('messages').insert(pdata)
|
||||
#cache.set('get_cloud_messages',3600)
|
||||
return public.returnMsg(True,'同步成功!')
|
||||
pdata = {
|
||||
"level":x['level'],
|
||||
"msg":x['msg'],
|
||||
"state":1,
|
||||
"expire":int(time.time()) + (int(x['expire']) * 86400),
|
||||
"addtime": int(time.time())
|
||||
}
|
||||
public.M('messages').insert(pdata)
|
||||
cache.set('get_cloud_messages',86400)
|
||||
return public.returnMsg(True,'同步成功!')
|
||||
except:
|
||||
return public.returnMsg(False,'同步失败!')
|
||||
|
||||
def get_messages(self,args = None):
|
||||
'''
|
||||
@@ -78,7 +81,7 @@ class panelMessage:
|
||||
@author hwliang <2020-05-18>
|
||||
@return list
|
||||
'''
|
||||
self.get_cloud_messages(args)
|
||||
public.run_thread(self.get_cloud_messages,args=(args,))
|
||||
data = public.M('messages').where('state=? and expire>?',(1,int(time.time()))).order("id desc").select()
|
||||
return data
|
||||
|
||||
@@ -88,7 +91,7 @@ class panelMessage:
|
||||
@author hwliang <2020-05-18>
|
||||
@return list
|
||||
'''
|
||||
self.get_cloud_messages(args)
|
||||
public.run_thread(self.get_cloud_messages,args=(args,))
|
||||
data = public.M('messages').order("id desc").select()
|
||||
return data
|
||||
|
||||
|
||||
+32
-3
@@ -22,7 +22,13 @@ class panelMysql:
|
||||
def __Conn(self):
|
||||
if self.__DB_NET: return True
|
||||
try:
|
||||
socket = '/tmp/mysql.sock'
|
||||
myconf = public.readFile('/etc/my.cnf')
|
||||
socket_re = re.search(r"socket\s*=\s*(.+)",myconf)
|
||||
if socket_re:
|
||||
socket = socket_re.groups()[0]
|
||||
else:
|
||||
socket = '/tmp/mysql.sock'
|
||||
|
||||
try:
|
||||
if sys.version_info[0] != 2:
|
||||
try:
|
||||
@@ -34,7 +40,7 @@ class panelMysql:
|
||||
import MySQLdb
|
||||
if sys.version_info[0] == 2:
|
||||
reload(MySQLdb)
|
||||
except Exception as ex:
|
||||
except:
|
||||
try:
|
||||
import pymysql
|
||||
pymysql.install_as_MySQLdb()
|
||||
@@ -43,7 +49,7 @@ class panelMysql:
|
||||
self.__DB_ERR = e
|
||||
return False
|
||||
try:
|
||||
myconf = public.readFile('/etc/my.cnf')
|
||||
|
||||
rep = r"port\s*=\s*([0-9]+)"
|
||||
self.__DB_PORT = int(re.search(rep,myconf).groups()[0])
|
||||
except:
|
||||
@@ -65,12 +71,34 @@ class panelMysql:
|
||||
def connect_network(self,host,port,username,password):
|
||||
self.__DB_NET = True
|
||||
try:
|
||||
try:
|
||||
if sys.version_info[0] != 2:
|
||||
try:
|
||||
import pymysql
|
||||
except:
|
||||
public.ExecShell("pip install pymysql")
|
||||
import pymysql
|
||||
pymysql.install_as_MySQLdb()
|
||||
import MySQLdb
|
||||
if sys.version_info[0] == 2:
|
||||
reload(MySQLdb)
|
||||
except:
|
||||
try:
|
||||
import pymysql
|
||||
pymysql.install_as_MySQLdb()
|
||||
import MySQLdb
|
||||
except Exception as e:
|
||||
self.__DB_ERR = e
|
||||
return False
|
||||
self.__DB_CONN = MySQLdb.connect(host = host,user = username,passwd = password,port = port,charset="utf8",connect_timeout=10)
|
||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
||||
return True
|
||||
except MySQLdb.Error as e:
|
||||
self.__DB_ERR = e
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def execute(self,sql):
|
||||
#执行SQL语句返回受影响行
|
||||
if not self.__Conn(): return self.__DB_ERR
|
||||
@@ -99,6 +127,7 @@ class panelMysql:
|
||||
except Exception as ex:
|
||||
return ex
|
||||
|
||||
|
||||
#关闭连接
|
||||
def __Close(self):
|
||||
self.__DB_CUR.close()
|
||||
|
||||
+3
-10
@@ -61,15 +61,8 @@ class panelPHP:
|
||||
data = {}
|
||||
data['GET'] = request.args.to_dict()
|
||||
data['POST'] = {}
|
||||
x_token = request.headers.get('x-http-token')
|
||||
if x_token:
|
||||
aes_pwd = x_token[:8] + x_token[40:48]
|
||||
for key in request.form.keys():
|
||||
data['POST'][key] = str(request.form.get(key,''))
|
||||
if x_token:
|
||||
if len(data['POST'][key]) > 5:
|
||||
if data['POST'][key][:6] == 'BT-CRT':
|
||||
data['POST'][key] = public.aes_decrypt(data['POST'][key][6:],aes_pwd)
|
||||
data['POST']['client_ip'] = public.GetClientIp()
|
||||
data = json.dumps(data)
|
||||
public.writeFile(self.__args_tmp,data)
|
||||
@@ -93,7 +86,7 @@ class panelPHP:
|
||||
php_vs = json.loads(public.readFile(php_v_file).replace('.',''))
|
||||
else:
|
||||
#否则兼容所有版本
|
||||
php_vs = ["80","74","73","72","71","70","56","55","54","53","52"]
|
||||
php_vs = public.get_php_versions(True)
|
||||
#判段兼容的PHP版本是否安装
|
||||
php_path = "/www/server/php/"
|
||||
php_v = None
|
||||
@@ -125,7 +118,7 @@ class panelPHP:
|
||||
else:
|
||||
php_vs = sorted(php_version,reverse=True)
|
||||
else:
|
||||
php_vs = ["80","74","73","72","71","70","56","55","54","53","52"]
|
||||
php_vs = public.get_php_versions(True)
|
||||
php_path = "/www/server/php/"
|
||||
php_v = None
|
||||
for pv in php_vs:
|
||||
@@ -601,7 +594,7 @@ class FPM(object):
|
||||
'DOCUMENT_ROOT': self.document_root,
|
||||
'SERVER_PROTOCOL' : 'HTTP/1.1',
|
||||
'REMOTE_ADDR': '127.0.0.1',
|
||||
'REMOTE_PORT': '7800',
|
||||
'REMOTE_PORT': '8888',
|
||||
'SERVER_ADDR': '127.0.0.1',
|
||||
'SERVER_PORT': '80',
|
||||
'SERVER_NAME': 'BT-Panel'
|
||||
|
||||
+261
-207
File diff suppressed because it is too large
Load Diff
@@ -29,11 +29,11 @@ class ProjectController:
|
||||
}
|
||||
'''
|
||||
try: # 表单验证
|
||||
if args['mod_name'] in ['base']: return public.return_status_code(1000,'错误的调用!')
|
||||
if args['mod_name'] in ['base']: return public.return_status_code(1000,'wrong call!')
|
||||
public.exists_args('def_name,mod_name',args)
|
||||
if args['def_name'].find('__') != -1: return public.return_status_code(1000,'调用的方法名称中不能包含“__”字符')
|
||||
if not re.match(r"^\w+$",args['mod_name']): return public.return_status_code(1000,'调用的模块名称中不能包含\w以外的字符')
|
||||
if not re.match(r"^\w+$",args['def_name']): return public.return_status_code(1000,'调用的方法名称中不能包含\w以外的字符')
|
||||
if args['def_name'].find('__') != -1: return public.return_status_code(1000,'Called method name cannot contain [ __ ] characters')
|
||||
if not re.match(r"^\w+$",args['mod_name']): return public.return_status_code(1000,'The called module name cannot contain characters other than \w')
|
||||
if not re.match(r"^\w+$",args['def_name']): return public.return_status_code(1000,'The called module name cannot contain characters other than \w')
|
||||
except:
|
||||
return public.get_error_object()
|
||||
# 参数处理
|
||||
@@ -59,7 +59,7 @@ class ProjectController:
|
||||
else:
|
||||
pdata = args.data
|
||||
else:
|
||||
pdata = public.dict_obj()
|
||||
pdata = args
|
||||
|
||||
# 前置HOOK
|
||||
hook_index = '{}_{}_LAST'.format(mod_name.upper(),def_name.upper())
|
||||
|
||||
+30
-30
@@ -83,7 +83,7 @@ class panelRedirect:
|
||||
else:
|
||||
sk.connect((d, 443))
|
||||
except:
|
||||
return public.returnMsg(False, "CANT_GET_URL")
|
||||
return public.return_msg_gettext(False, 'Can NOT get target URL')
|
||||
# 计算proxyname md5
|
||||
def __calc_md5(self,redirectname):
|
||||
import hashlib
|
||||
@@ -112,7 +112,7 @@ class panelRedirect:
|
||||
if get.sitename in sitenamelist:
|
||||
rep = "include.*\/redirect\/.*\*.conf;"
|
||||
if not re.search(rep,ng_conf):
|
||||
ng_conf = ng_conf.replace("#SSL-END","#SSL-END\n\t%s\n\t" % public.GetMsg("NGINX_REDIRECT_REP") + "include " + ng_redirectfile + ";")
|
||||
ng_conf = ng_conf.replace("#SSL-END","#SSL-END\n\t%s\n\t" % public.get_msg_gettext('#referenced redirect rule, if commented, the configured redirect rule will be invalid') + "include " + ng_redirectfile + ";")
|
||||
public.writeFile(ng_file,ng_conf)
|
||||
|
||||
else:
|
||||
@@ -130,18 +130,18 @@ class panelRedirect:
|
||||
if os.path.exists(ap_file):
|
||||
ap_conf = public.readFile(ap_file)
|
||||
if p_conf == "[]":
|
||||
rep = "\n*%s\n+\s+IncludeOptiona[\s\w\/\.\*]+" % public.GetMsg("NGINX_REDIRECT_REP")
|
||||
rep = "\n*%s\n+\s+IncludeOptiona[\s\w\/\.\*]+" % public.get_msg_gettext('#referenced redirect rule, if commented, the configured redirect rule will be invalid')
|
||||
ap_conf = re.sub(rep, '', ap_conf)
|
||||
public.writeFile(ap_file, ap_conf)
|
||||
return
|
||||
if sitename in p_conf:
|
||||
rep = "%s(\n|.)+IncludeOptional.*\/redirect\/.*conf" % public.GetMsg("NGINX_REDIRECT_REP1")
|
||||
rep = "%s(\n|.)+IncludeOptional.*\/redirect\/.*conf" % public.get_msg_gettext('#referenced redirect rule')
|
||||
rep1 = "combined"
|
||||
if not re.search(rep,ap_conf):
|
||||
ap_conf = ap_conf.replace(rep1, rep1 + "\n\t%s" % public.GetMsg("NGINX_REDIRECT_REP") +"\n\tIncludeOptional " + ap_redirectfile)
|
||||
ap_conf = ap_conf.replace(rep1, rep1 + "\n\t%s" % public.get_msg_gettext('#referenced redirect rule, if commented, the configured redirect rule will be invalid') +"\n\tIncludeOptional " + ap_redirectfile)
|
||||
public.writeFile(ap_file,ap_conf)
|
||||
else:
|
||||
rep = "\n*%s\n+\s+IncludeOptiona[\s\w\/\.\*]+" % public.GetMsg("NGINX_REDIRECT_REP")
|
||||
rep = "\n*%s\n+\s+IncludeOptiona[\s\w\/\.\*]+" % public.get_msg_gettext('#referenced redirect rule, if commented, the configured redirect rule will be invalid')
|
||||
ap_conf = re.sub(rep,'', ap_conf)
|
||||
public.writeFile(ap_file, ap_conf)
|
||||
|
||||
@@ -149,52 +149,52 @@ class panelRedirect:
|
||||
def __CheckRedirectStart(self,get,action=""):
|
||||
isError = public.checkWebConfig()
|
||||
if (isError != True):
|
||||
return public.returnMsg(False, 'GET_ERR_IN_CONFILE')
|
||||
return public.return_msg_gettext(False, 'An error was detected in the configuration file. Please solve it before proceeding')
|
||||
if action == "create":
|
||||
#检测名称是否重复
|
||||
if sys.version_info.major < 3:
|
||||
if len(get.redirectname) < 3 or len(get.redirectname) > 15:
|
||||
return public.returnMsg(False, 'NAME_LEN')
|
||||
return public.return_msg_gettext(False, 'Database name cannot be more than 16 characters!')
|
||||
else:
|
||||
if len(get.redirectname.encode("utf-8")) < 3 or len(get.redirectname.encode("utf-8")) > 15:
|
||||
return public.returnMsg(False, 'NAME_LEN')
|
||||
return public.return_msg_gettext(False, 'Database name cannot be more than 16 characters!')
|
||||
if self.__CheckRedirect(get.sitename,get.redirectname):
|
||||
return public.returnMsg(False, 'REDIRECT_EXIST')
|
||||
return public.return_msg_gettext(False, 'Specified redirect name already exists')
|
||||
#检测是否选择域名
|
||||
if get.domainorpath == "domain":
|
||||
if not json.loads(get.redirectdomain):
|
||||
return public.returnMsg(False, 'SELECT_RED_DOMAIN')
|
||||
return public.return_msg_gettext(False, 'Please select redirected domain')
|
||||
else:
|
||||
if not get.redirectpath:
|
||||
return public.returnMsg(False, 'INPUT_RED_DOMAIN')
|
||||
return public.return_msg_gettext(False, 'Please enter redirected path')
|
||||
#repte = "[\?\=\[\]\)\(\*\&\^\%\$\#\@\!\~\`{\}\>\<\,\',\"]+"
|
||||
# 检测路径格式
|
||||
if "/" not in get.redirectpath:
|
||||
return public.returnMsg(False, "PATH_ERR")
|
||||
return public.return_msg_gettext(False, 'Path format is incorrect, the format is /xxx')
|
||||
#if re.search(repte, get.redirectpath):
|
||||
# return public.returnMsg(False, "代理目录不能有以下特殊符号 ?,=,[,],),(,*,&,^,%,$,#,@,!,~,`,{,},>,<,\,',\"]")
|
||||
# return public.return_msg_gettext(False, "代理目录不能有以下特殊符号 ?,=,[,],),(,*,&,^,%,$,#,@,!,~,`,{,},>,<,\,',\"]")
|
||||
#检测域名是否已经存在配置文件
|
||||
repeatdomain = self.__CheckRepeatDomain(get,action)
|
||||
if repeatdomain:
|
||||
return public.returnMsg(False, 'RED_DOMAIN_EXIST' , (repeatdomain,))
|
||||
return public.return_msg_gettext(False, 'Redirected domain already exists {}' , (repeatdomain,))
|
||||
#检测路径是否有存在配置文件
|
||||
repeatpath = self.__CheckRepeatPath(get)
|
||||
if repeatpath:
|
||||
return public.returnMsg(False, 'RED_DOMAIN_EXIST' , (repeatpath,))
|
||||
return public.return_msg_gettext(False, 'Redirected domain already exists {}' , (repeatpath,))
|
||||
#检测目标URL格式
|
||||
rep = "http(s)?\:\/\/([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z0-9][a-zA-Z0-9]{0,62})+.?"
|
||||
if not re.match(rep, get.tourl):
|
||||
return public.returnMsg(False, 'URL_FORMAT_ERR' ,(get.tourl,))
|
||||
return public.return_msg_gettext(False, 'The target URL format is incorrect {}' ,(get.tourl,))
|
||||
#检测目标URL是否可用
|
||||
#if self.__CheckRedirectUrl(get):
|
||||
# return public.returnMsg(False, '目标URL无法访问')
|
||||
# return public.return_msg_gettext(False, '目标URL无法访问')
|
||||
|
||||
#检查目标URL的域名和被重定向的域名是否一样
|
||||
if get.domainorpath == "domain":
|
||||
for d in json.loads(get.redirectdomain):
|
||||
tu = self.GetToDomain(get.tourl)
|
||||
if d == tu:
|
||||
return public.returnMsg(False,public.GetMsg("DOMAIN_SAMEAS_URL",(d,)))
|
||||
return public.return_msg_gettext(False,public.get_msg_gettext('Domain name {} is the same as the target domain name, please deselect it',(d,)))
|
||||
|
||||
if get.domainorpath == "path":
|
||||
domains = self.GetAllDomain(get.sitename)
|
||||
@@ -203,7 +203,7 @@ class panelRedirect:
|
||||
for d in domains:
|
||||
ad = "%s%s" % (d,get.redirectpath) #站点域名+重定向路径
|
||||
if tu == ad:
|
||||
return public.GetMsg("URL_SAMEAS_REDPATH",(tu,))
|
||||
return public.get_msg_gettext('{}, the target URL is the same as the redirected path',(tu,))
|
||||
#创建重定向
|
||||
def CreateRedirect(self,get):
|
||||
|
||||
@@ -226,7 +226,7 @@ class panelRedirect:
|
||||
self.SetRedirectApache(get.sitename)
|
||||
self.SetRedirect(get)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'CREATE_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Successfully created file!')
|
||||
|
||||
# 设置重定向
|
||||
def SetRedirect(self,get):
|
||||
@@ -331,7 +331,7 @@ class panelRedirect:
|
||||
for i in range(len(p_conf) - 1, -1, -1):
|
||||
if get.sitename == p_conf[i]["sitename"] and p_conf[i]["redirectname"]:
|
||||
del(p_conf[i])
|
||||
return public.returnMsg(False, '%s<br><a style="color:red;">' % public.GetMsg("HAVE_ERR") + isError.replace("\n",'<br>') + '</a>')
|
||||
return public.return_msg_gettext(False, '%s<br><a style="color:red;">' % public.get_msg_gettext('Sorry, something went wrong') + isError.replace("\n",'<br>') + '</a>')
|
||||
|
||||
else:
|
||||
redirectname_md5 = self.__calc_md5(get.redirectname)
|
||||
@@ -361,7 +361,7 @@ class panelRedirect:
|
||||
self.SetRedirectApache(get.sitename)
|
||||
if not hasattr(get,'notreload'):
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'EDIT_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Setup successfully!')
|
||||
|
||||
def del_redirect_multiple(self,get):
|
||||
'''
|
||||
@@ -384,9 +384,9 @@ class panelRedirect:
|
||||
continue
|
||||
del_successfully.append(redirectname)
|
||||
except:
|
||||
del_failed[redirectname]=public.getMsg('DEL_ERROR1')
|
||||
del_failed[redirectname]=public.get_msg_gettext('There was an error deleting, please try again.')
|
||||
public.serviceReload()
|
||||
return {'status': True, 'msg': public.getMsg('DEL_REDIRECT_MULTIPLE',(','.join(del_successfully),)), 'error': del_failed,
|
||||
return {'status': True, 'msg': public.get_msg_gettext('Delete redirects [{}] successfully',(','.join(del_successfully),)), 'error': del_failed,
|
||||
'success': del_successfully}
|
||||
|
||||
def DeleteRedirect(self,get,multiple=None):
|
||||
@@ -404,7 +404,7 @@ class panelRedirect:
|
||||
self.SetRedirectApache(get.sitename)
|
||||
if not multiple:
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True, 'DEL_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Successfully deleted')
|
||||
|
||||
def GetRedirectList(self,get):
|
||||
redirectconf = self.__read_config(self.__redirectfile)
|
||||
@@ -433,7 +433,7 @@ class panelRedirect:
|
||||
# get.redirectpath = "/"
|
||||
# get.redirectdomain = "[]"
|
||||
# get.sitename = sitename
|
||||
# get.redirectname = public.GetMsg("OLD_CONF")
|
||||
# get.redirectname = public.get_msg_gettext('Old configuration')
|
||||
# get.type = 1
|
||||
# get.holdpath = 1
|
||||
|
||||
@@ -470,7 +470,7 @@ class panelRedirect:
|
||||
conf = re.sub(rep, "", old_conf)
|
||||
public.writeFile(conf_path, conf)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(False, 'CLEAR_OLD_RED')
|
||||
return public.return_msg_gettext(False, 'Old redirection cleaned')
|
||||
|
||||
# 取重定向配置文件
|
||||
def GetRedirectFile(self,get):
|
||||
@@ -484,7 +484,7 @@ class panelRedirect:
|
||||
get.path = "%s/panel/vhost/%s/redirect/%s/%s_%s.conf" % (self.setupPath, get.webserver, sitename,proxyname_md5,sitename)
|
||||
for i in conf:
|
||||
if redirectname == i["redirectname"] and sitename == i["sitename"] and i["type"] != 1:
|
||||
return public.returnMsg(False, 'RED_ALREADY_STOP')
|
||||
return public.return_msg_gettext(False, 'Redirection suspended')
|
||||
f = files.files()
|
||||
return f.GetFileBody(get),get.path
|
||||
|
||||
@@ -493,7 +493,7 @@ class panelRedirect:
|
||||
import files
|
||||
f = files.files()
|
||||
return f.SaveFileBody(get)
|
||||
# return public.returnMsg(True, '保存成功')
|
||||
# return public.return_msg_gettext(True, '保存成功')
|
||||
|
||||
def __CheckRedirect(self,sitename,redirectname):
|
||||
conf_data = self.__read_config(self.__redirectfile)
|
||||
|
||||
+23
-23
@@ -20,7 +20,7 @@ class panelRun:
|
||||
__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 = '开机启动项'
|
||||
__log_name = 'Startup items'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
@@ -69,7 +69,7 @@ class panelRun:
|
||||
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,'启动配置不存在!')
|
||||
return public.return_msg_gettext(False,'Configuration file not exist')
|
||||
|
||||
run_info = json.loads(public.readFile(run_file))
|
||||
return run_info
|
||||
@@ -98,14 +98,14 @@ class panelRun:
|
||||
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))
|
||||
return public.return_msg_gettext(False,'The specified run directory {} does not exist!'.format(run_path))
|
||||
|
||||
if not re.match(r'^\w+$',run_name):
|
||||
return public.returnMsg(False, '启动项名称格式不正确,支持:[a-zA-Z0-9_]!')
|
||||
return public.return_msg_gettext(False, 'The startup item name format is incorrect, support: [a-zA-Z0-9_]!')
|
||||
|
||||
run_file = '{}/{}'.format(self.__run_config_path,run_name)
|
||||
if os.path.exists(run_file):
|
||||
return public.returnMsg(False,'启动配置已存在!')
|
||||
return public.return_msg_gettext(False,'Launch configuration already exists!')
|
||||
|
||||
run_info = {
|
||||
'run_title': run_title,
|
||||
@@ -117,8 +117,8 @@ class panelRun:
|
||||
}
|
||||
run_info = json.dumps(run_info)
|
||||
public.writeFile(run_file,run_info)
|
||||
public.WriteLog(self.__log_name,'创建启动项[]成功!'.format(run_title))
|
||||
return public.returnMsg(True,'创建成功!')
|
||||
public.write_log_gettext(self.__log_name,'Create startup item [] successful!'.format(run_title))
|
||||
return public.return_msg_gettext(True,'Successfully created')
|
||||
|
||||
|
||||
def modify_run(self,get):
|
||||
@@ -145,15 +145,15 @@ class panelRun:
|
||||
run_env = json.loads(get['run_env'])
|
||||
|
||||
if not os.path.exists(run_path):
|
||||
return public.returnMsg(False,'指定运行目录{}不存在!'.format(run_path))
|
||||
return public.return_msg_gettext(False,'The specified run directory {} does not exist!',(run_path,))
|
||||
|
||||
if not re.match(r'^\w+$',run_name):
|
||||
return public.returnMsg(False, '启动项名称格式不正确,支持:[a-zA-Z0-9_]!')
|
||||
return public.return_msg_gettext(False, 'The startup item name format is incorrect, support: [a-zA-Z0-9_]!')
|
||||
|
||||
|
||||
run_file = '{}/{}'.format(self.__run_config_path,run_name)
|
||||
if not os.path.exists(run_file):
|
||||
return public.returnMsg(False,'启动配置不存在!')
|
||||
return public.return_msg_gettext(False,'The launch configuration does not exist!')
|
||||
|
||||
run_info = json.loads(public.readFile(run_file))
|
||||
run_info['run_title'] = run_title
|
||||
@@ -162,8 +162,8 @@ class panelRun:
|
||||
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,'修改成功!')
|
||||
public.write_log_gettext(self.__log_name,'Modify startup item [{}] successful!',(run_title,))
|
||||
return public.return_msg_gettext(True,'Successfully modified')
|
||||
|
||||
|
||||
def remove_run(self,get):
|
||||
@@ -178,11 +178,11 @@ class panelRun:
|
||||
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,'启动配置不存在!')
|
||||
return public.return_msg_gettext(False,'The launch configuration does not exist!')
|
||||
|
||||
os.remove(run_file)
|
||||
public.WriteLog(self.__log_name,'删除启动项[]成功!'.format(run_name))
|
||||
return public.returnMsg(True,'删除成功!')
|
||||
public.write_log_gettext(self.__log_name,'Delete startup item [{}] successful!',(run_name,))
|
||||
return public.return_msg_gettext(True,'successfully deleted')
|
||||
|
||||
def set_run_status(self,get):
|
||||
'''
|
||||
@@ -199,14 +199,14 @@ class panelRun:
|
||||
|
||||
run_file = '{}/{}'.format(self.__run_config_path,run_name)
|
||||
if not os.path.isfile(run_file):
|
||||
return public.returnMsg(False,'启动配置不存在!')
|
||||
return public.return_msg_gettext(False,'launch configuration does not exist!')
|
||||
|
||||
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,'设置成功!')
|
||||
public.write_log_gettext(self.__log_name,'Setting startup item [{}] status succeeded!',(run_info['title'],))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
def stop_run(self,run_name = None):
|
||||
@@ -219,7 +219,7 @@ class panelRun:
|
||||
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))
|
||||
public.write_log_gettext(self.__log_name,'Close startup item [{}] successful!',(run_name,))
|
||||
return True
|
||||
|
||||
|
||||
@@ -267,9 +267,9 @@ class panelRun:
|
||||
@return dict
|
||||
'''
|
||||
pid = self.get_run_pid(run_name)
|
||||
if not pid: return public.returnMsg(False,'未启动')
|
||||
if not pid: return public.return_msg_gettext(False,'Not run')
|
||||
process_info = self.get_process_info(pid)
|
||||
if not process_info: return public.returnMsg(False,'无法获取进程信息')
|
||||
if not process_info: return public.return_msg_gettext(False,'Unable to get process information')
|
||||
return process_info
|
||||
|
||||
def get_process_info(self,pid):
|
||||
@@ -281,7 +281,7 @@ class panelRun:
|
||||
'''
|
||||
process_info = {}
|
||||
p = psutil.Process(pid)
|
||||
status_ps = {'sleeping':'睡眠','running':'活动'}
|
||||
status_ps = {'sleeping':'sleeping','running':'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
|
||||
@@ -368,7 +368,7 @@ class panelRun:
|
||||
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))
|
||||
public.write_log_gettext(self.__log_name, 'Startup {} successful, PID:{}',(run_name,pid,))
|
||||
return True
|
||||
|
||||
|
||||
|
||||
+39
-39
@@ -20,7 +20,7 @@ try:
|
||||
except:
|
||||
pass
|
||||
class panelSSL:
|
||||
__APIURL = 'https://brandnew.aapanel.com/api/user'
|
||||
__APIURL = 'https://www.aapanel.com/api/user'
|
||||
__APIURL2 = 'http://www.bt.cn/api/Cert'
|
||||
__UPATH = 'data/userInfo.json'
|
||||
__PUBKEY = 'data/public.key'
|
||||
@@ -65,13 +65,13 @@ class panelSSL:
|
||||
userinfo['token'] = result['res']['access_token']
|
||||
public.writeFile(self.__UPATH, json.dumps(userinfo))
|
||||
session['focre_cloud'] = True
|
||||
return public.returnMsg(True,'Bind successfully')
|
||||
return public.return_msg_gettext(True,'Bind successfully')
|
||||
else:
|
||||
return public.returnMsg(False,'Invalid username or email or password! please check and try again!')
|
||||
return public.return_msg_gettext(False,'Invalid username or email or password! please check and try again!')
|
||||
except Exception as ex:
|
||||
bind = 'data/bind.pl'
|
||||
if os.path.exists(bind): os.remove(bind)
|
||||
return public.returnMsg(False, '%s<br>%s' % (public.GetMsg("CONNECT_ERR"), str(rtmp)))
|
||||
return public.return_msg_gettext(False, '%s<br>%s' % (public.get_msg_gettext('Failed to connect server!'), str(rtmp)))
|
||||
|
||||
#删除Token
|
||||
def DelToken(self,get):
|
||||
@@ -83,7 +83,7 @@ class panelSSL:
|
||||
public.ExecShell("rm -f " + self.__UPATH)
|
||||
session['focre_cloud'] = True
|
||||
|
||||
return public.returnMsg(True,"SSL_BTUSER_UN")
|
||||
return public.return_msg_gettext(True,'Unbound!')
|
||||
|
||||
#获取用户信息
|
||||
def GetUserInfo(self,get):
|
||||
@@ -93,19 +93,19 @@ class panelSSL:
|
||||
userTmp = {}
|
||||
userTmp['username'] = self.__userInfo['email'][0:3]+'****'+self.__userInfo['email'][-4:]
|
||||
result['status'] = True
|
||||
result['msg'] = public.getMsg('SSL_GET_SUCCESS')
|
||||
result['msg'] = public.get_msg_gettext('Got successfully!')
|
||||
result['data'] = userTmp
|
||||
else:
|
||||
userTmp = {}
|
||||
userTmp['username'] = public.getMsg('SSL_NOT_BTUSER')
|
||||
userTmp['username'] = public.get_msg_gettext('Please bind your account!')
|
||||
result['status'] = False
|
||||
result['msg'] = public.getMsg('SSL_NOT_BTUSER')
|
||||
result['msg'] = public.get_msg_gettext('Please bind your account!')
|
||||
result['data'] = userTmp
|
||||
except:
|
||||
userTmp = {}
|
||||
userTmp['username'] = public.getMsg('SSL_NOT_BTUSER')
|
||||
userTmp['username'] = public.get_msg_gettext('Please bind your account!')
|
||||
result['status'] = False
|
||||
result['msg'] = public.getMsg('SSL_NOT_BTUSER')
|
||||
result['msg'] = public.get_msg_gettext('Please bind your account!')
|
||||
result['data'] = userTmp
|
||||
return result
|
||||
|
||||
@@ -153,7 +153,7 @@ class panelSSL:
|
||||
import panelSite
|
||||
panelSite.panelSite().SetSSLConf(get)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
#生成商业证书支付订单
|
||||
def apply_order_pay(self,args):
|
||||
@@ -311,7 +311,7 @@ class panelSSL:
|
||||
verify_info['paths'] = []
|
||||
verify_info['hosts'] = []
|
||||
if verify_info['data']['application']['status'] == 'ongoing':
|
||||
return public.returnMsg(False,'订单出现问题,CA正在人工验证,若24小时内依然出现此提示,请联系宝塔')
|
||||
return public.return_msg_gettext(False,'订单出现问题,CA正在人工验证,若24小时内依然出现此提示,请联系宝塔')
|
||||
for dinfo in verify_info['data']['dcvList']:
|
||||
is_https = dinfo['dcvMethod'] == 'HTTPS_CSR_HASH'
|
||||
if is_https:
|
||||
@@ -356,7 +356,7 @@ class panelSSL:
|
||||
#发送请求
|
||||
def request(self,dname):
|
||||
self.__PDATA['data'] = json.dumps(self.__PDATA['data'])
|
||||
result= public.returnMsg(False,'The request failed, please try again later!')
|
||||
result= public.return_msg_gettext(False,'The request failed, please try again later!')
|
||||
try:
|
||||
result = public.httpPost(self.__APIURL2 + '/' + dname,self.__PDATA)
|
||||
result = json.loads(result)
|
||||
@@ -378,7 +378,7 @@ class panelSSL:
|
||||
rs = public.httpPost(self.__APIURL + '/GetSSLList',self.__PDATA)
|
||||
try:
|
||||
result = json.loads(rs)
|
||||
except: return public.returnMsg(False,'SSL_ORDER_GET_FAILED')
|
||||
except: return public.return_msg_gettext(False,'Failed to get, please try again later!')
|
||||
|
||||
result['data'] = self.En_Code(result['data'])
|
||||
for i in range(len(result['data'])):
|
||||
@@ -408,11 +408,11 @@ class panelSSL:
|
||||
#当申请二级域名为www时,检测主域名是否绑定到同一网站
|
||||
if get.domain[:4] == 'www.':
|
||||
if not public.M('domain').where('name=? AND pid=?',(get.domain[4:],get.id)).count():
|
||||
return public.returnMsg(False,"Apply for [%s] certificate to verify [%s] Please bind [%s] and resolve to the site!" % (get.domain,get.domain[4:],get.domain[4:]))
|
||||
return public.return_msg_gettext(False,"Apply for [{}] certificate to verify [{}] Please bind [{}] and resolve to the site!",(get.domain,get.domain[4:],get.domain[4:]))
|
||||
|
||||
#检测是否开启强制HTTPS
|
||||
if not self.CheckForceHTTPS(get.siteName):
|
||||
return public.returnMsg(False,'SSL_ORDER_HTTPS_ERR')
|
||||
return public.return_msg_gettext(False,'[Force HTTPS] is enabled on the current website, please turn off this function before applying for an SSL certificate!')
|
||||
|
||||
#获取真实网站运行目录
|
||||
runPath = self.GetRunPath(get)
|
||||
@@ -423,19 +423,19 @@ class panelSSL:
|
||||
authfile = get.path + '/.well-known/pki-validation/fileauth.txt'
|
||||
if not self.CheckDomain(get):
|
||||
if not os.path.exists(authfile):
|
||||
return public.returnMsg(False,'CANT_CREATE',(authfile,))
|
||||
return public.return_msg_gettext(False,'Cannot create [{}]',(authfile,))
|
||||
else:
|
||||
msg = '''{err_msg}<br><a class="btlink" href="{c_url}" target="_blank">{c_url}</a> <br><br>
|
||||
<p></b>{err_msg1}</b></p>
|
||||
{err_msg2}<br>
|
||||
{err_msg3}<br>
|
||||
{err_msg4}'''.format(c_url = self._check_url,
|
||||
err_msg=public.getMsg('SSL_ERR_MSG'),
|
||||
err_msg1=public.getMsg('SSL_ERR_MSG1'),
|
||||
err_msg2=public.getMsg('SSL_ERR_MSG2'),
|
||||
err_msg3=public.getMsg('SSL_ERR_MSG3'),
|
||||
err_msg4=public.getMsg('SSL_ERR_MSG4'))
|
||||
return public.returnMsg(False,msg)
|
||||
err_msg=public.get_msg_gettext('Cannot access verification file correctly'),
|
||||
err_msg1=public.get_msg_gettext('Possible reason:'),
|
||||
err_msg2=public.get_msg_gettext('1. The resolution is not correct, or the resolution is not effective [Please resolve the domain name correctly, or wait for the resolution to take effect and try again]'),
|
||||
err_msg3=public.get_msg_gettext('2. Check if there is 301/302 redirection set up [please temporarily turn off the redirection related configuration]'),
|
||||
err_msg4=public.get_msg_gettext('3. Check whether the website is set to force HTTPS [please turn off the force HTTPS function temporarily]'))
|
||||
return public.return_msg_gettext(False,msg)
|
||||
|
||||
action = 'GetDVSSL'
|
||||
if hasattr(get,'partnerOrderId'):
|
||||
@@ -523,7 +523,7 @@ class panelSSL:
|
||||
try:
|
||||
sslInfo = json.loads(tmp)
|
||||
except:
|
||||
return public.returnMsg(False,tmp)
|
||||
return public.return_msg_gettext(False,tmp)
|
||||
|
||||
sslInfo['data'] = self.En_Code(sslInfo['data'])
|
||||
try:
|
||||
@@ -531,13 +531,13 @@ class panelSSL:
|
||||
if not os.path.exists(spath): public.ExecShell("mkdir -p '" + spath + "'")
|
||||
public.writeFile(spath + '/fileauth.txt',sslInfo['data']['authValue'])
|
||||
except:
|
||||
return public.returnMsg(False,'SSL_CHECK_WRITE_ERR')
|
||||
return public.return_msg_gettext(False,'Verification error!')
|
||||
try:
|
||||
result = json.loads(public.httpPost(self.__APIURL + '/Completed',self.__PDATA))
|
||||
if 'data' in result:
|
||||
result['data'] = self.En_Code(result['data'])
|
||||
except:
|
||||
result = public.returnMsg(True,'CHECKING')
|
||||
result = public.return_msg_gettext(True,'Checking...')
|
||||
n = 0;
|
||||
my_ok = False
|
||||
while True:
|
||||
@@ -598,9 +598,9 @@ class panelSSL:
|
||||
import panelSite
|
||||
panelSite.panelSite().SetSSLConf(get)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
except:
|
||||
return public.returnMsg(False,'SET_ERROR')
|
||||
return public.return_msg_gettext(False,'Failed to set')
|
||||
result['data'] = self.En_Code(result['data'])
|
||||
return result
|
||||
|
||||
@@ -632,9 +632,9 @@ class panelSSL:
|
||||
import panelSite
|
||||
panelSite.panelSite().SetSSLConf(get)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
except Exception as ex:
|
||||
return public.returnMsg(False,'SET_ERROR,' + public.get_error_info())
|
||||
return public.return_msg_gettext(False,'Failed to set \n{}',(public.get_error_info(),))
|
||||
|
||||
#获取证书列表
|
||||
def GetCertList(self,get):
|
||||
@@ -657,17 +657,17 @@ class panelSSL:
|
||||
def RemoveCert(self,get):
|
||||
try:
|
||||
vpath = '/www/server/panel/vhost/ssl/' + get.certName.replace("*.",'')
|
||||
if not os.path.exists(vpath): return public.returnMsg(False,'CRET_NOT_EXIST')
|
||||
if not os.path.exists(vpath): return public.return_msg_gettext(False,'Certificate does NOT exist!')
|
||||
public.ExecShell("rm -rf " + vpath)
|
||||
return public.returnMsg(True,'CRET_DEL')
|
||||
return public.return_msg_gettext(True,'Certificate deleted!')
|
||||
except:
|
||||
return public.returnMsg(False,'CRET_DEL_FAIL')
|
||||
return public.return_msg_gettext(False,'Failed to delete!')
|
||||
|
||||
#保存证书
|
||||
def SaveCert(self,get):
|
||||
try:
|
||||
certInfo = self.GetCertName(get)
|
||||
if not certInfo: return public.returnMsg(False,'CRET_RESOLVE_FAIL')
|
||||
if not certInfo: return public.return_msg_gettext(False,'Certificate parsing failed')
|
||||
vpath = '/www/server/panel/vhost/ssl/' + certInfo['subject']
|
||||
vpath=vpath.replace("*.",'')
|
||||
if not os.path.exists(vpath):
|
||||
@@ -675,14 +675,14 @@ class panelSSL:
|
||||
public.writeFile(vpath + '/privkey.pem',public.readFile(get.keyPath))
|
||||
public.writeFile(vpath + '/fullchain.pem',public.readFile(get.certPath))
|
||||
public.writeFile(vpath + '/info.json',json.dumps(certInfo))
|
||||
return public.returnMsg(True,'CRET_SAVE_SUSSESS')
|
||||
return public.return_msg_gettext(True,'Successfully saved certificate!')
|
||||
except:
|
||||
return public.returnMsg(False,'CRET_SAVE_FAIL')
|
||||
return public.return_msg_gettext(False,'Failed to save certificate!')
|
||||
|
||||
#读取证书
|
||||
def GetCert(self,get):
|
||||
vpath = os.path.join('/www/server/panel/vhost/ssl' , get.certName.replace("*.",''))
|
||||
if not os.path.exists(vpath): return public.returnMsg(False,'CRET_NOT_EXIST')
|
||||
if not os.path.exists(vpath): return public.return_msg_gettext(False,'Certificate does NOT exist!')
|
||||
data = {}
|
||||
data['privkey'] = public.readFile(vpath + '/privkey.pem')
|
||||
data['fullchain'] = public.readFile(vpath + '/fullchain.pem')
|
||||
@@ -822,13 +822,13 @@ class panelSSL:
|
||||
# 手动一键续签
|
||||
def renew_lets_ssl(self, get):
|
||||
if not os.path.exists('vhost/cert/crontab.json'):
|
||||
return public.returnMsg(False,'SSL_RENEW_ERR')
|
||||
return public.return_msg_gettext(False,'There are currently no certificates to renew!')
|
||||
|
||||
old_list = json.loads(public.ReadFile("vhost/cert/crontab.json"))
|
||||
cron_list = old_list
|
||||
if hasattr(get, 'siteName'):
|
||||
if not get.siteName in old_list:
|
||||
return public.returnMsg(False,'WEBSITE_SSL_RENEW_ERR')
|
||||
return public.return_msg_gettext(False,'There is no certificate that can be renewed on the current website..')
|
||||
cron_list = {}
|
||||
cron_list[get.siteName] = old_list[get.siteName]
|
||||
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ class safe:
|
||||
|
||||
def checkPHPINI(self):
|
||||
setupPath = '/www/server';
|
||||
phps = ['52','53','54','55','56','70','71']
|
||||
phps = public.get_php_versions()
|
||||
rep = "disable_functions\s*=\s*(.+)\n"
|
||||
defs = ['passthru','exec','system','chroot','chgrp','chown','shell_exec','popen','ini_alter','ini_restore','dl','openlog','syslog','readlink','symlink','popepassthru']
|
||||
data = []
|
||||
|
||||
@@ -189,10 +189,10 @@ class panelSearch:
|
||||
noword 1 不输出行信息 0 默认
|
||||
'''
|
||||
def get_search(self, args):
|
||||
if 'text' not in args or not args.text: return {'error': 'Search content cannot be empty'}
|
||||
if 'exts' not in args or not args.exts: return {'error': 'The suffix cannot be empty; please enter [ *.* ] to search all files'}
|
||||
if 'path' not in args or not args.path or args.path == '/': return {'error': 'The directory cannot be empty or /'}
|
||||
if not os.path.isdir(args.path): return {'error': 'Directory does not exist'}
|
||||
if 'text' not in args or not args.text: return {'error': public.get_msg_gettext('Search content cannot be empty')}
|
||||
if 'exts' not in args or not args.exts: return {'error': public.get_msg_gettext('The suffix cannot be empty; please enter [ *.* ] to search all files')}
|
||||
if 'path' not in args or not args.path or args.path == '/': return {'error': public.get_msg_gettext('The directory cannot be empty or /')}
|
||||
if not os.path.isdir(args.path): return {'error': public.get_msg_gettext('Directory does not exist')}
|
||||
text=args.text
|
||||
exts=args.exts
|
||||
path=args.path
|
||||
@@ -217,11 +217,11 @@ class panelSearch:
|
||||
noword 1 不输出行信息 0 默认
|
||||
'''
|
||||
def get_replace(self, args):
|
||||
if 'text' not in args or not args.text: return {'error': 'Search content cannot be empty'}
|
||||
if 'rtext' not in args or not args.text: return {'error': 'The content to be replaced cannot be empty'}
|
||||
if 'exts' not in args or not args.exts: return {'error': 'The suffix cannot be empty; please enter [ *.* ] to search all files'}
|
||||
if 'path' not in args or not args.path or args.path == '/': return {'error': 'The directory cannot be empty or /'}
|
||||
if not os.path.isdir(args.path): return {'error': 'Directory does not exist'}
|
||||
if 'text' not in args or not args.text: return {'error': public.get_msg_gettext('Search content cannot be empty')}
|
||||
if 'rtext' not in args or not args.text: return {'error': public.get_msg_gettext('The content to be replaced cannot be empty')}
|
||||
if 'exts' not in args or not args.exts: return {'error': public.get_msg_gettext('The suffix cannot be empty; please enter [ *.* ] to search all files')}
|
||||
if 'path' not in args or not args.path or args.path == '/': return {'error': public.get_msg_gettext('The directory cannot be empty or /')}
|
||||
if not os.path.isdir(args.path): return {'error': public.get_msg_gettext('Directory does not exist')}
|
||||
is_backup = int(args.isbackup) if 'isbackup' in args else 0
|
||||
text = args.text
|
||||
rtext = args.rtext
|
||||
|
||||
+710
-318
File diff suppressed because it is too large
Load Diff
+20
-19
@@ -140,7 +140,7 @@ class bt_task:
|
||||
"kill -9 $(ps aux|grep '"+task_info['shell']+"'|grep -v grep|awk '{print $2}')")
|
||||
|
||||
public.ExecShell("/etc/init.d/bt start")
|
||||
return public.returnMsg(True, 'TASK_CANCEL')
|
||||
return public.return_msg_gettext(True, 'Task cancelled!')
|
||||
|
||||
# 取一条任务
|
||||
def get_task_find(self, id):
|
||||
@@ -187,7 +187,6 @@ class bt_task:
|
||||
self.backup_site(task_shell, log_file)
|
||||
elif task_type == 7: # 恢复网站
|
||||
pass
|
||||
|
||||
# 标记状态与结束时间
|
||||
self.modify_task(id, 'status', 1)
|
||||
self.modify_task(id, 'endtime', int(time.time()))
|
||||
@@ -235,7 +234,7 @@ class bt_task:
|
||||
if not os.path.exists(log_file):
|
||||
data = ''
|
||||
if(task_type == '1'):
|
||||
data = {'name': public.GetMsg("DOWNLOAD_FILE"), 'total': 0, 'used': 0,
|
||||
data = {'name': public.get_msg_gettext('Download file'), 'total': 0, 'used': 0,
|
||||
'pre': 0, 'speed': 0, 'time': 0}
|
||||
return data
|
||||
|
||||
@@ -262,7 +261,7 @@ class bt_task:
|
||||
speed_total = re.findall(
|
||||
r"([\d\.]+[BbKkMmGg]).+\s+(\d+)%\s+([\d\.]+[KMBGkmbg])\s+(\w+[sS])", speed_tmp)
|
||||
if not speed_total:
|
||||
data = {'name':public.getMsg('DOWNLOAD_FILE1',(filename,)),'total':0,'used':0,'pre':0,'speed':0,'time':0}
|
||||
data = {'name':public.get_msg_gettext('Download file {}',(filename,)),'total':0,'used':0,'pre':0,'speed':0,'time':0}
|
||||
else:
|
||||
speed_total = speed_total[0]
|
||||
used = speed_total[0]
|
||||
@@ -271,11 +270,13 @@ class bt_task:
|
||||
float(speed_total[0].lower().replace('k', '')) * 1024)
|
||||
u_time = speed_total[3].replace(
|
||||
'h', 'Hour').replace('m', 'Minute').replace('s', 'Second')
|
||||
data = {'name': public.getMsg('DOWNLOAD_FILE1',(filename,)),'total': total, 'used': used, 'pre': speed_total[1], 'speed': speed_total[2], 'time': u_time}
|
||||
data = {'name': public.get_msg_gettext('Download file {}',(filename,)),'total': total, 'used': used, 'pre': speed_total[1], 'speed': speed_total[2], 'time': u_time}
|
||||
else:
|
||||
data = public.ExecShell("tail -n {} {}".format(num, log_file))[0]
|
||||
if type(data) == list:
|
||||
return ''
|
||||
if isinstance(data,bytes):
|
||||
data = data.decode('utf-8')
|
||||
data = data.replace('\x08', '').replace('\n', '<br>')
|
||||
return data
|
||||
|
||||
@@ -303,7 +304,7 @@ class bt_task:
|
||||
path = path.encode('utf-8')
|
||||
if sfile.find(',') == -1:
|
||||
if not os.path.exists(path+'/'+sfile):
|
||||
return public.returnMsg(False, 'FILE_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Configuration file not exist')
|
||||
# 处理多文件压缩
|
||||
sfiles = ''
|
||||
for sfile in sfile.split(','):
|
||||
@@ -325,11 +326,11 @@ class bt_task:
|
||||
public.ExecShell("cd '" + path + "' && "+rar_file +
|
||||
" a -r '" + dfile + "' " + sfiles + " &> " + log_file)
|
||||
else:
|
||||
return public.returnMsg(False,'NOT_SUP_COMP_FORMAT')
|
||||
return public.return_msg_gettext(False,'Specified compression format is not supported!')
|
||||
|
||||
self.set_file_accept(dfile)
|
||||
#public.WriteLog("TYPE_FILE", 'ZIP_SUCCESS', (sfiles, dfile),not_web = self.not_web)
|
||||
return public.returnMsg(True, 'ZIP_SUCCESS')
|
||||
#public.WriteLog("TYPE_FILE", 'Compression succeeded!', (sfiles, dfile),not_web = self.not_web)
|
||||
return public.return_msg_gettext(True, 'Compression succeeded!')
|
||||
|
||||
# 文件解压
|
||||
def _unzip(self, sfile, dfile, password, log_file):
|
||||
@@ -337,7 +338,7 @@ class bt_task:
|
||||
sfile = sfile.encode('utf-8')
|
||||
dfile = dfile.encode('utf-8')
|
||||
if not os.path.exists(sfile):
|
||||
return public.returnMsg(False, 'FILE_NOT_EXISTS')
|
||||
return public.return_msg_gettext(False, 'Configuration file not exist')
|
||||
|
||||
# 判断压缩包格式
|
||||
if sfile[-4:] == '.zip':
|
||||
@@ -372,8 +373,8 @@ class bt_task:
|
||||
user = pwd.getpwuid(os.stat(dfile).st_uid).pw_name
|
||||
public.ExecShell("chown %s:%s %s" % (user, user, dfile))
|
||||
|
||||
#public.WriteLog("TYPE_FILE", 'UNZIP_SUCCESS', (sfile, dfile),not_web = self.not_web)
|
||||
return public.returnMsg(True, 'UNZIP_SUCCESS')
|
||||
#public.WriteLog("TYPE_FILE", 'Uncompression succeeded!', (sfile, dfile),not_web = self.not_web)
|
||||
return public.return_msg_gettext(True, 'Uncompression succeeded!')
|
||||
|
||||
# 备份网站
|
||||
def backup_site(self, id, log_file):
|
||||
@@ -395,7 +396,7 @@ class bt_task:
|
||||
sql = public.M('backup').add('type,name,pid,filename,size,addtime',
|
||||
(0, fileName, find['id'], zipName, 0, public.getDate()))
|
||||
public.WriteLog('TYPE_SITE', 'SITE_BACKUP_SUCCESS', (find['name'],),not_web = self.not_web)
|
||||
return public.returnMsg(True, 'BACKUP_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Backup Succeeded!')
|
||||
|
||||
# 备份数据库
|
||||
def backup_database(self, id, log_file):
|
||||
@@ -413,7 +414,7 @@ class bt_task:
|
||||
public.ExecShell("/www/server/mysql/bin/mysqldump --force --opt \"" +
|
||||
name + "\" | gzip > " + backupName)
|
||||
if not os.path.exists(backupName):
|
||||
return public.returnMsg(False, 'BACKUP_ERROR')
|
||||
return public.return_msg_gettext(False, 'Backup error!')
|
||||
|
||||
self.mypass(False, find['mysql_root'])
|
||||
|
||||
@@ -422,7 +423,7 @@ class bt_task:
|
||||
sql.add('type,name,pid,filename,size,addtime',
|
||||
(1, fileName, id, backupName, 0, addTime))
|
||||
public.WriteLog("TYPE_DATABASE", "DATABASE_BACKUP_SUCCESS", (name,),not_web = self.not_web)
|
||||
return public.returnMsg(True, 'BACKUP_SUCCESS')
|
||||
return public.return_msg_gettext(True, 'Backup Succeeded!')
|
||||
|
||||
# 导入数据库
|
||||
def input_database(self, id, file, log_file):
|
||||
@@ -432,7 +433,7 @@ class bt_task:
|
||||
exts = ['sql', 'gz', 'zip']
|
||||
ext = tmp[len(tmp) - 1]
|
||||
if ext not in exts:
|
||||
return public.returnMsg(False, 'DATABASE_INPUT_ERR_FORMAT')
|
||||
return public.return_msg_gettext(False, 'Select sql/gz/zip file!')
|
||||
|
||||
isgzip = False
|
||||
if ext != 'sql':
|
||||
@@ -454,7 +455,7 @@ class bt_task:
|
||||
isgzip = True
|
||||
|
||||
if not os.path.exists(backupPath + '/' + tmpFile) or tmpFile == '':
|
||||
return public.returnMsg(False, 'FILE_NOT_EXISTS', (tmpFile,))
|
||||
return public.return_msg_gettext(False, 'Configuration file not exist', (tmpFile,))
|
||||
self.mypass(True, root)
|
||||
public.ExecShell(public.GetConfigValue('setup_path') + "/mysql/bin/mysql -uroot -p" +
|
||||
root + " --force \"" + name + "\" < " + backupPath + '/' + tmpFile)
|
||||
@@ -470,8 +471,8 @@ class bt_task:
|
||||
'setup_path') + "/mysql/bin/mysql -uroot -p" + root + " --force \"" + name + "\" < " + file)
|
||||
self.mypass(False, root)
|
||||
|
||||
public.WriteLog("TYPE_DATABASE", 'DATABASE_INPUT_SUCCESS', (name,),not_web = self.not_web)
|
||||
return public.returnMsg(True, 'DATABASE_INPUT_SUCCESS')
|
||||
public.WriteLog("TYPE_DATABASE", 'Successfully imported database [{}]', (name,),not_web = self.not_web)
|
||||
return public.return_msg_gettext(True, 'Successfully imported database!')
|
||||
|
||||
# 配置
|
||||
def mypass(self, act, root):
|
||||
|
||||
+1
-7
@@ -18,14 +18,8 @@ from BTPanel import Response
|
||||
|
||||
def get_buff_size(file_size):
|
||||
buff_size = 2097152
|
||||
if file_size < 104857600:
|
||||
buff_size = 2097152
|
||||
elif file_size < 524288000:
|
||||
if file_size > 1073741824:
|
||||
buff_size = 4194304
|
||||
elif file_size < 1073741824:
|
||||
buff_size = 8388608
|
||||
else:
|
||||
buff_size = 10485760
|
||||
return buff_size
|
||||
|
||||
def partial_response(path, start, end=None):
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/python
|
||||
#coding: utf-8
|
||||
# Author: <lkqiang>lkq@bt.cn
|
||||
# Author: lkqiang<lkq@bt.cn>
|
||||
# panelWaf.py
|
||||
# code: 面板基础安全类
|
||||
# +-------------------------------------------------------------------
|
||||
|
||||
+18
-14
@@ -48,21 +48,25 @@ class panelWarning:
|
||||
}
|
||||
result_file = self.__result + '/' + m_name + '.pl'
|
||||
|
||||
not_force = True
|
||||
if 'force' in args:
|
||||
not_force = m_info['ignore']
|
||||
# not_force = True
|
||||
# if 'force' in args:
|
||||
# not_force = m_info['ignore']
|
||||
|
||||
if os.path.exists(result_file) and not_force:
|
||||
m_info['status'],m_info['msg'],m_info['check_time'],m_info['taking'] = json.loads(public.readFile(result_file))
|
||||
else:
|
||||
try:
|
||||
s_time = time.time()
|
||||
m_info['status'],m_info['msg'] = p[m_name].check_run()
|
||||
m_info['taking'] = round(time.time() - s_time,6)
|
||||
m_info['check_time'] = int(time.time())
|
||||
public.writeFile(result_file,json.dumps([m_info['status'],m_info['msg'],m_info['check_time'],m_info['taking']],))
|
||||
except:
|
||||
continue
|
||||
# if os.path.exists(result_file) and not_force:
|
||||
# try:
|
||||
# m_info['status'],m_info['msg'],m_info['check_time'],m_info['taking'] = json.loads(public.readFile(result_file))
|
||||
# except:
|
||||
# if os.path.exists(result_file): os.remove(result_file)
|
||||
# continue
|
||||
# else:
|
||||
try:
|
||||
s_time = time.time()
|
||||
m_info['status'],m_info['msg'] = p[m_name].check_run()
|
||||
m_info['taking'] = round(time.time() - s_time,6)
|
||||
m_info['check_time'] = int(time.time())
|
||||
public.writeFile(result_file,json.dumps([m_info['status'],m_info['msg'],m_info['check_time'],m_info['taking']],))
|
||||
except:
|
||||
continue
|
||||
|
||||
|
||||
if m_info['ignore']:
|
||||
|
||||
@@ -60,7 +60,7 @@ class panel_restore:
|
||||
# 判断备份文件是否存在,如果不存在继续检查是否远程备份
|
||||
if not os.path.exists(local_backup_file_path):
|
||||
self._progress_rewrite('No backup file found: {}'.format(str(local_backup_file_path)))
|
||||
return public.returnMsg(False, 'Panel does not find the backup file: {}'.format(local_backup_file_path))
|
||||
return public.return_msg_gettext(False, 'Panel does not find the backup file: {}'.format(local_backup_file_path))
|
||||
# 将网站目录移至回收站
|
||||
self._progress_rewrite('Move the current website directory to the recycle bin: {}'.format(str(args.path)))
|
||||
self._remove_old_website_file_to_trush(args)
|
||||
@@ -158,14 +158,14 @@ class panel_restore:
|
||||
self._download_google_drive_file(args)
|
||||
result = self._restore_backup(self._local_file, site_info, args)
|
||||
else:
|
||||
return public.ExecShell(False,'Currently only supports restoring local, Google storage and AWS S3 backups')
|
||||
return public.return_msg_gettext(False,'Currently only supports restoring local, Google storage and AWS S3 backups')
|
||||
if os.path.exists(self._local_file):
|
||||
os.remove(self._local_file)
|
||||
if result:
|
||||
self._progress_rewrite('Recovery failed: {}'.format(str(site_info['site_path'])))
|
||||
return result
|
||||
self._progress_rewrite('Successful recovery: {}'.format(str(site_info['site_path'])))
|
||||
return public.returnMsg(True,'Restore Successful')
|
||||
return public.return_msg_gettext(True,'Restore Successful')
|
||||
|
||||
# 取任务进度
|
||||
def get_progress(self, get):
|
||||
@@ -187,6 +187,8 @@ class panel_restore:
|
||||
@parma file_name 备份得文件名 /www/backup/database/db_test_com_20200817_112722.sql.gz|Google Drive|db_test_com_20200817_112722.sql.gz
|
||||
@parma obj_name 数据库名
|
||||
"""
|
||||
if "|" not in args.file:
|
||||
return public.returnMsg(True,'success')
|
||||
try:
|
||||
backup_info = args.file.split('|')
|
||||
args.file_name = backup_info[-1]
|
||||
@@ -202,7 +204,8 @@ class panel_restore:
|
||||
elif backup_method == 'Google Drive':
|
||||
self._download_google_drive_file(args)
|
||||
else:
|
||||
return public.ExecShell(False,'Currently only supports restoring local, Google storage and AWS S3 backups')
|
||||
return public.returnMsg(False,'Currently only supports restoring local, Google storage and AWS S3 backups')
|
||||
public.ExecShell('mv {} {}/database'.format(self._local_file, self._get_local_backup_path()))
|
||||
return public.returnMsg(True,'success')
|
||||
except:
|
||||
return False
|
||||
return public.returnMsg(False,"Download error!")
|
||||
|
||||
@@ -17,7 +17,7 @@ pip = public.get_pip_bin()
|
||||
try:
|
||||
import telegram
|
||||
except:
|
||||
public.ExecShell('{} install telegram'.format(pip))
|
||||
public.ExecShell('{} install python-telegram-bot'.format(pip))
|
||||
import telegram
|
||||
|
||||
class panel_telegram_bot:
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#+--------------------------------------------------------------------
|
||||
|
||||
import public,json,os,time,sys,re
|
||||
from BTPanel import session
|
||||
from BTPanel import session,cache
|
||||
class obj: id=0
|
||||
class plugin_deployment:
|
||||
__setupPath = 'data'
|
||||
@@ -21,6 +21,7 @@ class plugin_deployment:
|
||||
__tmp = '/www/server/panel/temp/'
|
||||
timeoutCount = 0
|
||||
oldTime = 0
|
||||
_speed_key = 'dep_download_speed'
|
||||
|
||||
#获取列表
|
||||
def GetList(self,get):
|
||||
@@ -76,7 +77,7 @@ class plugin_deployment:
|
||||
if sys.version_info[0] == 2: filename = filename.encode('utf-8')
|
||||
if os.path.exists(filename):
|
||||
if os.path.getsize(filename) > 100: return pinfo
|
||||
public.ExecShell("wget -O " + filename + ' http://www.bt.cn' + m_uri + " &")
|
||||
public.ExecShell("wget -O " + filename + ' https://www.bt.cn' + m_uri + " &")
|
||||
return pinfo
|
||||
|
||||
#获取插件列表
|
||||
@@ -103,7 +104,7 @@ class plugin_deployment:
|
||||
try:
|
||||
jsonFile = self.__setupPath + '/deployment_list.json'
|
||||
if not 'package' in session or not os.path.exists(jsonFile) or hasattr(get,'force'):
|
||||
downloadUrl = 'http://www.bt.cn/api/panel/get_deplist'
|
||||
downloadUrl = 'https://www.bt.cn/api/panel/get_deplist'
|
||||
pdata = public.get_pdata()
|
||||
tmp = json.loads(public.httpPost(downloadUrl,pdata,3))
|
||||
if not tmp: return public.returnMsg(False,'Failed to get from the cloud!')
|
||||
@@ -269,7 +270,7 @@ class plugin_deployment:
|
||||
#下载文件
|
||||
if isDownload:
|
||||
self.WriteLogs(json.dumps({'name':'Downloading file ...','total':0,'used':0,'pre':0,'speed':0}))
|
||||
if pinfo['versions'][0]['download']: self.DownloadFile('http://www.bt.cn/api/Pluginother/get_file?fname=' + pinfo['versions'][0]['download'], packageZip)
|
||||
if pinfo['versions'][0]['download']: self.DownloadFile('https://www.bt.cn/api/Pluginother/get_file?fname=' + pinfo['versions'][0]['download'], packageZip)
|
||||
|
||||
if not os.path.exists(packageZip): return public.returnMsg(False,'File download failed!' + packageZip)
|
||||
|
||||
@@ -470,7 +471,7 @@ class plugin_deployment:
|
||||
p = panelAuth.panelAuth()
|
||||
pdata = p.create_serverid(None);
|
||||
pdata['pid'] = id;
|
||||
p_url = 'http://www.bt.cn/api/pluginother/create_order_okey'
|
||||
p_url = 'https://www.bt.cn/api/pluginother/create_order_okey'
|
||||
public.httpPost(p_url,pdata)
|
||||
|
||||
#获取进度
|
||||
|
||||
@@ -1,2 +1,63 @@
|
||||
#coding: utf-8
|
||||
import public,re
|
||||
|
||||
class projectBase:
|
||||
pass
|
||||
|
||||
def check_port(self, port):
|
||||
'''
|
||||
@name 检查端口是否被占用
|
||||
@args port:端口号
|
||||
@return: 被占用返回True,否则返回False
|
||||
@author: lkq 2021-08-28
|
||||
'''
|
||||
a = public.ExecShell("netstat -nltp|awk '{print $4}'")
|
||||
if a[0]:
|
||||
if re.search(':' + port + '\n', a[0]):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def is_domain(self, domain):
|
||||
'''
|
||||
@name 验证域名合法性
|
||||
@args domain:域名
|
||||
@return: 合法返回True,否则返回False
|
||||
@author: lkq 2021-08-28
|
||||
'''
|
||||
import re
|
||||
domain_regex = re.compile(r'(?:[A-Z0-9_](?:[A-Z0-9-_]{0,247}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(?<!-))\Z', re.IGNORECASE)
|
||||
return True if domain_regex.match(domain) else False
|
||||
|
||||
|
||||
def generate_random_port(self):
|
||||
'''
|
||||
@name 生成随机端口
|
||||
@args
|
||||
@return: 端口号
|
||||
@author: lkq 2021-08-28
|
||||
'''
|
||||
import random
|
||||
port = str(random.randint(5000, 10000))
|
||||
while True:
|
||||
if not self.check_port(port): break
|
||||
port = str(random.randint(5000, 10000))
|
||||
return port
|
||||
|
||||
def IsOpen(self, port):
|
||||
'''
|
||||
@name 检查端口是否被占用
|
||||
@args port:端口号
|
||||
@return: 被占用返回True,否则返回False
|
||||
@author: lkq 2021-08-28
|
||||
'''
|
||||
ip = '0.0.0.0'
|
||||
import socket
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
s.connect((ip, int(port)))
|
||||
s.shutdown(2)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
@@ -666,6 +666,7 @@ export PATH
|
||||
error_list = []
|
||||
for domain in domains:
|
||||
domain = domain.strip()
|
||||
if not domain: return public.return_error('Domain name cannot be empty',data='')
|
||||
domain_arr = domain.split(':')
|
||||
if len(domain_arr) == 1:
|
||||
domain_arr.append(80)
|
||||
@@ -683,8 +684,8 @@ export PATH
|
||||
if success_list:
|
||||
public.M('sites').where('id=?',(project_id,)).save('project_config',json.dumps(project_find['project_config']))
|
||||
self.set_config(get.project_name)
|
||||
|
||||
return public.return_data(True,"[{}] domain names added successfully, [{}] failed!".format(len(success_list),len(error_list)),error_msg=error_list)
|
||||
return public.return_data(True,"[{}] domain names added successfully, [{}] failed!".format(len(success_list),len(error_list)),error_msg=error_list)
|
||||
return public.return_data(False,"[{}] domain names added successfully, [{}] failed!".format(len(success_list),len(error_list)),error_msg=error_list)
|
||||
|
||||
|
||||
def project_remove_domain(self,get):
|
||||
@@ -1093,26 +1094,71 @@ export PATH
|
||||
@param pid: string<项目pid>
|
||||
@return list
|
||||
'''
|
||||
plugin_name = None
|
||||
project_name = None
|
||||
for pid_name in os.listdir(self._node_pid_path):
|
||||
pid_file = '{}/{}'.format(self._node_pid_path,pid_name)
|
||||
s_pid = int(public.readFile(pid_file))
|
||||
#s_pid = int(public.readFile(pid_file))
|
||||
data = public.readFile(pid_file)
|
||||
if isinstance(data,str) and data:
|
||||
s_pid = int(data)
|
||||
else:
|
||||
return []
|
||||
if pid == s_pid:
|
||||
plugin_name = pid_name[:-4]
|
||||
project_name = pid_name[:-4]
|
||||
break
|
||||
project_find = self.get_project_find(plugin_name)
|
||||
project_find = self.get_project_find(project_name)
|
||||
if not project_find: return []
|
||||
if not self._pids: self._pids = psutil.pids()
|
||||
all_pids = []
|
||||
for i in self._pids:
|
||||
try:
|
||||
p = psutil.Process(i)
|
||||
if p.cwd() == project_find['path'] and p.username() == project_find['project_config']['run_user']:
|
||||
if p.name() in ['node','npm','pm2']:
|
||||
if p.cwd() == project_find['path']:
|
||||
pname = p.name()
|
||||
if pname in ['node','npm','pm2','yarn'] or pname.find('node ') == 0:
|
||||
cmdline = ','.join(p.cmdline())
|
||||
if cmdline.find('God Daemon') != -1:continue
|
||||
env_list = p.environ()
|
||||
if 'name' in env_list:
|
||||
if not env_list['name'] == project_name: continue
|
||||
if 'NODE_PROJECT_NAME' in env_list:
|
||||
if not env_list['NODE_PROJECT_NAME'] == project_name: continue
|
||||
all_pids.append(i)
|
||||
except: continue
|
||||
return all_pids
|
||||
|
||||
def get_project_state_by_cwd(self,project_name):
|
||||
'''
|
||||
@name 通过cwd获取项目状态
|
||||
@author hwliang<2022-01-17>
|
||||
@param project_name<string> 项目名称
|
||||
@return bool or list
|
||||
'''
|
||||
project_find = self.get_project_find(project_name)
|
||||
self._pids = psutil.pids()
|
||||
if not project_find: return []
|
||||
all_pids = []
|
||||
for i in self._pids:
|
||||
try:
|
||||
p = psutil.Process(i)
|
||||
if p.cwd() == project_find['path']:
|
||||
pname = p.name()
|
||||
if pname in ['node','npm','pm2','yarn'] or pname.find('node ') == 0:
|
||||
cmdline = ','.join(p.cmdline())
|
||||
if cmdline.find('God Daemon') != -1:continue
|
||||
env_list = p.environ()
|
||||
if 'name' in env_list:
|
||||
if not env_list['name'] == project_name: continue
|
||||
if 'NODE_PROJECT_NAME' in env_list:
|
||||
if not env_list['NODE_PROJECT_NAME'] == project_name: continue
|
||||
all_pids.append(i)
|
||||
except: continue
|
||||
if all_pids:
|
||||
pid_file = "{}/{}.pid".format(self._node_pid_path,project_name)
|
||||
public.writeFile(pid_file,str(all_pids[0]))
|
||||
return all_pids
|
||||
return False
|
||||
|
||||
def kill_pids(self,get=None,pids = None):
|
||||
'''
|
||||
@name 结束进程列表
|
||||
@@ -1175,7 +1221,10 @@ export PATH
|
||||
nodejs_version = project_find['project_config']['nodejs_version']
|
||||
node_bin = self.get_node_bin(nodejs_version)
|
||||
npm_bin = self.get_npm_bin(nodejs_version)
|
||||
project_script = project_find['project_config']['project_script'].strip()
|
||||
project_script = project_find['project_config']['project_script'].strip().replace(' ',' ')
|
||||
if project_script[:3] == 'pm2': # PM2启动方式处理
|
||||
project_script = project_script.replace('pm2 ','pm2 -u {} -n {} '.format(project_find['project_config']['run_user'],get.project_name))
|
||||
project_find['project_config']['run_user'] = 'root'
|
||||
log_file = "{}/{}.log".format(self._node_logs_path,get.project_name)
|
||||
if not project_script: return public.return_error('No startup script configured')
|
||||
|
||||
@@ -1184,6 +1233,7 @@ export PATH
|
||||
# 生成启动脚本
|
||||
if os.path.exists(project_script):
|
||||
start_cmd = '''{last_env}
|
||||
export NODE_PROJECT_NAME="{project_name}"
|
||||
cd {project_cwd}
|
||||
nohup {node_bin} {project_script} 2>&1 >> {log_file} &
|
||||
echo $! > {pid_file}
|
||||
@@ -1193,10 +1243,12 @@ echo $! > {pid_file}
|
||||
project_script = project_script,
|
||||
log_file = log_file,
|
||||
pid_file = pid_file,
|
||||
last_env = last_env
|
||||
last_env = last_env,
|
||||
project_name = get.project_name
|
||||
)
|
||||
elif project_script in scripts_keys:
|
||||
start_cmd = '''{last_env}
|
||||
export NODE_PROJECT_NAME="{project_name}"
|
||||
cd {project_cwd}
|
||||
nohup {npm_bin} run {project_script} 2>&1 >> {log_file} &
|
||||
echo $! > {pid_file}
|
||||
@@ -1206,10 +1258,12 @@ echo $! > {pid_file}
|
||||
project_script = project_script,
|
||||
pid_file = pid_file,
|
||||
log_file = log_file,
|
||||
last_env = last_env
|
||||
last_env = last_env,
|
||||
project_name = get.project_name
|
||||
)
|
||||
else:
|
||||
start_cmd = '''{last_env}
|
||||
export NODE_PROJECT_NAME="{project_name}"
|
||||
cd {project_cwd}
|
||||
nohup {project_script} 2>&1 >> {log_file} &
|
||||
echo $! > {pid_file}
|
||||
@@ -1218,7 +1272,8 @@ echo $! > {pid_file}
|
||||
project_script = project_script,
|
||||
pid_file = pid_file,
|
||||
log_file = log_file,
|
||||
last_env = last_env
|
||||
last_env = last_env,
|
||||
project_name = get.project_name
|
||||
)
|
||||
script_file = "{}/{}.sh".format(self._node_run_scripts,get.project_name)
|
||||
|
||||
@@ -1236,6 +1291,10 @@ echo $! > {pid_file}
|
||||
# 执行脚本文件
|
||||
p = public.ExecShell("bash {}".format(script_file),user=project_find['project_config']['run_user'])
|
||||
time.sleep(1)
|
||||
n = 0
|
||||
while n < 5:
|
||||
if self.get_project_state_by_cwd(get.project_name): break
|
||||
n+=1
|
||||
if not os.path.exists(pid_file):
|
||||
p = '\n'.join(p)
|
||||
if p.find('[Errno 0]') != -1:
|
||||
@@ -1245,7 +1304,10 @@ echo $! > {pid_file}
|
||||
return public.return_error('failed to activate<pre>{}</pre>'.format(p))
|
||||
|
||||
# 获取PID
|
||||
pid = int(public.readFile(pid_file))
|
||||
try:
|
||||
pid = int(public.readFile(pid_file))
|
||||
except:
|
||||
return public.return_error('Startup failed <br>{}'.format(public.GetNumLines(log_file,20)))
|
||||
pids = self.get_project_pids(pid=pid)
|
||||
if not pids:
|
||||
if os.path.exists(pid_file): os.remove(pid_file)
|
||||
@@ -1263,13 +1325,33 @@ echo $! > {pid_file}
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
project_find = self.get_project_find(get.project_name)
|
||||
if not project_find: return public.return_error('Project does not exist')
|
||||
project_script = project_find['project_config']['project_script'].strip().replace(' ',' ')
|
||||
pid_file = "{}/{}.pid".format(self._node_pid_path,get.project_name)
|
||||
if not os.path.exists(pid_file): return public.return_error('Project did not start')
|
||||
pid = int(public.readFile(pid_file))
|
||||
pids = self.get_project_pids(pid=pid)
|
||||
if not pids: return public.return_error('Project did not start')
|
||||
self.kill_pids(pids=pids)
|
||||
if project_script.find('pm2 start') != -1: # 处理PM2启动的项目
|
||||
nodejs_version = project_find['project_config']['nodejs_version']
|
||||
last_env = self.get_last_env(nodejs_version,project_find['path'])
|
||||
project_script = project_script.replace('pm2 start','pm2 stop')
|
||||
public.ExecShell('''{}
|
||||
cd {}
|
||||
{}'''.format(last_env,project_find['path'],project_script))
|
||||
else:
|
||||
pid_file = "{}/{}.pid".format(self._node_pid_path,get.project_name)
|
||||
if not os.path.exists(pid_file): return public.return_error('Project did not start')
|
||||
data = public.readFile(pid_file)
|
||||
if isinstance(data,str) and data:
|
||||
pid = int(data)
|
||||
pids = self.get_project_pids(pid=pid)
|
||||
else:
|
||||
return public.return_error('Project did not start')
|
||||
if not pids: return public.return_error('Project did not start')
|
||||
self.kill_pids(pids=pids)
|
||||
if os.path.exists(pid_file): os.remove(pid_file)
|
||||
time.sleep(0.5)
|
||||
pids = self.get_project_state_by_cwd(get.project_name)
|
||||
if pids: self.kill_pids(pids=pids)
|
||||
|
||||
return public.return_data(True, 'Stopped successfully')
|
||||
|
||||
def restart_project(self,get):
|
||||
@@ -1314,8 +1396,12 @@ echo $! > {pid_file}
|
||||
load_info = {}
|
||||
pid_file = "{}/{}.pid".format(self._node_pid_path,project_name)
|
||||
if not os.path.exists(pid_file): return load_info
|
||||
pid = int(public.readFile(pid_file))
|
||||
pids = self.get_project_pids(pid=pid)
|
||||
data = public.readFile(pid_file)
|
||||
if isinstance(data,str) and data:
|
||||
pid = int(data)
|
||||
pids = self.get_project_pids(pid=pid)
|
||||
else:
|
||||
return load_info
|
||||
if not pids: return load_info
|
||||
for i in pids:
|
||||
process_info = self.get_process_info_by_pid(i)
|
||||
@@ -1514,9 +1600,13 @@ echo $! > {pid_file}
|
||||
if get: project_name = get.project_name.strip()
|
||||
pid_file = "{}/{}.pid".format(self._node_pid_path,project_name)
|
||||
if not os.path.exists(pid_file): return False
|
||||
pid = int(public.readFile(pid_file))
|
||||
pids = self.get_project_pids(pid=pid)
|
||||
if not pids: return False
|
||||
data=public.readFile(pid_file)
|
||||
if isinstance(data,str) and data:
|
||||
pid = int(data)
|
||||
pids = self.get_project_pids(pid=pid)
|
||||
else:
|
||||
return self.get_project_state_by_cwd(project_name)
|
||||
if not pids: return self.get_project_state_by_cwd(project_name)
|
||||
return True
|
||||
|
||||
def get_project_find(self,project_name):
|
||||
@@ -1556,12 +1646,16 @@ echo $! > {pid_file}
|
||||
'''
|
||||
project_info['project_config'] = json.loads(project_info['project_config'])
|
||||
project_info['run'] = self.get_project_run_state(project_name = project_info['name'])
|
||||
project_info['load_info'] = self.get_project_load_info(project_name = project_info['name'])
|
||||
project_info['load_info'] = {}
|
||||
if project_info['run']:
|
||||
project_info['load_info'] = self.get_project_load_info(project_name = project_info['name'])
|
||||
project_info['ssl'] = self.get_ssl_end_date(project_name = project_info['name'])
|
||||
project_info['listen'] = []
|
||||
project_info['listen_ok'] = True
|
||||
if project_info['load_info']:
|
||||
for pid in project_info['load_info'].keys():
|
||||
if not 'connections' in project_info['load_info'][pid]:
|
||||
project_info['load_info'][pid]['connections'] = []
|
||||
for conn in project_info['load_info'][pid]['connections']:
|
||||
if not conn['status'] == 'LISTEN': continue
|
||||
if not conn['local_port'] in project_info['listen']:
|
||||
|
||||
+2112
-214
File diff suppressed because it is too large
Load Diff
@@ -51,8 +51,23 @@ def check_run():
|
||||
if not public.ExecShell("lsof -i :{}".format(port_tmp[0]))[0]:
|
||||
return True,'MySQL is not installed'
|
||||
result = public.check_port_stat(int(port_tmp[0]),public.GetLocalIp())
|
||||
if result == 0:
|
||||
return True,'Risk-free'
|
||||
#兼容socket能连通但实际端口不通情况
|
||||
if result != 0:
|
||||
res=''
|
||||
if os.path.exists('/usr/sbin/firewalld'):
|
||||
res=public.ExecShell('firewall-cmd --list-all')
|
||||
elif os.path.exists('/usr/sbin/ufw'):
|
||||
try:
|
||||
res=public.ExecShell('sudo ufw status verbose')
|
||||
except:
|
||||
res=public.ExecShell('ufw status verbose')
|
||||
else:
|
||||
pass
|
||||
check_str=' '+port_tmp[0]+'/'
|
||||
if res[0].find(check_str) == -1:
|
||||
return True,'Risk-free'
|
||||
else:return True,'Risk-free'
|
||||
|
||||
|
||||
fail2ban_file = '/www/server/panel/plugin/fail2ban/config.json'
|
||||
if os.path.exists(fail2ban_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 and port != 7800:
|
||||
if port != 8888:
|
||||
return True,'Rick-free'
|
||||
return False,'The panel port is the default port ({}), which may cause unnecessary security risks'.format(port)
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ def check_run():
|
||||
@return tuple (status<bool>,msg<string>)
|
||||
'''
|
||||
not_uini = []
|
||||
site_list = public.M('sites').where('status=?',(1,)).field('name,path').select()
|
||||
site_list = public.M('sites').where('status=? AND project_type=?',(1,'PHP')).field('name,path').select()
|
||||
for s in site_list:
|
||||
path = get_site_run_path(s['name'],s['path'])
|
||||
user_ini = path + '/.user.ini'
|
||||
|
||||
+19
-39
@@ -109,7 +109,6 @@ class send_to_user:
|
||||
def read_thread(self):
|
||||
if not public.M('send_settings').count():return False
|
||||
send_data=public.M('send_settings').field('id,name,type,path,send_type,inser_time,last_time,time_frame').select()
|
||||
print(send_data)
|
||||
for i in send_data:
|
||||
if (int(time.time())-int(i['last_time']))<int(i['time_frame']):continue
|
||||
if i['type']=='json':
|
||||
@@ -118,23 +117,21 @@ class send_to_user:
|
||||
if not read_file:continue
|
||||
if not read_file[0]:continue
|
||||
for i2 in read_file:
|
||||
self.inser_send_msg(i['name'],i['send_type'],self.get_ip()+'服务器存在问题-->'+i2[1]+',触发告警时间:'+self.dtchg(int(time.time())),'json',i2[0])
|
||||
self.inser_send_msg(i['name'],i['send_type'],self.get_ip()+"服务器触发告警信息为: "+i2[1]+',触发告警时间:'+self.dtchg(int(time.time())),'json',i2[0])
|
||||
public.writeFile(i['path'], '')
|
||||
public.M('send_settings').where("id=?", (i['id'],)).update({"last_time": int(time.time())})
|
||||
continue
|
||||
if i['type']=='file':
|
||||
if os.path.exists(i['path']):
|
||||
self.inser_send_msg(i['name'], i['send_type'], '堡塔'+i['name']+'提醒您服务器'+self.get_ip()+'存在异常,详情请登陆面板查看'+i['name']+',触发告警时间:'+self.dtchg(int(time.time())), 'file', int(time.time()))
|
||||
public.M('send_settings').where("id=?", (i['id'],)).update({"last_time": int(time.time())})
|
||||
os.system('rm -rf %s'%i['path'])
|
||||
if os.path.exists(i['path']):os.system('rm -rf %s'%i['path'])
|
||||
else:
|
||||
continue
|
||||
def send(self,title,body):
|
||||
tongdao = self.mail.get_settings()
|
||||
return self.mail.qq_smtp_send(tongdao['user_mail']['mail_list'], title=title, body=body)
|
||||
def send_dingding(self,count):
|
||||
return self.mail.dingding_send(count)
|
||||
try:
|
||||
f=open(i['path'],'r')
|
||||
for i2 in f:
|
||||
i2 =i2.strip()
|
||||
if i2:
|
||||
self.inser_send_msg(i['name'], i['send_type'],self.get_ip()+"服务器触发告警信息为: "+i2+',触发告警时间:'+self.dtchg(int(time.time())), 'file', int(time.time()))
|
||||
os.remove(i['path'])
|
||||
public.M('send_settings').where("id=?", (i['id'],)).update({"last_time": int(time.time())})
|
||||
except:
|
||||
os.remove(i['path'])
|
||||
|
||||
def __write_log(self,name, msg):
|
||||
public.WriteLog(name+'告警', msg)
|
||||
@@ -146,34 +143,17 @@ class send_to_user:
|
||||
count=1
|
||||
for i in send_msg:
|
||||
if count>=4:break
|
||||
settings=self.mail.get_settings()
|
||||
if i['send_type']=='mail':
|
||||
if not settings['user_mail']['user_name']:continue
|
||||
if i['name']=='Nginx防火墙' or i['name'] == 'Apache防火墙':
|
||||
if self.send(i['name'] + '提醒您' + self.get_ip() + '服务器正在遭受攻击', i['msg']):
|
||||
self.__write_log(i['name'], i['msg'])
|
||||
public.M('send_msg').where("id=?", (i['id'],)).update({"is_send": True})
|
||||
else:
|
||||
if self.send(i['name']+'提醒您'+self.get_ip()+'服务器存在风险', i['msg']):
|
||||
self.__write_log(i['name'],i['msg'])
|
||||
public.M('send_msg').where("id=?", (i['id'],)).update({"is_send":True})
|
||||
if public.send_mail(i['name'], i['msg']):
|
||||
self.__write_log(i['name'], i['msg'])
|
||||
public.M('send_msg').where("id=?", (i['id'],)).update({"is_send":True})
|
||||
if i['send_type']=='dingding':
|
||||
if not settings['dingding']['dingding']: continue
|
||||
if i['name'] == 'Nginx防火墙' or i['name'] == 'Apache防火墙':
|
||||
if self.send(i['name'] + '提醒您' + self.get_ip() + '服务器正在遭受攻击', i['msg']):
|
||||
self.__write_log(i['name'], i['msg'])
|
||||
public.M('send_msg').where("id=?", (i['id'],)).update({"is_send": True})
|
||||
else:
|
||||
if self.send_dingding(i['msg']):
|
||||
self.__write_log(i['name'], i['msg'])
|
||||
public.M('send_msg').where("id=?", (i['id'],)).update({"is_send": True})
|
||||
if public.send_dingding(i['msg']):
|
||||
self.__write_log(i['name'], i['msg'])
|
||||
public.M('send_msg').where("id=?", (i['id'],)).update({"is_send": True})
|
||||
count += 1
|
||||
public.M('send_msg').where("is_send=?", (True,)).delete()
|
||||
|
||||
def main(self):
|
||||
try:
|
||||
self.read_thread()
|
||||
self.send_msg()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.read_thread()
|
||||
self.send_msg()
|
||||
+12
-11
@@ -93,6 +93,7 @@ class setPanelLets:
|
||||
now = time.time()
|
||||
if time_stamp > int(now):
|
||||
return i
|
||||
for i in gcl:
|
||||
for d in i['dns']:
|
||||
d = d.split('.')
|
||||
if '*' in d and d[1:] == get.domain.split('.')[1:]:
|
||||
@@ -139,8 +140,8 @@ class setPanelLets:
|
||||
public.writeFile(self.__panel_cert_path + "certificate.pem", self.__tmp_cert)
|
||||
|
||||
# 记录证书源
|
||||
def __save_cert_source(self,domain,email):
|
||||
public.writeFile(self.__panel_cert_path+"lets.info",json.dumps({"domain":domain,"cert_type":"2","email":email}))
|
||||
def __save_cert_source(self,domain):
|
||||
public.writeFile(self.__panel_cert_path+"lets.info",json.dumps({"domain":domain,"cert_type":"2"}))
|
||||
|
||||
# 获取证书源
|
||||
def get_cert_source(self):
|
||||
@@ -192,10 +193,10 @@ class setPanelLets:
|
||||
panel_cert_data = self.__check_panel_cert()
|
||||
if not panel_cert_data:
|
||||
self.__write_panel_cert()
|
||||
return public.returnMsg(True,'')
|
||||
return public.returnMsg(True,'1')
|
||||
if panel_cert_data["key"] != self.__tmp_key and panel_cert_data["cert"] != self.__tmp_cert:
|
||||
self.__write_panel_cert()
|
||||
return public.returnMsg(True,'')
|
||||
return public.returnMsg(True,'1')
|
||||
return public.returnMsg(True, '')
|
||||
|
||||
# 设置lets证书
|
||||
@@ -209,7 +210,7 @@ class setPanelLets:
|
||||
domain = self.__check_panel_domain()
|
||||
get.domain = domain
|
||||
if not domain:
|
||||
return public.returnMsg(False, "You need to bind the domain name to the panel before you can apply for the Let\'s Encrypt certificate.")
|
||||
return public.returnMsg(False, "You need to bind the domain name to the panel before you can apply for the Lets Encrypt certificate.")
|
||||
if not self.__check_host_name(domain):
|
||||
create_site = self.__create_site_of_panel_lets(get)
|
||||
domain_cert = self.__check_cert_dir(get)
|
||||
@@ -218,9 +219,9 @@ class setPanelLets:
|
||||
if not res['status']:
|
||||
return res
|
||||
public.writeFile("/www/server/panel/data/ssl.pl", "True")
|
||||
public.writeFile("/www/server/panel/data/reload.pl","1")
|
||||
self.__save_cert_source(domain,get.email)
|
||||
return public.returnMsg(True, 'Panel lets set successfully')
|
||||
# public.writeFile("/www/server/panel/data/reload.pl","1")
|
||||
self.__save_cert_source(domain)
|
||||
return public.returnMsg(True, 'Setup successfully!')
|
||||
if not create_site:
|
||||
create_lets = self.__create_lets(get)
|
||||
if not create_lets['status']:
|
||||
@@ -229,9 +230,9 @@ class setPanelLets:
|
||||
domain_cert = self.__check_cert_dir(get)
|
||||
self.copy_cert(domain_cert)
|
||||
public.writeFile("/www/server/panel/data/ssl.pl", "True")
|
||||
public.writeFile("/www/server/panel/data/reload.pl", "1")
|
||||
self.__save_cert_source(domain, get.email)
|
||||
return public.returnMsg(True, 'Panel lets set successfully')
|
||||
# public.writeFile("/www/server/panel/data/reload.pl", "1")
|
||||
self.__save_cert_source(domain)
|
||||
return public.returnMsg(True, 'Setup successfully!')
|
||||
else:
|
||||
return public.returnMsg(False, create_lets)
|
||||
else:
|
||||
|
||||
@@ -42,7 +42,7 @@ class CloudFlareDns(common.BaseDns):
|
||||
)
|
||||
if find_dns_zone_response.status_code != 200:
|
||||
raise ValueError(
|
||||
"Error creating cloudflare dns record: status_code={status_code} response={response}".format(
|
||||
"Error creating cloudflare model record: status_code={status_code} response={response}".format(
|
||||
status_code=find_dns_zone_response.status_code,
|
||||
response=self.log_response(find_dns_zone_response),
|
||||
)
|
||||
@@ -92,7 +92,7 @@ class CloudFlareDns(common.BaseDns):
|
||||
# raise error so that we do not continue to make calls to ACME
|
||||
# server
|
||||
raise ValueError(
|
||||
"Error creating cloudflare dns record: status_code={status_code} response={response}".format(
|
||||
"Error creating cloudflare model record: status_code={status_code} response={response}".format(
|
||||
status_code=create_cloudflare_dns_record_response.status_code,
|
||||
response=self.log_response(create_cloudflare_dns_record_response),
|
||||
)
|
||||
|
||||
@@ -44,12 +44,12 @@ import hmac
|
||||
try:
|
||||
import requests
|
||||
except:
|
||||
os.system('pip install requests')
|
||||
os.system('btpip install requests')
|
||||
import requests
|
||||
try:
|
||||
import OpenSSL
|
||||
except:
|
||||
os.system('pip install pyopenssl')
|
||||
os.system('btpip install pyOpenSSL')
|
||||
import OpenSSL
|
||||
import random
|
||||
import datetime
|
||||
@@ -252,7 +252,7 @@ class ACMEclient(object):
|
||||
print("Apply for a certificate")
|
||||
identifiers = []
|
||||
for domain_name in self.all_domain_names:
|
||||
identifiers.append({"type": "model", "value": domain_name})
|
||||
identifiers.append({"type": "dns", "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"] == "model-01":
|
||||
if i["type"] == "dns-01":
|
||||
dns_challenge = i
|
||||
dns_token = dns_challenge["token"]
|
||||
dns_challenge_url = dns_challenge["url"]
|
||||
@@ -806,7 +806,7 @@ class AliyunDns(object):
|
||||
msg = public.GetMsg("CANT_FIND_RECORDID"), domain_name
|
||||
print(msg)
|
||||
return
|
||||
print("start to delete model record, id: ", record_id)
|
||||
print("start to delete dns 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/model/dns_main.py add_txt {} {}'''.format(public.get_python_bin(),acme_txt + '.' + root, 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))
|
||||
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/model/dns_main.py remove_txt {} {}'''.format(public.get_python_bin() ,acme_txt + '.' + root, 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))
|
||||
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": # model.com
|
||||
elif dnsapi == "dns_bt": # dns.com
|
||||
dns_class = Dns_com()
|
||||
elif dnsapi == "model": # 手动的
|
||||
elif dnsapi == "dns": # 手动的
|
||||
dns_class = Dns_Manual()
|
||||
Manual = 1
|
||||
domain_alt_names = data['domain_alt_names'].split(",")
|
||||
|
||||
+80
-27
@@ -62,31 +62,32 @@ 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
|
||||
# if len(get.username) < 3 or len(get.password) < 3:
|
||||
# return public.return_msg_gettext(False, 'Username or password cannot be less than 3 characters')
|
||||
# name = get.name
|
||||
param = self.__check_param(get)
|
||||
if not param['status']:
|
||||
return param
|
||||
param = param['msg']
|
||||
password = param['password']
|
||||
username = param['username']
|
||||
name = param['name']
|
||||
site_dir = get.site_dir
|
||||
if public.get_webserver() == "openlitespeed":
|
||||
return public.returnMsg(False,"OpenLiteSpeed is currently not supported")
|
||||
if not hasattr(get,"password") or not get.password or not hasattr(get,"username") or not get.username:
|
||||
return public.returnMsg(False, 'Please enter an account or password')
|
||||
return public.return_msg_gettext(False,"OpenLiteSpeed is currently not supported")
|
||||
# if not hasattr(get,"password") or not get.password or not hasattr(get,"username") or not get.username:
|
||||
# return public.return_msg_gettext(False, 'Please enter an account or password')
|
||||
if not get.site_dir:
|
||||
return public.returnMsg(False, 'Please enter the directory to be protected')
|
||||
return public.return_msg_gettext(False, 'Please enter the directory to be protected')
|
||||
if not get.name:
|
||||
return public.returnMsg(False, 'Please enter the Name')
|
||||
|
||||
# if site_dir[0] != "/" or site_dir[-1] != "/":
|
||||
# return public.returnMsg(False, 'Directory format is incorrect')
|
||||
# site_dir = site_dir[1:]
|
||||
# if site_dir[-1] == "/":
|
||||
# site_dir = site_dir[:-1]
|
||||
passwd = public.hasPwd(get.password)
|
||||
return public.return_msg_gettext(False, 'Please enter the Name')
|
||||
passwd = public.hasPwd(password)
|
||||
site_info = self.get_site_info(get.id)
|
||||
site_name = site_info["site_name"]
|
||||
if self._check_site_authorization(site_name):
|
||||
return public.returnMsg(False, 'Site password protection has been set, please cancel and then set. Site directory --> Password access')
|
||||
return public.return_msg_gettext(False, 'Site password protection has been set, please cancel and then set. Site directory --> Password access')
|
||||
if self._check_dir_auth(site_name, name,site_dir):
|
||||
return public.returnMsg(False, 'Directory has been protected')
|
||||
return public.return_msg_gettext(False, 'Directory has been protected')
|
||||
auth = "{user}:{passwd}".format(user=get.username,passwd=passwd)
|
||||
auth_file = '{setup_path}/pass/{site_name}'.format(setup_path=self.setup_path,site_name=site_name)
|
||||
if not os.path.exists(auth_file):
|
||||
@@ -108,7 +109,7 @@ class SiteDirAuth:
|
||||
conf = {"name":name,"site_dir":get.site_dir,"auth_file":auth_file}
|
||||
self._write_conf(conf,site_name)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,"Created successfully")
|
||||
return public.return_msg_gettext(True,"Successfully created")
|
||||
|
||||
# 检查配置是否存在
|
||||
def _check_dir_auth(self, site_name, name,site_dir):
|
||||
@@ -126,6 +127,10 @@ class SiteDirAuth:
|
||||
conf = public.readFile(self.setup_path + '/panel/vhost/'+public.get_webserver()+'/'+siteName+'.conf');
|
||||
if public.get_webserver() == 'nginx':
|
||||
rep = "enable-php-(\w{2,5})\.conf"
|
||||
tmp = re.search(rep,conf)
|
||||
if not tmp:
|
||||
rep = "enable-php-(\d+-wpfastcgi).conf"
|
||||
re.search(rep, conf)
|
||||
else:
|
||||
rep = "php-cgi-(\w{2,5})\.sock"
|
||||
tmp = re.search(rep,conf).groups()
|
||||
@@ -134,7 +139,7 @@ class SiteDirAuth:
|
||||
else:
|
||||
return ""
|
||||
except:
|
||||
return public.returnMsg(False, 'SITE_PHPVERSION_ERR_A22')
|
||||
return public.return_msg_gettext(False, 'Apache2.2 does NOT support MultiPHP!')
|
||||
|
||||
# 获取站点名
|
||||
def get_site_info(self,id):
|
||||
@@ -179,6 +184,8 @@ class SiteDirAuth:
|
||||
%s
|
||||
#AUTH_END
|
||||
}''' % (site_dir,auth_file,php_conf)
|
||||
public.writeFile("/tmp/2", conf)
|
||||
|
||||
else:
|
||||
# 设置apache
|
||||
conf = '''<Directory "{site_path}{site_dir}">
|
||||
@@ -211,10 +218,12 @@ class SiteDirAuth:
|
||||
conf = public.readFile(file)
|
||||
if i == "apache":
|
||||
if act == "create":
|
||||
rep = "combined(\n|.)+IncludeOptional.*\/dir_auth\/.*conf"
|
||||
rep1 = "combined"
|
||||
if not re.search(rep,conf):
|
||||
conf = conf.replace(rep1, rep1 + "\n\t#Directory protection rules, do not manually delete\n\tIncludeOptional {}".format(dir_auth_file))
|
||||
rep = "IncludeOptional.*\/dir_auth\/.*conf(\n|.)+<\/VirtualHost>"
|
||||
rep1 = "</VirtualHost>"
|
||||
if not re.search(rep, conf):
|
||||
conf = conf.replace(rep1,
|
||||
"\n\t#Directory protection rules, do not manually delete\n\tIncludeOptional {}\n</VirtualHost>".format(
|
||||
dir_auth_file))
|
||||
else:
|
||||
rep = "\n*#Directory protection rules, do not manually delete\n+\s+IncludeOptional[\s\w\/\.\*]+"
|
||||
conf = re.sub(rep, '', conf)
|
||||
@@ -240,7 +249,7 @@ class SiteDirAuth:
|
||||
# for i in range(len(a_conf)-1,-1,-1):
|
||||
# if site_name == a_conf[i]["sitename"] and a_conf[i]["proxyname"]:
|
||||
# del a_conf[i]
|
||||
return public.returnMsg(False, 'ERROR: %s<br><a style="color:red;">' % public.GetMsg("CONFIG_ERROR") + isError.replace("\n",
|
||||
return public.return_msg_gettext(False, 'ERROR: %s<br><a style="color:red;">' % public.get_msg_gettext('Configuration ERROR') + isError.replace("\n",
|
||||
'<br>') + '</a>')
|
||||
|
||||
# 删除密码保护
|
||||
@@ -256,7 +265,7 @@ class SiteDirAuth:
|
||||
site_name = site_info["site_name"]
|
||||
conf = self._read_conf()
|
||||
if site_name not in conf:
|
||||
return public.returnMsg(False,"The website does not exist in the configuration:{}".format(site_name))
|
||||
return public.return_msg_gettext(False,"The website does not exist in the configuration:{}",(site_name,))
|
||||
for i in range(len(conf[site_name])):
|
||||
if name in conf[site_name][i].values():
|
||||
print(conf[site_name][i])
|
||||
@@ -275,7 +284,7 @@ class SiteDirAuth:
|
||||
self.set_conf(site_name,"delete")
|
||||
if not hasattr(get,'multiple'):
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,"DEL_SUCCESS")
|
||||
return public.return_msg_gettext(True,'Successfully deleted!')
|
||||
|
||||
# 修改目录保护密码
|
||||
def modify_dir_auth_pass(self,get):
|
||||
@@ -287,6 +296,14 @@ class SiteDirAuth:
|
||||
:param get:
|
||||
:return:
|
||||
'''
|
||||
# if not hasattr(get,"password") or not get.password or not hasattr(get,"username") or not get.username:
|
||||
# return public.return_msg_gettext(False, 'Username or password cannot be less than 3 characters')
|
||||
param = self.__check_param(get)
|
||||
if not param['status']:
|
||||
return param
|
||||
param = param['msg']
|
||||
password = param['password']
|
||||
username = param['username']
|
||||
name = get.name
|
||||
site_info = self.get_site_info(get.id)
|
||||
site_name = site_info["site_name"]
|
||||
@@ -295,7 +312,7 @@ class SiteDirAuth:
|
||||
auth_file = '{setup_path}/pass/{site_name}/{name}.pass'.format(setup_path=self.setup_path,site_name=site_name,name=name)
|
||||
public.writeFile(auth_file,auth)
|
||||
public.serviceReload()
|
||||
return public.returnMsg(True,"EDIT_SUCCESS")
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
# 获取目录保护列表
|
||||
def get_dir_auth(self,get):
|
||||
@@ -314,3 +331,39 @@ class SiteDirAuth:
|
||||
if site_name in conf:
|
||||
return {site_name:conf[site_name]}
|
||||
return {}
|
||||
|
||||
def __check_param(self, get):
|
||||
values = {}
|
||||
if hasattr(get, "password"):
|
||||
if not get.password:
|
||||
return public.returnMsg(False, 'Please enter password!')
|
||||
password = get.password.strip()
|
||||
if len(password) < 3:
|
||||
return public.returnMsg(False, 'Password cannot be less than 3 characters')
|
||||
if re.search('\s', password):
|
||||
return public.returnMsg(False, 'Password cannot contain spaces')
|
||||
values['password'] = password
|
||||
|
||||
if hasattr(get, "username"):
|
||||
if not get.username:
|
||||
return public.returnMsg(False, 'Please enter username!')
|
||||
username = get.username.strip()
|
||||
if len(username) < 3:
|
||||
return public.returnMsg(False, 'Username cannot be less than 3 characters')
|
||||
if re.search('\s', username):
|
||||
return public.returnMsg(False, 'Username cannot contain spaces')
|
||||
values['username'] = username
|
||||
|
||||
if hasattr(get, "name"):
|
||||
if not get.name:
|
||||
return public.returnMsg(False, 'Please enter a name!')
|
||||
name = get.name.strip()
|
||||
if len(name) < 3:
|
||||
return public.returnMsg(False, 'Name cannot be less than 3 characters')
|
||||
if re.search('\s', name):
|
||||
return public.returnMsg(False, 'Name cannot contain spaces')
|
||||
if re.search('[\/\"\'\!@#$%^&*()+={}\[\]\:\;\?><,./\\\]+', name):
|
||||
return public.returnMsg(False, 'Name format must be [ aaa_bbb ]')
|
||||
values['name'] = name
|
||||
|
||||
return public.returnMsg(True, values)
|
||||
+1
-1
@@ -200,7 +200,7 @@ server
|
||||
}],
|
||||
"proxy": {
|
||||
"open": False,
|
||||
"url": "http://www.bt.cn",
|
||||
"url": "https://www.bt.cn",
|
||||
"host": "www.bt.cn",
|
||||
"subOpen": False,
|
||||
"src": "",
|
||||
|
||||
@@ -100,7 +100,7 @@ class ssh_authentication:
|
||||
def install_pam_python(self,check):
|
||||
so_path=check[2]
|
||||
so_name=check[2].split('/')[-1]
|
||||
public.ExecShell('/usr/local/curl/bin/curl -o %s http://download.bt.cn/btwaf_rule/pam_python_so/%s'%(so_path,so_name))
|
||||
public.ExecShell('/usr/local/curl/bin/curl -o %s https://download.bt.cn/btwaf_rule/pam_python_so/%s'%(so_path,so_name))
|
||||
public.ExecShell("chmod 600 " + so_path)
|
||||
return True
|
||||
|
||||
|
||||
+25
-11
@@ -378,16 +378,28 @@ class ssh_security:
|
||||
关闭key
|
||||
无需参数传递
|
||||
'''
|
||||
file = ['/root/.ssh/id_rsa.pub', '/root/.ssh/id_rsa', '/root/.ssh/authorized_keys']
|
||||
rec = '\n#?RSAAuthentication\s\w+'
|
||||
rec2 = '\n#?PubkeyAuthentication\s\w+'
|
||||
file = public.readFile(self.__SSH_CONFIG)
|
||||
file_ssh = re.sub(rec, '\nRSAAuthentication no', file)
|
||||
file_result = re.sub(rec2, '\nPubkeyAuthentication no', file_ssh)
|
||||
self.wirte(self.__SSH_CONFIG, file_result)
|
||||
self.set_password(get)
|
||||
self.restart_ssh()
|
||||
return public.returnMsg(True, 'Closed successfully')
|
||||
is_ssh_status=public.get_sshd_status()
|
||||
if is_ssh_status:
|
||||
file = ['/root/.ssh/id_rsa.pub', '/root/.ssh/id_rsa', '/root/.ssh/authorized_keys']
|
||||
rec = '\n#?RSAAuthentication\s\w+'
|
||||
rec2 = '\n#?PubkeyAuthentication\s\w+'
|
||||
file = public.readFile(self.__SSH_CONFIG)
|
||||
file_ssh = re.sub(rec, '\nRSAAuthentication no', file)
|
||||
file_result = re.sub(rec2, '\nPubkeyAuthentication no', file_ssh)
|
||||
self.wirte(self.__SSH_CONFIG, file_result)
|
||||
self.set_password(get)
|
||||
self.restart_ssh()
|
||||
return public.returnMsg(True, 'Closed successfully')
|
||||
else:
|
||||
file = ['/root/.ssh/id_rsa.pub', '/root/.ssh/id_rsa', '/root/.ssh/authorized_keys']
|
||||
rec = '\n#?RSAAuthentication\s\w+'
|
||||
rec2 = '\n#?PubkeyAuthentication\s\w+'
|
||||
file = public.readFile(self.__SSH_CONFIG)
|
||||
file_ssh = re.sub(rec, '\nRSAAuthentication no', file)
|
||||
file_result = re.sub(rec2, '\nPubkeyAuthentication no', file_ssh)
|
||||
self.wirte(self.__SSH_CONFIG, file_result)
|
||||
#self.set_password(get)
|
||||
return public.returnMsg(True, 'Closed successfully')
|
||||
|
||||
def get_config(self, get):
|
||||
'''
|
||||
@@ -514,6 +526,8 @@ if __name__ == '__main__':
|
||||
try:
|
||||
aa = ssh_security()
|
||||
aa.login()
|
||||
except:pass
|
||||
except:
|
||||
print(111)
|
||||
pass
|
||||
else:
|
||||
pass
|
||||
|
||||
+208
-111
@@ -21,7 +21,7 @@ from io import BytesIO, StringIO
|
||||
|
||||
def returnMsg(status,msg,value=None):
|
||||
if value:
|
||||
msg = public.getMsg(msg,value)
|
||||
msg = public.get_msg_gettext(msg,value)
|
||||
return {'status':status,'msg':msg}
|
||||
|
||||
import public
|
||||
@@ -38,7 +38,7 @@ class ssh_terminal:
|
||||
_ssh = None
|
||||
_last_cmd = ""
|
||||
_last_cmd_tip = 0
|
||||
_log_type = public.getMsg('TYPE_TERMINAL')
|
||||
_log_type = public.get_msg_gettext('aaPanel terminal')
|
||||
_history_len = 0
|
||||
_client = ""
|
||||
_rep_ssh_config = False
|
||||
@@ -48,6 +48,8 @@ class ssh_terminal:
|
||||
_old_conf = None
|
||||
_debug_file = 'logs/terminal.log'
|
||||
_s_code = None
|
||||
_last_num = 0
|
||||
_key_passwd = None
|
||||
|
||||
def connect(self):
|
||||
'''
|
||||
@@ -58,7 +60,7 @@ class ssh_terminal:
|
||||
msg: string 详情
|
||||
}
|
||||
'''
|
||||
if not self._host: return returnMsg(False,'WRONG_CONN_ADDR')
|
||||
if not self._host: return public.return_msg_gettext(False,'Wrong connection address')
|
||||
|
||||
if not self._user: self._user = 'root'
|
||||
if not self._port: self._port = 22
|
||||
@@ -71,7 +73,7 @@ class ssh_terminal:
|
||||
while num < 5:
|
||||
num +=1
|
||||
try:
|
||||
self.debug(public.getMsg('RECONN_TIMES',(num,)))
|
||||
self.debug(public.get_msg_gettext('Reconnection attempts:{}',(num,)))
|
||||
if self._rep_ssh_config: time.sleep(0.1)
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(2 + num)
|
||||
@@ -81,10 +83,10 @@ class ssh_terminal:
|
||||
except Exception as e:
|
||||
if num == 5:
|
||||
self.set_sshd_config(True)
|
||||
self.debug(public.getMsg('RECONN_FAILED',(e,)))
|
||||
self.debug(public.get_msg_gettext('Retry connection failed, {}',(e,)))
|
||||
if self._host in ['127.0.0.1','localhost']:
|
||||
return returnMsg(False,'CONN_FAIL',("Authentication failed ," + self._user + "@" + self._host + ":" +str(self._port),))
|
||||
return returnMsg(False,'CONN_FAIL1',(self._host,self._port))
|
||||
return returnMsg(False,'Connection failure: {}',("Authentication failed ," + self._user + "@" + self._host + ":" +str(self._port),))
|
||||
return returnMsg(False,'Connection failure: {}',(self._host,self._port))
|
||||
else:
|
||||
time.sleep(0.2)
|
||||
|
||||
@@ -92,15 +94,15 @@ class ssh_terminal:
|
||||
import paramiko
|
||||
|
||||
self._tp = paramiko.Transport(sock)
|
||||
|
||||
pkey = None
|
||||
try:
|
||||
self._tp.start_client()
|
||||
if not self._pass and not self._pkey:
|
||||
self.set_sshd_config(True)
|
||||
return public.returnMsg(False,'SSH_LOGIN_INFO_ERR',(self._host,str(self._port)))
|
||||
return public.return_msg_gettext(False,'Password or private key cannot both be empty: {}:{}',(self._host,str(self._port)))
|
||||
self._tp.banner_timeout=60
|
||||
if self._pkey:
|
||||
self.debug(public.getMsg('AUTH_PRI_KEY'))
|
||||
self.debug(public.get_msg_gettext('Authenticating private key'))
|
||||
if sys.version_info[0] == 2:
|
||||
try:
|
||||
self._pkey = self._pkey.encode('utf-8')
|
||||
@@ -110,18 +112,43 @@ class ssh_terminal:
|
||||
else:
|
||||
p_file = StringIO(self._pkey)
|
||||
try:
|
||||
pkey = paramiko.RSAKey.from_private_key(p_file)
|
||||
except:
|
||||
if self._key_passwd:
|
||||
pkey = paramiko.RSAKey.from_private_key(p_file,password=self._key_passwd)
|
||||
else:
|
||||
pkey = paramiko.RSAKey.from_private_key(p_file)
|
||||
self.debug("尝试使用RSA私钥认证")
|
||||
except Exception as ex:
|
||||
try:
|
||||
p_file.seek(0)
|
||||
pkey = paramiko.Ed25519Key.from_private_key(p_file)
|
||||
if self._key_passwd:
|
||||
pkey = paramiko.Ed25519Key.from_private_key(p_file,password=self._key_passwd)
|
||||
else:
|
||||
pkey = paramiko.Ed25519Key.from_private_key(p_file)
|
||||
self.debug("尝试使用Ed25519私钥认证")
|
||||
except:
|
||||
try:
|
||||
p_file.seek(0)
|
||||
pkey = paramiko.ECDSAKey.from_private_key(p_file)
|
||||
if self._key_passwd:
|
||||
pkey = paramiko.ECDSAKey.from_private_key(p_file,password=self._key_passwd)
|
||||
else:
|
||||
pkey = paramiko.ECDSAKey.from_private_key(p_file)
|
||||
self.debug("尝试使用ECDSA私钥认证")
|
||||
except:
|
||||
p_file.seek(0)
|
||||
pkey = paramiko.DSSKey.from_private_key(p_file)
|
||||
if self._key_passwd:
|
||||
try:
|
||||
pkey = paramiko.DSSKey.from_private_key(p_file,password=self._key_passwd)
|
||||
except Exception as ex:
|
||||
ex = str(ex)
|
||||
if ex.find('OpenSSH private key file checkints do not match') != -1:
|
||||
return public.returnMsg(False,'Incorrect private key password: {}'.format(ex))
|
||||
elif ex.find('encountered RSA key, expected DSA key') != -1:
|
||||
pkey = paramiko.RSAKey.from_private_key(p_file,password=self._key_passwd)
|
||||
else:
|
||||
return public.returnMsg(False,'private key error: {}'.format(ex))
|
||||
else:
|
||||
pkey = paramiko.DSSKey.from_private_key(p_file)
|
||||
if not pkey: return public.returnMsg(False,'Incorrect private key!')
|
||||
self._tp.auth_publickey(username=self._user, key=pkey)
|
||||
else:
|
||||
try:
|
||||
@@ -142,32 +169,43 @@ class ssh_terminal:
|
||||
self._tp.close()
|
||||
e = str(e)
|
||||
if e.find('websocket error!') != -1:
|
||||
return returnMsg(True,'connection succeeded')
|
||||
return public.return_msg_gettext(True,'connection succeeded')
|
||||
if e.find('Authentication timeout') != -1:
|
||||
self.debug("认证超时{}".format(e))
|
||||
return returnMsg(False,'Authentication timed out, please press enter to try again!{}'.format(e))
|
||||
return public.return_msg_gettext(False,'Authentication timed out, please press enter to try again!{}',(e,))
|
||||
if e.find('Authentication failed') != -1:
|
||||
self.debug(public.getMsg('AUTH_FAIL',(str(e),)))
|
||||
return returnMsg(False,'SSH_LOGIN_ERR1',(str(e + "," + self._user + "@" + self._host + ":" +str(self._port)),))
|
||||
self.debug(public.get_msg_gettext('Authentication failed {}',(str(e),)))
|
||||
if self._key_passwd:
|
||||
sshd_config = public.readFile('/etc/ssh/sshd_config')
|
||||
if sshd_config and sshd_config.find('ssh-dss') == -1:
|
||||
return returnMsg(False,'The private key verification fails, the private key may be incorrect, or the ssh-dss private key authentication type may not be enabled in the /etc/ssh/sshd_config configuration file')
|
||||
return returnMsg(False,'Authentication failed, please check whether the private key is correct: {}'.format(e + "," + self._user + "@" + self._host + ":" +str(self._port)))
|
||||
return returnMsg(False,'account or password incorrect:{}'.format(e + "," + self._user + "@" + self._host + ":" +str(self._port)))
|
||||
if e.find('Bad authentication type; allowed types') != -1:
|
||||
self.debug(public.getMsg('AUTH_FAIL',(str(e),)))
|
||||
self.debug(public.get_msg_gettext('Authentication failed {}',(str(e),)))
|
||||
if self._host in ['127.0.0.1','localhost'] and self._pass == 'none':
|
||||
return returnMsg(False,'USER_OR_PASSWD_ERR',(str("Authentication failed ," + self._user + "@" + self._host + ":" +str(self._port)),))
|
||||
return returnMsg(False,'SSH_LOGIN_ERR2',(str(e)))
|
||||
return public.return_msg_gettext(False,'Username or Password incorrect: {}',(str("Authentication failed ," + self._user + "@" + self._host + ":" +str(self._port)),))
|
||||
return public.return_msg_gettext(False,'Unsupported authentication type: {}',(str(e)))
|
||||
if e.find('Connection reset by peer') != -1:
|
||||
self.debug(public.getMsg('SSH_LOGIN_ERR3'))
|
||||
return returnMsg(False,public.getMsg('SSH_LOGIN_ERR3'))
|
||||
self.debug(public.get_msg_gettext('The target server actively refused the connection'))
|
||||
return public.return_msg_gettext(False,public.get_msg_gettext('The target server actively refused the connection'))
|
||||
if e.find('Error reading SSH protocol banner') != -1:
|
||||
self.debug('SSH_LOGIN_ERR10')
|
||||
return returnMsg(False,public.getMsg('SSH_LOGIN_ERR4',(str(e),)))
|
||||
self.debug('The protocol header response timed out')
|
||||
return public.return_msg_gettext(False,public.get_msg_gettext('The protocol header response timed out, and the network quality with the target server was too bad: {}',(str(e),)))
|
||||
if e.find('encountered RSA key, expected DSA key') != -1:
|
||||
self.debug('Private keys may require password access')
|
||||
return public.return_msg_gettext(False,public.get_msg_gettext('Private keys may require password access: {}',(str(e),)))
|
||||
if e.find('password and salt must not be empty') != -1:
|
||||
self.debug('Private keys may require password access')
|
||||
return public.return_msg_gettext(False,public.get_msg_gettext('Private keys may require password access: {}',(str(e),)))
|
||||
if not e:
|
||||
self.debug('SSH_LOGIN_ERR11')
|
||||
return returnMsg(False,"SSH_LOGIN_ERR5")
|
||||
self.debug('The SSH protocol handshake timed out')
|
||||
return public.return_msg_gettext(False,"The SSH protocol handshake timed out, and the network quality with the target server is too bad")
|
||||
err = public.get_error_info()
|
||||
self.debug(err)
|
||||
return returnMsg(False,public.getMsg("SSH_LOGIN_ERR6",(str(err),)))
|
||||
return public.return_msg_gettext(False,public.get_msg_gettext('unknown error: {}',(str(err),)))
|
||||
|
||||
self.debug('SSH_LOGIN_INFO3')
|
||||
self.debug(public.get_msg_gettext('The authentication is successful and the session channel is being constructed'))
|
||||
self._ssh = self._tp.open_session()
|
||||
self._ssh.get_pty(term='xterm', width=100, height=34)
|
||||
self._ssh.invoke_shell()
|
||||
@@ -175,11 +213,11 @@ class ssh_terminal:
|
||||
self._last_send = []
|
||||
from BTPanel import request
|
||||
self._client = public.GetClientIp() +':' + str(request.environ.get('REMOTE_PORT'))
|
||||
public.WriteLog(self._log_type,'SSH_LOGIN',(self._host,str(self._port)))
|
||||
self.history_send("LOGIN_SUCCESS2")
|
||||
public.write_log_gettext(self._log_type,'Successfully logged in to the SSH server [{}:{}]',(self._host,str(self._port)))
|
||||
self.history_send(public.get_msg_gettext("Login success\n"))
|
||||
self.set_sshd_config(True)
|
||||
self.debug('SSH_LOGIN_INFO2')
|
||||
return returnMsg(True,'CONNECTION_SUCCEEDED')
|
||||
self.debug(public.get_msg_gettext('Login success'))
|
||||
return public.return_msg_gettext(True,'connection succeeded')
|
||||
|
||||
def _auth_interactive(self):
|
||||
self.debug('Verification Code')
|
||||
@@ -216,6 +254,8 @@ class ssh_terminal:
|
||||
|
||||
self._tp.auth_interactive(self._user, handler)
|
||||
|
||||
|
||||
|
||||
def get_login_user(self):
|
||||
'''
|
||||
@name 获取本地登录用户
|
||||
@@ -288,10 +328,15 @@ class ssh_terminal:
|
||||
self._pass = ssh_info['password']
|
||||
self._old_conf = True
|
||||
return
|
||||
|
||||
ssh_key_type_file = '{}/data/ssh_key_type.pl'.format(public.get_panel_path())
|
||||
ssh_key_type = ''
|
||||
if os.path.exists(ssh_key_type_file):
|
||||
ssh_key_type_new = public.readFile(ssh_key_type_file)
|
||||
if ssh_key_type_new: ssh_key_type = ssh_key_type_new.strip()
|
||||
login_user = self.get_login_user()
|
||||
if self._user == 'root' and login_user == 'root':
|
||||
id_rsa_file = ['/root/.ssh/id_rsa','/root/.ssh/id_rsa_bt']
|
||||
id_rsa_file = ['/root/.ssh/id_ed25519','/root/.ssh/id_ecdsa','/root/.ssh/id_rsa','/root/.ssh/id_rsa_bt']
|
||||
if ssh_key_type: id_rsa_file.insert(0,'/root/.ssh/id_{}'.format(ssh_key_type))
|
||||
for ifile in id_rsa_file:
|
||||
if os.path.exists(ifile):
|
||||
self._pkey = public.readFile(ifile)
|
||||
@@ -301,12 +346,14 @@ class ssh_terminal:
|
||||
return
|
||||
|
||||
|
||||
|
||||
if not self._pass or not self._pkey or not self._user:
|
||||
home_path = '/home/' + login_user
|
||||
if login_user == 'root':
|
||||
home_path = '/root'
|
||||
self._user = login_user
|
||||
id_rsa_file = [home_path + '/.ssh/id_rsa',home_path + '/.ssh/id_rsa_bt']
|
||||
id_rsa_file = [home_path + '/.ssh/id_ed25519',home_path + '/.ssh/id_ecdsa',home_path + '/.ssh/id_rsa',home_path + '/.ssh/id_rsa_bt']
|
||||
if ssh_key_type: id_rsa_file.insert(0,home_path + '/.ssh/id_{}'.format(ssh_key_type))
|
||||
for ifile in id_rsa_file:
|
||||
if os.path.exists(ifile):
|
||||
self._pkey = public.readFile(ifile)
|
||||
@@ -314,19 +361,6 @@ class ssh_terminal:
|
||||
|
||||
self._pass = 'none'
|
||||
return
|
||||
# _ssh_ks = home_path + '/.ssh'
|
||||
# if not os.path.exists(_ssh_ks):
|
||||
# os.makedirs(_ssh_ks,384)
|
||||
# os.system("ssh-keygen -t rsa -P '' -f {}/.ssh/id_rsa |echo y".format(home_path))
|
||||
# pub_file = home_path + '/.ssh/id_rsa.pub'
|
||||
# az_file = home_path + '/.ssh/authorized_keys'
|
||||
# rsa_file = home_path + '/.ssh/id_rsa'
|
||||
# public.ExecShell('cat {} >> {} && chmod 600 {} {}'.format(pub_file, az_file, az_file,rsa_file))
|
||||
# os.remove(pub_file)
|
||||
# public.ExecShell("chown -R {}:{} {}".format(self._user,self._user,_ssh_ks))
|
||||
# public.ExecShell("chmod -R 600 {}".format(_ssh_ks))
|
||||
# self._pkey = public.readFile(rsa_file)
|
||||
|
||||
|
||||
except:
|
||||
return
|
||||
@@ -416,6 +450,8 @@ class ssh_terminal:
|
||||
self.restart_ssh()
|
||||
return True
|
||||
|
||||
|
||||
|
||||
pin = r'^\s*PubkeyAuthentication\s+(yes|no)'
|
||||
pubkey_status = re.findall(pin,sshd_config,re.I)
|
||||
if pubkey_status:
|
||||
@@ -491,12 +527,12 @@ class ssh_terminal:
|
||||
'''
|
||||
n = 0
|
||||
try:
|
||||
while not self._ws.closed:
|
||||
while self._ws.connected:
|
||||
resp_line = self._ssh.recv(1024)
|
||||
if not resp_line:
|
||||
if not self._tp.is_active():
|
||||
self.debug(public.getMsg('SSH_LOGIN_ERR14'))
|
||||
self._ws.send(public.getMsg('RECONNECT_SSH'))
|
||||
self.debug(public.get_msg_gettext('Channel disconnected'))
|
||||
self._ws.send(public.get_msg_gettext('The connection is disconnected, press enter to try to reconnect!'))
|
||||
self.close()
|
||||
return
|
||||
|
||||
@@ -505,7 +541,7 @@ class ssh_terminal:
|
||||
if n > 5: break
|
||||
continue
|
||||
n = 0
|
||||
if self._ws.closed:
|
||||
if not self._ws.connected:
|
||||
return
|
||||
try:
|
||||
result = resp_line.decode('utf-8','ignore')
|
||||
@@ -517,16 +553,16 @@ class ssh_terminal:
|
||||
|
||||
self._ws.send(result)
|
||||
|
||||
self.history_recv(result)
|
||||
# self.history_recv(result)
|
||||
except Exception as e:
|
||||
e = str(e)
|
||||
if e.find('closed') != -1:
|
||||
self.debug('SSH_LOGIN_INFO')
|
||||
elif not self._ws.closed:
|
||||
self.debug(public.getMsg('SSH_LOGIN_ERR15',(str(e),)))
|
||||
self.debug(public.getMsg('SSH_LOGIN_INFO'))
|
||||
elif self._ws.connected:
|
||||
self.debug(public.get_msg_gettext('Error reading tty buffer data, {}',(str(e),)))
|
||||
|
||||
if self._ws.closed:
|
||||
self.debug(public.getMsg('SSH_LOGIN_INFO1'))
|
||||
if not self._ws.connected:
|
||||
self.debug(public.get_msg_gettext('The client has actively disconnected'))
|
||||
self.close()
|
||||
|
||||
def send(self):
|
||||
@@ -536,12 +572,13 @@ class ssh_terminal:
|
||||
@return void
|
||||
'''
|
||||
try:
|
||||
while not self._ws.closed:
|
||||
while self._ws.connected:
|
||||
if self._s_code:
|
||||
time.sleep(0.1)
|
||||
continue
|
||||
client_data = self._ws.receive()
|
||||
if not client_data: continue
|
||||
if client_data == '{}': continue
|
||||
if len(client_data) > 10:
|
||||
if client_data.find('{"host":"') != -1:
|
||||
continue
|
||||
@@ -549,20 +586,21 @@ class ssh_terminal:
|
||||
self.resize(client_data)
|
||||
continue
|
||||
self._ssh.send(client_data)
|
||||
self.history_send(client_data)
|
||||
# self.history_send(client_data)
|
||||
except Exception as ex:
|
||||
ex = str(ex)
|
||||
|
||||
if ex.find('_io.BufferedReader') != -1:
|
||||
self.debug(public.getMsg('SSH_LOGIN_ERR16'))
|
||||
self.debug(public.get_msg_gettext('An error occurred while reading data from websocket. Retrying'))
|
||||
self.send()
|
||||
return
|
||||
elif ex.find('closed') != -1:
|
||||
self.debug('SSH_LOGIN_INFO')
|
||||
self.debug(public.get_msg_gettext('SSH_LOGIN_INFO'))
|
||||
else:
|
||||
self.debug(public.getMsg('SSH_LOGIN_ERR17',(str(ex),)))
|
||||
self.debug(public.get_msg_gettext('An error occurred while writing data to the buffer: {}',(str(ex),)))
|
||||
|
||||
if self._ws.closed:
|
||||
self.debug(public.getMsg('SSH_LOGIN_INFO1'))
|
||||
if not self._ws.connected:
|
||||
self.debug(public.get_msg_gettext('The client has actively disconnected'))
|
||||
self.close()
|
||||
|
||||
|
||||
@@ -576,7 +614,7 @@ class ssh_terminal:
|
||||
#处理TAB补登
|
||||
if self._last_cmd_tip == 1:
|
||||
if not recv_data.startswith('\r\n'):
|
||||
self._last_cmd += recv_data.replace('\u0007','').strip()
|
||||
self._last_cmd += recv_data.replace('\u0007','').replace("\x07","").strip()
|
||||
self._last_cmd_tip = 0
|
||||
|
||||
#上下切换命令
|
||||
@@ -601,32 +639,49 @@ class ssh_terminal:
|
||||
self._last_cmd_tip = 2
|
||||
return
|
||||
|
||||
#左移光标
|
||||
if send_data in ["\x1b[C"]:
|
||||
self._last_num -= 1
|
||||
return
|
||||
|
||||
# 右移光标
|
||||
if send_data in ["\x1b[D"]:
|
||||
self._last_num += 1
|
||||
return
|
||||
|
||||
#退格
|
||||
if send_data == "\x7f":
|
||||
self._last_cmd = self._last_cmd[:-1]
|
||||
return
|
||||
|
||||
|
||||
#过滤特殊符号
|
||||
if send_data in ["\x1b[C","\x1b[D","\x1b[K","\x07","\x08","\x03","\x01","\x02","\x04","\x05","\x06","\u0007"]:
|
||||
if send_data in ["\x1b[C","\x1b[D","\x1b[K","\x07","\x08","\x03","\x01","\x02","\x04","\x05","\x06","\x1bOB","\x1bOA","\x1b[8P","\x1b","\x1b[4P","\x1b[6P","\x1b[5P"]:
|
||||
return
|
||||
|
||||
#Tab补全处理
|
||||
if send_data == '\t':
|
||||
if send_data == "\t":
|
||||
self._last_cmd_tip = 1
|
||||
return
|
||||
|
||||
if str(send_data).find("\x1b") != -1:
|
||||
return
|
||||
|
||||
if send_data[-1] in ['\r','\n']:
|
||||
if not self._last_cmd: return
|
||||
his_shell = [int(time.time()),self._client,self._user,self._last_cmd]
|
||||
public.writeFile(his_file, json.dumps(his_shell) + "\n","a+")
|
||||
self._last_cmd = ""
|
||||
|
||||
#超过5M则保留最新的200行
|
||||
if os.stat(his_file).st_size > 5242880:
|
||||
his_tmp = public.GetNumLines(his_file,200)
|
||||
#超过50M则保留最新的20000行
|
||||
if os.stat(his_file).st_size > 52428800:
|
||||
his_tmp = public.GetNumLines(his_file,20000)
|
||||
public.writeFile(his_file, his_tmp)
|
||||
else:
|
||||
self._last_cmd += send_data
|
||||
if self._last_num >= 0:
|
||||
self._last_cmd += send_data
|
||||
else:
|
||||
self._last_cmd.insert(len(self._last_cmd) + self._last_num, send_data)
|
||||
|
||||
|
||||
def close(self):
|
||||
@@ -640,7 +695,7 @@ class ssh_terminal:
|
||||
self._ssh.close()
|
||||
if self._tp: # 关闭宿主服务
|
||||
self._tp.close()
|
||||
if not self._ws.closed:
|
||||
if self._ws.connected:
|
||||
self._ws.close()
|
||||
except:
|
||||
pass
|
||||
@@ -660,6 +715,8 @@ class ssh_terminal:
|
||||
self._pkey = ssh_info['pkey']
|
||||
if 'password' in ssh_info:
|
||||
self._pass = ssh_info['password']
|
||||
if 'pkey_passwd' in ssh_info:
|
||||
self._key_passwd = ssh_info['pkey_passwd']
|
||||
try:
|
||||
result = self.connect()
|
||||
except Exception as ex:
|
||||
@@ -680,7 +737,7 @@ class ssh_terminal:
|
||||
self._tp.send_ignore()
|
||||
else:
|
||||
break
|
||||
if not self._ws.closed:
|
||||
if self._ws.connected:
|
||||
self._ws.send("")
|
||||
else:
|
||||
break
|
||||
@@ -692,6 +749,7 @@ class ssh_terminal:
|
||||
@return void
|
||||
'''
|
||||
msg = "{} - {}:{} => {} \n".format(public.format_date(),self._host,self._port,msg)
|
||||
self.history_send(msg)
|
||||
public.writeFile(self._debug_file,msg,'a+')
|
||||
|
||||
def run(self,web_socket, ssh_info=None):
|
||||
@@ -714,7 +772,8 @@ class ssh_terminal:
|
||||
return
|
||||
result = self.set_attr(ssh_info)
|
||||
else:
|
||||
result = returnMsg(True,'ALREADY_CONNECTED')
|
||||
result = public.get_msg_gettext(True,'ALREADY_CONNECTED')
|
||||
|
||||
if result['status']:
|
||||
sendt = threading.Thread(target=self.send)
|
||||
recvt = threading.Thread(target=self.recv)
|
||||
@@ -728,6 +787,7 @@ class ssh_terminal:
|
||||
self.close()
|
||||
else:
|
||||
self._ws.send(result['msg'])
|
||||
self.close()
|
||||
|
||||
def __del__(self):
|
||||
'''
|
||||
@@ -746,6 +806,14 @@ class ssh_host_admin(ssh_terminal):
|
||||
_pass_str = None
|
||||
|
||||
def __init__(self):
|
||||
self.__create_aes_pass()
|
||||
|
||||
def __create_aes_pass(self):
|
||||
'''
|
||||
@name 创建AES密码
|
||||
@author
|
||||
@return string
|
||||
'''
|
||||
if not os.path.exists(self._save_path):
|
||||
os.makedirs(self._save_path,384)
|
||||
if not os.path.exists(self._pass_file):
|
||||
@@ -753,6 +821,10 @@ class ssh_host_admin(ssh_terminal):
|
||||
public.set_mode(self._pass_file,600)
|
||||
if not self._pass_str:
|
||||
self._pass_str = public.readFile(self._pass_file)
|
||||
if not self._pass_str:
|
||||
self._pass_str = public.GetRandomString(16)
|
||||
public.writeFile(self._pass_file,self._pass_str)
|
||||
public.set_mode(self._pass_file,600)
|
||||
|
||||
def get_host_list(self,args = None):
|
||||
'''
|
||||
@@ -766,12 +838,17 @@ class ssh_host_admin(ssh_terminal):
|
||||
for name in os.listdir(self._save_path):
|
||||
info_file = self._save_path + name +'/info.json'
|
||||
if not os.path.exists(info_file): continue
|
||||
info_tmp = self.get_ssh_info(name)
|
||||
host_info = {}
|
||||
host_info['host'] = name
|
||||
host_info['port'] = info_tmp['port']
|
||||
host_info['ps'] = info_tmp['ps']
|
||||
host_info['sort'] = int(info_tmp['sort'])
|
||||
try:
|
||||
info_tmp = self.get_ssh_info(name)
|
||||
host_info = {}
|
||||
host_info['host'] = name
|
||||
host_info['port'] = info_tmp['port']
|
||||
host_info['ps'] = info_tmp['ps']
|
||||
host_info['sort'] = int(info_tmp['sort'])
|
||||
except:
|
||||
if os.path.exists(info_file):
|
||||
os.remove(info_file)
|
||||
continue
|
||||
|
||||
host_list.append(host_info)
|
||||
|
||||
@@ -790,7 +867,7 @@ class ssh_host_admin(ssh_terminal):
|
||||
args.host = args.host.strip()
|
||||
info_file = self._save_path + args.host +'/info.json'
|
||||
if not os.path.exists(info_file):
|
||||
return public.returnMsg(False,'SSH_LOGIN_ERR7')
|
||||
return public.return_msg_gettext(False,'The specified SSH information does not exist!')
|
||||
info_tmp = self.get_ssh_info(args.host)
|
||||
host_info = {}
|
||||
host_info['host'] = args.host
|
||||
@@ -800,6 +877,9 @@ class ssh_host_admin(ssh_terminal):
|
||||
host_info['username'] = info_tmp['username']
|
||||
host_info['password'] = info_tmp['password']
|
||||
host_info['pkey'] = info_tmp['pkey']
|
||||
host_info['pkey_passwd'] = ''
|
||||
if 'pkey_passwd' in info_tmp:
|
||||
host_info['pkey_passwd'] = info_tmp['pkey_passwd']
|
||||
return host_info
|
||||
|
||||
def modify_host(self,args):
|
||||
@@ -815,6 +895,7 @@ class ssh_host_admin(ssh_terminal):
|
||||
username: 用户名
|
||||
password: 密码
|
||||
pkey: 密钥(如果不为空,将使用密钥连接)
|
||||
pkey_passwd: 密钥的密码
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
@@ -823,12 +904,12 @@ class ssh_host_admin(ssh_terminal):
|
||||
if args.host != args.new_host:
|
||||
info_file = self._save_path + args.new_host +'/info.json'
|
||||
if os.path.exists(info_file):
|
||||
return public.returnMsg(False,'SSH_LOGIN_ERR8')
|
||||
return public.return_msg_gettext(False,'The specified host address has been added to other SSH information!')
|
||||
|
||||
info_file = self._save_path + args.host +'/info.json'
|
||||
|
||||
if not os.path.exists(info_file):
|
||||
return public.returnMsg(False,'SSH_LOGIN_ERR7')
|
||||
return public.return_msg_gettext(False,'The specified SSH information does not exist!')
|
||||
|
||||
if not 'sort' in args:
|
||||
r_data = public.aes_decrypt(public.readFile(info_file),self._pass_str)
|
||||
@@ -843,14 +924,18 @@ class ssh_host_admin(ssh_terminal):
|
||||
host_info['username'] = args['username']
|
||||
host_info['password'] = args['password']
|
||||
host_info['pkey'] = args['pkey']
|
||||
if 'pkey_passwd' in args:
|
||||
host_info['pkey_passwd'] = args['pkey_passwd']
|
||||
else:
|
||||
host_info['pkey_passwd'] = ''
|
||||
if not host_info['pkey']: host_info['pkey'] = ''
|
||||
result = self.set_attr(host_info)
|
||||
if not result['status']: return result
|
||||
self.save_ssh_info(args.host,host_info)
|
||||
if args.host != args.new_host:
|
||||
public.ExecShell('mv {} {}'.format(self._save_path + args.host,self._save_path + args.new_host))
|
||||
public.WriteLog(self._log_type,'MODIFY_SSH_INFO',(args.host,))
|
||||
return public.returnMsg(True,'EDIT_SUCCESS')
|
||||
public.write_log_gettext(self._log_type,'Modify the SSH information of HOST: {}',(args.host,))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
def create_host(self,args):
|
||||
'''
|
||||
@@ -864,6 +949,7 @@ class ssh_host_admin(ssh_terminal):
|
||||
username: 用户名
|
||||
password: 密码
|
||||
pkey: 密钥(如果不为空,将使用密钥连接)
|
||||
pkey_passwd: 密钥的密码
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
@@ -886,11 +972,14 @@ class ssh_host_admin(ssh_terminal):
|
||||
host_info['username'] = args['username']
|
||||
host_info['password'] = args['password']
|
||||
host_info['pkey'] = args['pkey']
|
||||
host_info['pkey_passwd'] = ''
|
||||
if 'pkey_passwd' in args:
|
||||
host_info['pkey_passwd'] = args['pkey_passwd']
|
||||
result = self.set_attr(host_info)
|
||||
if not result['status']: return result
|
||||
self.save_ssh_info(args.host,host_info)
|
||||
public.WriteLog(self._log_type,'ADD_SSH_INFO',(str(args.host),))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
public.write_log_gettext(self._log_type,'Add the SSH information of HOST: {}',(str(args.host),))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
def remove_host(self,args):
|
||||
@@ -903,13 +992,13 @@ class ssh_host_admin(ssh_terminal):
|
||||
@return dict
|
||||
'''
|
||||
args.host = args.host.strip()
|
||||
if not args.host: return public.returnMsg(False,'INIT_ARGS_ERR')
|
||||
if not args.host: return public.return_msg_gettext(False,'Parameter ERROR!')
|
||||
host_path = self._save_path + args.host
|
||||
if not os.path.exists(host_path):
|
||||
return public.returnMsg(False,'SSH_LOGIN_ERR7!')
|
||||
return public.return_msg_gettext(False,'The specified SSH information does not exist!')
|
||||
public.ExecShell("rm -rf {}".format(host_path))
|
||||
public.WriteLog(self._log_type,'DEL_SSH_INFO',(str(args.host),))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
public.write_log_gettext(self._log_type,'Delete the SSH information of HOST: {}',(str(args.host),))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
|
||||
def get_ssh_info(self,host):
|
||||
@@ -921,7 +1010,15 @@ class ssh_host_admin(ssh_terminal):
|
||||
'''
|
||||
info_file = self._save_path + host + '/info.json'
|
||||
if not os.path.exists(info_file): return False
|
||||
r_data = public.aes_decrypt(public.readFile(info_file),self._pass_str)
|
||||
try:
|
||||
r_data = public.aes_decrypt(public.readFile(info_file),self._pass_str)
|
||||
except ValueError as ex:
|
||||
if str(ex).find('Incorrect AES key length') != -1:
|
||||
if os.path.exists(self._pass_file):
|
||||
os.remove(self._pass_file)
|
||||
self.__create_aes_pass()
|
||||
r_data = public.aes_decrypt(public.readFile(info_file),self._pass_str)
|
||||
|
||||
return json.loads(r_data)
|
||||
|
||||
def save_ssh_info(self,host,host_info):
|
||||
@@ -954,7 +1051,7 @@ class ssh_host_admin(ssh_terminal):
|
||||
@return bool
|
||||
'''
|
||||
if not 'sort_list' in args:
|
||||
return public.returnMsg(False,'SSH_LOGIN_ERR9')
|
||||
return public.return_msg_gettext(False,'Please pass in the [sort_list] field')
|
||||
sort_list = json.loads(args.sort_list)
|
||||
for name in sort_list.keys():
|
||||
info_file = self._save_path + name + '/info.json'
|
||||
@@ -963,7 +1060,7 @@ class ssh_host_admin(ssh_terminal):
|
||||
ssh_info = self.get_ssh_info(name)
|
||||
ssh_info['sort'] = int(sort_list[name])
|
||||
self.save_ssh_info(name,ssh_info)
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
def get_command_list(self,args = None, user_cmd = False , sys_cmd = False):
|
||||
'''
|
||||
@@ -1028,7 +1125,7 @@ class ssh_host_admin(ssh_terminal):
|
||||
command = self.get_command_list(sys_cmd=True)
|
||||
|
||||
if self.command_exists(command,args.title):
|
||||
return public.returnMsg(False,'COMMAND_NAME_EXIST')
|
||||
return public.return_msg_gettext(False,'The specified command name already exists')
|
||||
|
||||
cmd = {
|
||||
"title": args.title,
|
||||
@@ -1037,8 +1134,8 @@ class ssh_host_admin(ssh_terminal):
|
||||
|
||||
command.append(cmd)
|
||||
self.save_command(command)
|
||||
public.WriteLog(self._log_type,'ADD_COMMAND_COMMAND',(str(args.title),))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
public.write_log_gettext(self._log_type,'Add common commands [{}]',(str(args.title),))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
def get_command_find(self,args = None, title=None):
|
||||
'''
|
||||
@@ -1053,9 +1150,9 @@ class ssh_host_admin(ssh_terminal):
|
||||
if args: title = args.title.strip()
|
||||
command = self.get_command_list()
|
||||
for cmd in command:
|
||||
if cmd['title'] == title:
|
||||
if cmd['title'] == title or cmd['title'] == args.title:
|
||||
return cmd
|
||||
return public.returnMsg(False,'COMMAND_NOTEXIST')
|
||||
return public.return_msg_gettext(False,'The specified command does not exist')
|
||||
|
||||
def modify_command(self,args):
|
||||
'''
|
||||
@@ -1068,18 +1165,18 @@ class ssh_host_admin(ssh_terminal):
|
||||
}
|
||||
@return dict
|
||||
'''
|
||||
args.title = args.title.strip()
|
||||
title = args.title.strip()
|
||||
command = self.get_command_list(sys_cmd=True)
|
||||
if not self.command_exists(command,args.title):
|
||||
return public.returnMsg(False,'COMMAND_NOTEXIST')
|
||||
return public.return_msg_gettext(False,'The specified command does not exist')
|
||||
for i in range(len(command)):
|
||||
if command[i]['title'] == args.title:
|
||||
command[i]['title'] = args.new_title
|
||||
if command[i]['title'] == args.title or command[i]['title'] == title:
|
||||
command[i]['title'] = args.new_title.strip()
|
||||
command[i]['shell'] = args.shell.strip()
|
||||
break
|
||||
self.save_command(command)
|
||||
public.WriteLog(self._log_type,'EDIT_COMMAND_COMMAND',(str(args.title),))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
public.write_log_gettext(self._log_type,'Modify common commands [{}]',(str(args.title),))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
|
||||
def remove_command(self,args):
|
||||
'''
|
||||
@@ -1093,12 +1190,12 @@ class ssh_host_admin(ssh_terminal):
|
||||
args.title = args.title.strip()
|
||||
command = self.get_command_list(sys_cmd=True)
|
||||
if not self.command_exists(command,args.title):
|
||||
return public.returnMsg(False,'COMMAND_NOTEXIST')
|
||||
return public.return_msg_gettext(False,'The specified command does not exist')
|
||||
for i in range(len(command)):
|
||||
if command[i]['title'] == args.title:
|
||||
del(command[i])
|
||||
break
|
||||
|
||||
self.save_command(command)
|
||||
public.WriteLog(self._log_type,'DEL_COMMAND_COMMAND',(str(args.title),))
|
||||
return public.returnMsg(True,'SET_SUCCESS')
|
||||
public.write_log_gettext(self._log_type,'Delete common commands [{}]',(str(args.title),))
|
||||
return public.return_msg_gettext(True,'Setup successfully!')
|
||||
+33
-34
@@ -28,7 +28,7 @@ class system:
|
||||
data = session['config']
|
||||
data['webserver'] = public.get_webserver()
|
||||
#PHP版本
|
||||
phpVersions = ('52','53','54','55','56','70','71','72','73','74')
|
||||
phpVersions = public.get_php_versions()
|
||||
|
||||
data['php'] = []
|
||||
|
||||
@@ -120,7 +120,7 @@ class system:
|
||||
|
||||
|
||||
tmp['type'] = data['webserver']
|
||||
tmp['version'] = public.readFile(self.setupPath + '/'+data['webserver']+'/version.pl');
|
||||
tmp['version'] = public.xss_version(public.readFile(self.setupPath + '/'+data['webserver']+'/version.pl'))
|
||||
tmp['status'] = False
|
||||
result = public.ExecShell('/etc/init.d/' + serviceName + ' status')
|
||||
if result[0].find('running') != -1: tmp['status'] = True
|
||||
@@ -128,7 +128,7 @@ class system:
|
||||
|
||||
tmp = {}
|
||||
vfile = self.setupPath + '/phpmyadmin/version.pl'
|
||||
tmp['version'] = public.readFile(vfile)
|
||||
tmp['version'] = public.xss_version(public.readFile(vfile))
|
||||
if tmp['version']: tmp['version'] = tmp['version'].strip()
|
||||
tmp['setup'] = os.path.exists(vfile)
|
||||
tmp['status'] = pstatus
|
||||
@@ -141,12 +141,12 @@ class system:
|
||||
tmp['setup'] = os.path.exists('/etc/init.d/tomcat')
|
||||
tmp['status'] = tmp['setup']
|
||||
#if public.ExecShell('ps -aux|grep tomcat|grep -v grep')[0] == "": tmp['status'] = False
|
||||
tmp['version'] = public.readFile(self.setupPath + '/tomcat/version.pl')
|
||||
tmp['version'] = public.xss_version(public.readFile(self.setupPath + '/tomcat/version.pl'))
|
||||
data['tomcat'] = tmp
|
||||
|
||||
tmp = {}
|
||||
tmp['setup'] = os.path.exists(self.setupPath +'/mysql/bin/mysql')
|
||||
tmp['version'] = public.readFile(self.setupPath + '/mysql/version.pl')
|
||||
tmp['version'] = public.xss_version(public.readFile(self.setupPath + '/mysql/version.pl'))
|
||||
tmp['status'] = os.path.exists('/tmp/mysql.sock')
|
||||
data['mysql'] = tmp
|
||||
|
||||
@@ -162,7 +162,7 @@ class system:
|
||||
|
||||
tmp = {}
|
||||
tmp['setup'] = os.path.exists(self.setupPath +'/pure-ftpd/bin/pure-pw')
|
||||
tmp['version'] = public.readFile(self.setupPath + '/pure-ftpd/version.pl')
|
||||
tmp['version'] = public.xss_version(public.readFile(self.setupPath + '/pure-ftpd/version.pl'))
|
||||
tmp['status'] = os.path.exists('/var/run/pure-ftpd.pid')
|
||||
data['pure-ftpd'] = tmp
|
||||
data['panel'] = self.GetPanelInfo()
|
||||
@@ -281,14 +281,7 @@ class system:
|
||||
key = 'sys_version'
|
||||
version = cache.get(key)
|
||||
if version: return version
|
||||
import public
|
||||
version = public.readFile('/etc/redhat-release')
|
||||
if not version:
|
||||
version = public.readFile('/etc/issue').strip().split("\n")[0].replace('\\n','').replace('\l','').strip()
|
||||
else:
|
||||
version = version.replace('release ','').replace('Linux','').replace('(Core)','').strip()
|
||||
v_info = sys.version_info
|
||||
version = version + '(Py' + str(v_info.major) + '.' + str(v_info.minor) + '.' + str(v_info.micro) + ')'
|
||||
version = public.get_os_version()
|
||||
cache.set(key,version,600)
|
||||
return version
|
||||
|
||||
@@ -396,13 +389,17 @@ class system:
|
||||
diskInfo.append(tmp)
|
||||
return diskInfo
|
||||
|
||||
def GetDiskInfo2(self):
|
||||
def GetDiskInfo2(self, human=True):
|
||||
|
||||
#取磁盘分区信息
|
||||
key = 'sys_disk'
|
||||
diskInfo = cache.get(key)
|
||||
if diskInfo: return diskInfo
|
||||
temp = public.ExecShell("df -hT -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
|
||||
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
|
||||
if human:
|
||||
temp = public.ExecShell("df -hT -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev|grep -v overlay")[0]
|
||||
else:
|
||||
temp = public.ExecShell("df -T -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev|grep -v overlay")[0]
|
||||
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev|grep -v overlay")[0]
|
||||
temp1 = temp.split('\n')
|
||||
tempInodes1 = tempInodes.split('\n')
|
||||
diskInfo = []
|
||||
@@ -432,7 +429,7 @@ class system:
|
||||
arr['inodes'] = [inodes[1],inodes[2],inodes[3],inodes[4]]
|
||||
diskInfo.append(arr)
|
||||
except Exception as ex:
|
||||
public.WriteLog('GET_INFO',str(ex))
|
||||
public.write_log_gettext('Get Info',str(ex))
|
||||
continue
|
||||
cache.set(key,diskInfo,10)
|
||||
return diskInfo
|
||||
@@ -809,7 +806,7 @@ class system:
|
||||
import ajax
|
||||
get.status = 'True'
|
||||
ajax.ajax().setPHPMyAdmin(get)
|
||||
return public.returnMsg(True,'SYS_EXEC_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Executed successfully!')
|
||||
|
||||
if get.name == 'openlitespeed':
|
||||
if get.type == 'stop':
|
||||
@@ -818,12 +815,12 @@ class system:
|
||||
public.ExecShell('rm -f /tmp/lshttpd/*.sock* && /usr/local/lsws/bin/lswsctrl start')
|
||||
else:
|
||||
public.ExecShell('rm -f /tmp/lshttpd/*.sock* && /usr/local/lsws/bin/lswsctrl restart')
|
||||
return public.returnMsg(True,'SYS_EXEC_SUCCESS')
|
||||
return public.return_msg_gettext(True,'Executed successfully!')
|
||||
|
||||
#检查httpd配置文件
|
||||
if get.name == 'apache' or get.name == 'httpd':
|
||||
get.name = 'httpd'
|
||||
if not os.path.exists(self.setupPath+'/apache/bin/apachectl'): return public.returnMsg(True,'SYS_NOT_INSTALL_APACHE')
|
||||
if not os.path.exists(self.setupPath+'/apache/bin/apachectl'): return public.return_msg_gettext(True,'Execution failed, check if Apache installed')
|
||||
vhostPath = self.setupPath + '/panel/vhost/apache'
|
||||
if not os.path.exists(vhostPath):
|
||||
public.ExecShell('mkdir ' + vhostPath)
|
||||
@@ -835,8 +832,8 @@ class system:
|
||||
|
||||
result = public.ExecShell('ulimit -n 8192 ; ' + self.setupPath+'/apache/bin/apachectl -t')
|
||||
if result[1].find('Syntax OK') == -1:
|
||||
public.WriteLog("TYPE_SOFT",'SYS_EXEC_ERR', (str(result),))
|
||||
return public.returnMsg(False,'SYS_CONF_APACHE_ERR',(result[1].replace("\n",'<br>'),))
|
||||
public.write_log_gettext("Software manager",'Execution failed: {}', (str(result),))
|
||||
return public.return_msg_gettext(False,"Apache rule configuration error: <br><a style='color:red;'>{}</a>",(result[1].replace("\n",'<br>'),))
|
||||
|
||||
if get.type == 'restart':
|
||||
public.ExecShell('pkill -9 httpd')
|
||||
@@ -847,12 +844,14 @@ class system:
|
||||
elif get.name == 'nginx':
|
||||
vhostPath = self.setupPath + '/panel/vhost/rewrite'
|
||||
if not os.path.exists(vhostPath): public.ExecShell('mkdir ' + vhostPath)
|
||||
if not os.path.exists("/dev/shm/nginx-cache/wp"):
|
||||
public.ExecShell('mkdir -p /dev/shm/nginx-cache/wp && chown -R www.www /dev/shm/nginx-cache')
|
||||
vhostPath = self.setupPath + '/panel/vhost/nginx'
|
||||
if not os.path.exists(vhostPath):
|
||||
public.ExecShell('mkdir ' + vhostPath)
|
||||
public.ExecShell('/etc/init.d/nginx start')
|
||||
|
||||
result = public.ExecShell('ulimit -n 8192 ; nginx -t -c '+self.setupPath+'/nginx/conf/nginx.conf')
|
||||
result = public.ExecShell('ulimit -n 8192 ; '+self.setupPath+'/nginx/sbin/nginx -t -c '+self.setupPath+'/nginx/conf/nginx.conf')
|
||||
if result[1].find('perserver') != -1:
|
||||
limit = self.setupPath + '/nginx/conf/nginx.conf'
|
||||
nginxConf = public.readFile(limit)
|
||||
@@ -860,18 +859,18 @@ class system:
|
||||
nginxConf = nginxConf.replace("#limit_conn_zone $binary_remote_addr zone=perip:10m;",limitConf)
|
||||
public.writeFile(limit,nginxConf)
|
||||
public.ExecShell('/etc/init.d/nginx start')
|
||||
return public.returnMsg(True,'SYS_CONF_NGINX_REP')
|
||||
return public.return_msg_gettext(True,'Configuration file mismatch caused by reinstalling Nginx fixed')
|
||||
|
||||
if result[1].find('proxy') != -1:
|
||||
import panelSite
|
||||
panelSite.panelSite().CheckProxy(get)
|
||||
public.ExecShell('/etc/init.d/nginx start')
|
||||
return public.returnMsg(True,'SYS_CONF_NGINX_REP')
|
||||
return public.return_msg_gettext(True,'Configuration file mismatch caused by reinstalling Nginx fixed')
|
||||
|
||||
#return result
|
||||
if result[1].find('successful') == -1:
|
||||
public.WriteLog("TYPE_SOFT",'SYS_EXEC_ERR', (str(result),))
|
||||
return public.returnMsg(False,'SYS_CONF_NGINX_ERR',(result[1].replace("\n",'<br>'),))
|
||||
public.write_log_gettext("Software manager",'Execution failed: {}', (str(result),))
|
||||
return public.return_msg_gettext(False,"Nginx rule configuration error: <br><a style='color:red;'>{}</a>",(result[1].replace("\n",'<br>'),))
|
||||
|
||||
if get.type == 'start':
|
||||
self.kill_port()
|
||||
@@ -903,14 +902,14 @@ class system:
|
||||
public.ExecShell('pkill -9 nginx && sleep 1')
|
||||
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')
|
||||
public.write_log_gettext("Software manager", 'Executed successfully!',(execStr,))
|
||||
if len(result[1]) > 1 and get.name != 'pure-ftpd' and get.name != 'redis': return public.return_msg_gettext(False, '<p>Warning message: <p>' + result[1].replace('\n','<br>'))
|
||||
return public.return_msg_gettext(True,'Executed successfully!')
|
||||
|
||||
def RestartServer(self,get):
|
||||
if not public.IsRestart(): return public.returnMsg(False,'EXEC_ERR_TASK')
|
||||
if not public.IsRestart(): return public.return_msg_gettext(False,'Please run the program when all install tasks finished!')
|
||||
public.ExecShell("sync && init 6 &")
|
||||
return public.returnMsg(True,'SYS_REBOOT')
|
||||
return public.return_msg_gettext(True,'Command sent successfully!')
|
||||
|
||||
def kill_port(self):
|
||||
public.ExecShell('pkill -9 httpd')
|
||||
@@ -931,7 +930,7 @@ class system:
|
||||
def ReWeb(self,get):
|
||||
public.ExecShell("/etc/init.d/bt start")
|
||||
public.writeFile('data/restart.pl','True')
|
||||
return public.returnMsg(True,'PANEL_WAS_RESTART')
|
||||
return public.return_msg_gettext(True,'Panel restarted')
|
||||
|
||||
|
||||
#修复面板
|
||||
|
||||
+9
-3
@@ -27,8 +27,11 @@ class tomcat:
|
||||
self.__ENGINE = self.__TREE.findall('Service/Engine')[0];
|
||||
|
||||
#获取虚拟主机列表
|
||||
def GetVhosts(self):
|
||||
Hosts = self.__ENGINE.getchildren();
|
||||
def GetVhosts(self):
|
||||
try:
|
||||
Hosts = self.__ENGINE.getchildren()
|
||||
except:
|
||||
Hosts = list(self.__ENGINE)
|
||||
data = []
|
||||
for host in Hosts:
|
||||
if host.tag != 'Host': continue;
|
||||
@@ -63,7 +66,10 @@ class tomcat:
|
||||
|
||||
#获取指定虚拟主机
|
||||
def GetVhost(self,name):
|
||||
Hosts = self.__ENGINE.getchildren();
|
||||
try:
|
||||
Hosts = self.__ENGINE.getchildren()
|
||||
except:
|
||||
Hosts = list(self.__ENGINE)
|
||||
for host in Hosts:
|
||||
if host.tag != 'Host': continue;
|
||||
if host.attrib['name'] == name:
|
||||
|
||||
+73
-73
@@ -65,8 +65,8 @@ def set_panel_pwd(password,ncli = False):
|
||||
result = sql.table('users').where('id=?',(1,)).setField('password',public.md5(password))
|
||||
username = sql.table('users').where('id=?',(1,)).getField('username')
|
||||
if ncli:
|
||||
print("|-%s: " % public.GetMsg("USER_NAME") + username)
|
||||
print("|-%s: " % public.GetMsg("NEW_PASS") + password)
|
||||
print("|-%s: " % public.get_msg_gettext('Username') + username)
|
||||
print("|-%s: " % public.get_msg_gettext('New password') + password)
|
||||
else:
|
||||
print(username)
|
||||
|
||||
@@ -107,28 +107,28 @@ echo '---------------------------------------------------------------------'
|
||||
#封装
|
||||
def PackagePanel():
|
||||
print('========================================================')
|
||||
print('|-%s...' % public.GetMsg("CLEARING_LOG")),
|
||||
public.M('logs').where('id!=?',(0,)).delete();
|
||||
print('|-%s...' % public.get_msg_gettext('Clearing log info')),
|
||||
public.M('logs').where('id!=?',(0,)).delete()
|
||||
print('\t\t\033[1;32m[done]\033[0m')
|
||||
print('|-%s...' % public.GetMsg("CLEARING_TASK_HISTORY")),
|
||||
public.M('tasks').where('id!=?',(0,)).delete();
|
||||
print('|-%s...' % public.get_msg_gettext('Clearing task history')),
|
||||
public.M('tasks').where('id!=?',(0,)).delete()
|
||||
print('\t\t\033[1;32m[done]\033[0m')
|
||||
print('|-%s...' % public.GetMsg("CLEARING_NET_MO")),
|
||||
public.M('network').dbfile('system').where('id!=?',(0,)).delete();
|
||||
print('|-%s...' % public.get_msg_gettext('Clearing network monitoring records')),
|
||||
public.M('network').dbfile('system').where('id!=?',(0,)).delete()
|
||||
print('\t\033[1;32m[done]\033[0m')
|
||||
print('|-%s...' % public.GetMsg("CLEARING_CPU_MO")),
|
||||
public.M('cpuio').dbfile('system').where('id!=?',(0,)).delete();
|
||||
print('|-%s...' % public.get_msg_gettext('Clearing CPU monitoring records')),
|
||||
public.M('cpuio').dbfile('system').where('id!=?',(0,)).delete()
|
||||
print('\t\033[1;32m[done]\033[0m')
|
||||
print('|-%s...' % public.GetMsg("CLEARING_DISK_MO")),
|
||||
public.M('diskio').dbfile('system').where('id!=?',(0,)).delete();
|
||||
print('|-%s...' % public.get_msg_gettext('Clearing disk monitoring records')),
|
||||
public.M('diskio').dbfile('system').where('id!=?',(0,)).delete()
|
||||
print('\t\033[1;32m[done]\033[0m')
|
||||
print('|-%s...' % public.GetMsg('CLEARING_IP')),
|
||||
print('|-%s...' % public.get_msg_gettext('Clearing IP info')),
|
||||
os.system('rm -f /www/server/panel/data/iplist.txt')
|
||||
os.system('rm -f /www/server/panel/data/address.pl')
|
||||
os.system('rm -f /www/server/panel/data/*.login')
|
||||
os.system('rm -f /www/server/panel/data/domain.conf')
|
||||
print('\t\033[1;32m[done]\033[0m')
|
||||
print('|-%s...' % public.GetMsg("CLEARING_SYS_HISTORY")),
|
||||
print('|-%s...' % public.get_msg_gettext('Clearing system history')),
|
||||
command = '''cat /dev/null > /var/log/boot.log
|
||||
cat /dev/null > /var/log/btmp
|
||||
cat /dev/null > /var/log/cron
|
||||
@@ -154,8 +154,8 @@ history -c
|
||||
port = public.readFile('data/port.pl').strip();
|
||||
public.M('config').where("id=?",('1',)).setField('status',0);
|
||||
print('========================================================')
|
||||
print('\033[1;32m|-%s\033[0m' % public.GetMsg("PANEL_TIPS"))
|
||||
print('\033[1;41m|-%s: http://{SERVERIP}:' % public.GetMsg("PANEL_INIT_ADD")+port+'/install\033[0m')
|
||||
print('\033[1;32m|-%s\033[0m' % public.get_msg_gettext('The panel is packaged successfully. Please do NOT log in to the panel to do any other operations!'))
|
||||
print('\033[1;41m|-%s: http://{SERVERIP}:' % public.get_msg_gettext('Panel initialization address')+port+'/install\033[0m')
|
||||
|
||||
#清空正在执行的任务
|
||||
def CloseTask():
|
||||
@@ -163,7 +163,7 @@ def CloseTask():
|
||||
os.system("kill `ps -ef |grep 'python panelSafe.pyc'|grep -v grep|grep -v panelExec|awk '{print $2}'`");
|
||||
os.system("kill `ps -ef |grep 'install_soft.sh'|grep -v grep|grep -v panelExec|awk '{print $2}'`");
|
||||
os.system('/etc/init.d/bt restart');
|
||||
print(public.GetMsg("CLEAR_TASK",(int(ncount),)))
|
||||
print(public.get_msg_gettext('Successfully cleared {} tasks!',(int(ncount),)))
|
||||
|
||||
#自签证书
|
||||
def CreateSSL():
|
||||
@@ -217,7 +217,7 @@ def ClearSystem():
|
||||
count += tmp_count;
|
||||
total += tmp_total;
|
||||
print('=======================================================================')
|
||||
print('\033[1;32m|-%s\033[0m' % public.GetMsg("CLEAR_RUBBISH",(str(count),ToSize(total))));
|
||||
print('\033[1;32m|-%s\033[0m' % public.get_msg_gettext('System rubbish cleared, totally deleted [{}] files, freed disk space [{}]',(str(count),ToSize(total))));
|
||||
|
||||
#清理邮件日志
|
||||
def ClearMail():
|
||||
@@ -242,11 +242,11 @@ def ClearMail():
|
||||
os.remove(filename)
|
||||
print('\t\033[1;32m[OK]\033[0m')
|
||||
num += 1
|
||||
print(public.GetMsg("CLEAR_RUBBISH1",(dpath,str(num),ToSize(size))))
|
||||
print(public.get_msg_gettext('|-Cleared [{}], deleted [{}] files, freed disk space [{}]',(dpath,str(num),ToSize(size))))
|
||||
total += size;
|
||||
count += num;
|
||||
print('=======================================================================')
|
||||
print(public.GetMsg('CLEAR_RUBBISH2',(str(count),ToSize(total))))
|
||||
print(public.get_msg_gettext('|-Spool cleared, deleted [{}] files, freed disk space [{}]',(str(count),ToSize(total))))
|
||||
return total,count
|
||||
|
||||
#清理php_session文件
|
||||
@@ -254,7 +254,7 @@ def ClearSession():
|
||||
spath = '/tmp'
|
||||
total = count = 0;
|
||||
import shutil
|
||||
print(public.GetMsg("CLEAR_PHP_SESSION"));
|
||||
print(public.get_msg_gettext('|-Clearing PHP Session ...'));
|
||||
for d in os.listdir(spath):
|
||||
if d.find('sess_') == -1: continue;
|
||||
filename = spath + '/' + d;
|
||||
@@ -267,7 +267,7 @@ def ClearSession():
|
||||
os.remove(filename)
|
||||
print('\t\033[1;32m[OK]\033[0m')
|
||||
count += 1;
|
||||
print(public.GetMsg("CLEAR_PHP_SESSION1",(str(count),ToSize(total))))
|
||||
print(public.get_msg_gettext('|-PHP session cleared, deleted [{}] files, freed disk space [{}]',(str(count),ToSize(total))))
|
||||
return total,count
|
||||
|
||||
#清空回收站
|
||||
@@ -288,7 +288,7 @@ def ClearOther():
|
||||
]
|
||||
|
||||
total = count = 0;
|
||||
print(public.GetMsg('CLEAR_RUBBISH3'));
|
||||
print(public.get_msg_gettext('|-Clearing up temporary files and site logs...'));
|
||||
for c in clearPath:
|
||||
for d in os.listdir(c['path']):
|
||||
if d.find(c['find']) == -1: continue;
|
||||
@@ -304,7 +304,7 @@ def ClearOther():
|
||||
count += 1;
|
||||
public.serviceReload();
|
||||
os.system('sleep 1 && /etc/init.d/bt reload > /dev/null &');
|
||||
print(public.GetMsg("CLEAR_RUBBISH4",(str(count),ToSize(total))))
|
||||
print(public.get_msg_gettext('|-Temporary files and site logs cleared, deleted [{}] files, freed disk space [{}]',(str(count),ToSize(total))))
|
||||
return total,count
|
||||
|
||||
#关闭普通日志
|
||||
@@ -336,14 +336,14 @@ def set_panel_username(username = None):
|
||||
sql = db.Sql()
|
||||
if username:
|
||||
if len(username) < 5:
|
||||
print(public.GetMsg("USER_NAME_LEN_ERR"))
|
||||
print(public.get_msg_gettext('|-ERROR, username cannot be less than 5 characters'))
|
||||
return;
|
||||
if username in ['admin','root']:
|
||||
print(public.GetMsg("EASY_NAME"))
|
||||
print(public.get_msg_gettext('|-ERROR, cannot use too simple username'))
|
||||
return;
|
||||
|
||||
sql.table('users').where('id=?',(1,)).setField('username',username)
|
||||
print(public.GetMsg("NEW_NAME",(username,)))
|
||||
print(public.get_msg_gettext('|-New username: {}',(username,)))
|
||||
return;
|
||||
|
||||
username = sql.table('users').where('id=?',(1,)).getField('username')
|
||||
@@ -365,14 +365,14 @@ def setup_idc():
|
||||
pFile = panelPath + '/static/language/Simplified_Chinese/public.json'
|
||||
pInfo = json.loads(public.readFile(pFile))
|
||||
pInfo['BRAND'] = idcInfo['msg']['name']
|
||||
pInfo['PRODUCT'] = public.GetMsg("WITH_BT_CUSTOM_EDITION")
|
||||
pInfo['PRODUCT'] = public.get_msg_gettext('Customized edition with aaPanel')
|
||||
pInfo['NANE'] = pInfo['BRAND'] + pInfo['PRODUCT']
|
||||
public.writeFile(pFile,json.dumps(pInfo))
|
||||
tFile = panelPath + '/data/title.pl'
|
||||
titleNew = (pInfo['BRAND'] + public.GetMsg("PANEL")).encode('utf-8')
|
||||
titleNew = (pInfo['BRAND'] + public.get_msg_gettext('Failed,cannot delete current port of the panel!')).encode('utf-8')
|
||||
if os.path.exists(tFile):
|
||||
title = public.readFile(tFile).strip()
|
||||
if title == public.GetMsg("NAME") or title == '': public.writeFile(tFile,titleNew)
|
||||
if title == public.get_msg_gettext('aaPanel') or title == '': public.writeFile(tFile,titleNew)
|
||||
else:
|
||||
public.writeFile(tFile,titleNew)
|
||||
return True
|
||||
@@ -381,48 +381,48 @@ def setup_idc():
|
||||
#将插件升级到6.0
|
||||
def update_to6():
|
||||
print("====================================================")
|
||||
print(public.GetMsg("PLUG_UPDATEING"))
|
||||
print(public.get_msg_gettext('Updating plugin...'))
|
||||
print("====================================================")
|
||||
download_address = public.get_url()
|
||||
exlodes = ['gitlab','pm2','mongodb','deployment_jd','logs','docker','beta','btyw']
|
||||
for pname in os.listdir('plugin/'):
|
||||
if not os.path.isdir('plugin/' + pname): continue
|
||||
if pname in exlodes: continue
|
||||
print("|-正在升级【%s】..." % pname),
|
||||
download_url = download_address + '/install/plugin/' + pname + '/install.sh';
|
||||
print(public.get_msg_gettext("|-Upgrading [{}]...",(pname,))),
|
||||
download_url = download_address + '/install/plugin/' + pname + '/install.sh'
|
||||
to_file = '/tmp/%s.sh' % pname
|
||||
public.downloadFile(download_url,to_file);
|
||||
os.system('/bin/bash ' + to_file + ' install &> /tmp/plugin_update.log 2>&1');
|
||||
print(" \033[32m[%s]\033[0m" % public.GetMsg("SUCCESS"))
|
||||
public.downloadFile(download_url,to_file)
|
||||
os.system('/bin/bash ' + to_file + ' install &> /tmp/plugin_update.log 2>&1')
|
||||
print(" \033[32m[%s]\033[0m" % public.get_msg_gettext('Login succeeded, loading...'))
|
||||
print("====================================================")
|
||||
print("\033[32m%s\033[0m" % public.GetMsg("PLUG_UPDATE_TO_6"))
|
||||
print("\033[32m%s\033[0m" % public.get_msg_gettext('All plugins successfully updated to 6.0 compatible!'))
|
||||
print("====================================================")
|
||||
|
||||
#命令行菜单
|
||||
def bt_cli():
|
||||
raw_tip = "==============================================="
|
||||
print("===============%s==================" % public.GetMsg("PANEL_SHELL"))
|
||||
print("(01) %s (08) %s" % (public.GetMsg("RESTART_PANEL"),public.GetMsg("CHANGE_PANEL_PORT")))
|
||||
print("(02) %s (09) %s" % (public.GetMsg("STOP_PANEL"),public.GetMsg("CLEAR_PANEL_CACHE")))
|
||||
print("(03) %s (10) %s" % (public.GetMsg("START_PANEL"),public.GetMsg("CLEAR_PANEL_LIMIT")))
|
||||
print("(04) %s (11) %s" % (public.GetMsg("RELOAD_PANEL"),public.GetMsg("CANCEL_ENTRY")))
|
||||
print("(05) %s (12) %s" % (public.GetMsg("CHANGE_PANEL_PASS"),public.GetMsg("CANCEL_DOMAIN_BIND")))
|
||||
print("(06) %s (13) %s" % (public.GetMsg("CHANGE_PANEL_USER"),public.GetMsg("CANCEL_IP_LIMIT")))
|
||||
print("(07) %s (14) %s" % (public.GetMsg("CHANGE_MYSQL_PASS_FORCE"),public.GetMsg("GET_PANEL_DEFAULT_MSG")))
|
||||
print("(00) %s (15) %s" % (public.GetMsg("CANCEL"),public.GetMsg("CLEAR_SYS_RUBBISH")))
|
||||
print("===============%s==================" % public.get_msg_gettext('aaPanel CLI'))
|
||||
print("(01) %s (08) %s" % (public.get_msg_gettext('Restart panel'),public.get_msg_gettext('Change panel port')))
|
||||
print("(02) %s (09) %s" % (public.get_msg_gettext('Stop panel'),public.get_msg_gettext('Clear panel cache')))
|
||||
print("(03) %s (10) %s" % (public.get_msg_gettext('Restart panel'),public.get_msg_gettext('Clear login limit')))
|
||||
print("(04) %s (11) %s" % (public.get_msg_gettext('Reload panel'),public.get_msg_gettext('Cancel entrance limit')))
|
||||
print("(05) %s (12) %s" % (public.get_msg_gettext('Change panel password'),public.get_msg_gettext('Cancel domain binding limit')))
|
||||
print("(06) %s (13) %s" % (public.get_msg_gettext('Change panel username'),public.get_msg_gettext('Cacel IP access limit')))
|
||||
print("(07) %s (14) %s" % (public.get_msg_gettext('Forcibly change MySQL root password'),public.get_msg_gettext('View panel default info')))
|
||||
print("(00) %s (15) %s" % (public.get_msg_gettext('Task cancelled!'),public.get_msg_gettext('Clear system rubbish')))
|
||||
print(raw_tip)
|
||||
try:
|
||||
u_input = input(public.GetMsg("INPUT_CMD_NUM"))
|
||||
u_input = input(public.get_msg_gettext('Pls enter command number:'))
|
||||
if sys.version_info[0] == 3: u_input = int(u_input)
|
||||
except: u_input = 0
|
||||
nums = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
|
||||
if not u_input in nums:
|
||||
print(raw_tip)
|
||||
print(public.GetMsg("CANCELLED"))
|
||||
print(public.get_msg_gettext('Cacelled!'))
|
||||
exit()
|
||||
|
||||
print(raw_tip)
|
||||
print(public.GetMsg("EXECUTING",(u_input,)))
|
||||
print(public.get_msg_gettext('Executing ({})...',(u_input,)))
|
||||
print(raw_tip)
|
||||
|
||||
if u_input == 1:
|
||||
@@ -435,55 +435,55 @@ def bt_cli():
|
||||
os.system("/etc/init.d/bt reload")
|
||||
elif u_input == 5:
|
||||
if sys.version_info[0] == 2:
|
||||
input_pwd = raw_input(public.GetMsg("INPUT_NEW_PASS"))
|
||||
input_pwd = raw_input(public.get_msg_gettext('Pls enter new password: '))
|
||||
else:
|
||||
input_pwd = input(public.GetMsg("INPUT_NEW_PASS"))
|
||||
input_pwd = input(public.get_msg_gettext('Pls enter new password: '))
|
||||
set_panel_pwd(input_pwd.strip(),True)
|
||||
elif u_input == 6:
|
||||
if sys.version_info[0] == 2:
|
||||
input_user = raw_input(public.GetMsg("INPUT_NEW_USER"))
|
||||
input_user = raw_input(public.get_msg_gettext('Pls enter new username(>5 characters): '))
|
||||
else:
|
||||
input_user = input(public.GetMsg("INPUT_NEW_USER"))
|
||||
input_user = input(public.get_msg_gettext('Pls enter new username(>5 characters): '))
|
||||
set_panel_username(input_user.strip())
|
||||
elif u_input == 7:
|
||||
if sys.version_info[0] == 2:
|
||||
input_mysql = raw_input(public.GetMsg("INPUT_NEW_MYSQL_PASS"))
|
||||
input_mysql = raw_input(public.get_msg_gettext('Pls enter new MySQL root password:'))
|
||||
else:
|
||||
input_mysql = input(public.GetMsg("INPUT_NEW_MYSQL_PASS"))
|
||||
input_mysql = input(public.get_msg_gettext('Pls enter new MySQL root password:'))
|
||||
if not input_mysql:
|
||||
print(public.GetMsg("PASS_NOT_EMPTY"))
|
||||
return;
|
||||
print(public.get_msg_gettext('|-ERROR, password cannot be empty'))
|
||||
return
|
||||
|
||||
if len(input_mysql) < 8:
|
||||
print(public.GetMsg("PASS_LEN_ERR"))
|
||||
return;
|
||||
print(public.get_msg_gettext('|-ERROR, password cannot be less than 8 characters'))
|
||||
return
|
||||
|
||||
import re
|
||||
rep = "^[\w@\._]+$"
|
||||
if not re.match(rep, input_mysql):
|
||||
print(public.GetMsg("PASS_SPECIAL_CHARACTRES_ERR"))
|
||||
return;
|
||||
print(public.get_msg_gettext('|-ERROR, password cannot contain special characters'))
|
||||
return
|
||||
|
||||
print(input_mysql)
|
||||
set_mysql_root(input_mysql.strip())
|
||||
elif u_input == 8:
|
||||
input_port = input(public.GetMsg("INPUT_NEW_PANEL_PORT"))
|
||||
input_port = input(public.get_msg_gettext('Pls enter new panel port: '))
|
||||
if sys.version_info[0] == 3: input_port = int(input_port)
|
||||
if not input_port:
|
||||
print(public.GetMsg("INPUT_PANEL_PORT_ERR"))
|
||||
return;
|
||||
print(public.get_msg_gettext('|-ERROR, no valid port entered'))
|
||||
return
|
||||
if input_port in [80,443,21,20,22]:
|
||||
print(public.GetMsg("CANT_USE_USUALLY_PORT_ERR"))
|
||||
return;
|
||||
print(public.get_msg_gettext('|-ERROR, pls do NOT use the common port as panel port'))
|
||||
return
|
||||
old_port = int(public.readFile('data/port.pl'))
|
||||
if old_port == input_port:
|
||||
print(public.GetMsg("NEW_PORT_SAMEAS_OLD"))
|
||||
return;
|
||||
print(public.get_msg_gettext('|-ERROR, new port is the same as current panel port, no need to change'))
|
||||
return
|
||||
|
||||
is_exists = public.ExecShell("lsof -i:%s" % input_port)
|
||||
if len(is_exists[0]) > 5:
|
||||
print(public.GetMsg("PORT_ALREADY_IN_USE"))
|
||||
return;
|
||||
print(public.get_msg_gettext('|-ERROR, specified port is already in use'))
|
||||
return
|
||||
|
||||
public.writeFile('data/port.pl',str(input_port))
|
||||
if os.path.exists("/usr/bin/firewall-cmd"):
|
||||
@@ -507,17 +507,17 @@ def bt_cli():
|
||||
auth_file = 'data/admin_path.pl'
|
||||
if os.path.exists(auth_file): os.remove(auth_file)
|
||||
os.system("/etc/init.d/bt reload")
|
||||
print(public.GetMsg("CHANGE_LIMITED_CANCEL"))
|
||||
print(public.get_msg_gettext('|-Entrance limit cancelled'))
|
||||
elif u_input == 12:
|
||||
auth_file = 'data/domain.conf'
|
||||
if os.path.exists(auth_file): os.remove(auth_file)
|
||||
os.system("/etc/init.d/bt reload")
|
||||
print(public.GetMsg("CHANGE_DOMAIN_CANCEL"))
|
||||
print(public.get_msg_gettext('|-Domain limit cancelled'))
|
||||
elif u_input == 13:
|
||||
auth_file = 'data/limitip.conf'
|
||||
if os.path.exists(auth_file): os.remove(auth_file)
|
||||
os.system("/etc/init.d/bt reload")
|
||||
print(public.GetMsg("CHANGE_IP_CANCEL"))
|
||||
print(public.get_msg_gettext('|-IP access limit cancelled'))
|
||||
elif u_input == 14:
|
||||
os.system("/etc/init.d/bt default")
|
||||
elif u_input == 15:
|
||||
|
||||
+120
-70
@@ -12,43 +12,74 @@ from BTPanel import session,cache,json_header
|
||||
from flask import request,redirect,g
|
||||
|
||||
class userlogin:
|
||||
|
||||
limit_expire_time = 0
|
||||
def request_post(self,post):
|
||||
if not hasattr(post, 'username') or not hasattr(post, 'password'):
|
||||
return public.returnJson(False,'LOGIN_USER_EMPTY'),json_header
|
||||
return public.returnJson(False,'User name or password cannot be empty!'),json_header
|
||||
|
||||
self.error_num(False)
|
||||
if self.limit_address('?') < 1: return public.returnJson(False,'LOGIN_ERR_LIMIT'),json_header
|
||||
if self.limit_address('?') < 1: return public.returnJson(False,'You have failed to log in many times。 Please wait for {} seconds and try again!'.format(int(self.limit_expire_time - time.time()))),json_header
|
||||
# if self.limit_address('?') < 1: return public.returnJson(False,'You cannot login now because login failed too many times!'),json_header
|
||||
post.username = post.username.strip()
|
||||
|
||||
# 核验用户名密码格式
|
||||
if len(post.username) != 32: return public.return_msg_gettext(False,'Disk inode has been exhausted, the panel has attempted to release the inode. Please try again ...'),json_header
|
||||
if len(post.password) != 32: return public.return_msg_gettext(False,'Disk inode has been exhausted, the panel has attempted to release the inode. Please try again ...'),json_header
|
||||
if not re.match(r"^\w+$",post.username): return public.return_msg_gettext(False,'Disk inode has been exhausted, the panel has attempted to release the inode. Please try again ...'),json_header
|
||||
if not re.match(r"^\w+$",post.password): return public.return_msg_gettext(False,'Disk inode has been exhausted, the panel has attempted to release the inode. Please try again ...'),json_header
|
||||
last_login_token = session.get('last_login_token',None)
|
||||
if not last_login_token:
|
||||
public.write_log_gettext('Login','Verification code error, account number: {}, verification code: {}, login IP: {}',('****','****',public.GetClientIp()))
|
||||
return public.returnJson(False,"Verification failed, please refresh the page and log in again!"),json_header
|
||||
|
||||
public.chdck_salt()
|
||||
sql = db.Sql()
|
||||
user_list = sql.table('users').field('id,username,password,salt').select()
|
||||
userInfo = None
|
||||
for u_info in user_list:
|
||||
if public.md5(u_info['username']) == post.username:
|
||||
userInfo = u_info
|
||||
user_plugin_file = '{}/users_main.py'.format(public.get_plugin_path('users'))
|
||||
if os.path.exists(user_plugin_file):
|
||||
user_list = sql.table('users').field('id,username,password,salt').select()
|
||||
for u_info in user_list:
|
||||
if public.md5(public.md5(u_info['username'] + last_login_token)) == post.username:
|
||||
userInfo = u_info
|
||||
else:
|
||||
userInfo = sql.table('users').where('id=?',1).field('id,username,password,salt').find()
|
||||
|
||||
|
||||
if 'code' in session:
|
||||
if session['code'] and not 'is_verify_password' in session:
|
||||
if not hasattr(post, 'code'): return public.returnJson(False,'Verification code can not be empty!'),json_header
|
||||
if not re.match(r"^\w+$",post.code): return public.returnJson(False,'Verification code is incorrect, please try again!'),json_header
|
||||
if not public.checkCode(post.code):
|
||||
public.WriteLog('TYPE_LOGIN','LOGIN_ERR_CODE',('****','****',public.GetClientIp()))
|
||||
return public.returnJson(False,'CODE_ERR'),json_header
|
||||
public.write_log_gettext('Login','Verification code is incorrect, Username:{}, Verification Code:{}, Login IP:{}',('****','****',public.GetClientIp()))
|
||||
return public.returnJson(False,'Verification code is incorrect, please try again!'),json_header
|
||||
try:
|
||||
if not userInfo['salt']:
|
||||
if not userInfo:
|
||||
public.write_log_gettext('Login','Wrong password, account: {}, password: {}, login IP: {}',('****','******',public.GetClientIp()))
|
||||
num = self.limit_address('+')
|
||||
if not num: return public.returnJson(False,'You have failed to log in many times, please wait {} seconds and try again!'.format(int(self.limit_expire_time - time.time()))),json_header
|
||||
return public.returnJson(False,'Username or password is wrong, <span style="color:red;">Please refresh the page and try again</span>, you can try again [{}] times'.format(num)),json_header
|
||||
|
||||
if userInfo and not userInfo['salt']:
|
||||
public.chdck_salt()
|
||||
userInfo = sql.table('users').where('id=?',(userInfo['id'],)).field('id,username,password,salt').find()
|
||||
|
||||
password = public.md5(post.password.strip() + userInfo['salt'])
|
||||
if public.md5(userInfo['username']) != post.username or userInfo['password'] != password:
|
||||
public.WriteLog('TYPE_LOGIN','LOGIN_ERR_PASS',('****','******',public.GetClientIp()))
|
||||
s_username = public.md5(public.md5(userInfo['username'] + last_login_token))
|
||||
if s_username != post.username or userInfo['password'] != password:
|
||||
public.write_log_gettext('Login','Password is incorrect, Username:{}, Password:{}, Login IP:{}',('****','******',public.GetClientIp()))
|
||||
num = self.limit_address('+')
|
||||
return public.returnJson(False,'LOGIN_USER_ERR',(str(num),)),json_header
|
||||
if not num: return public.returnJson(False,'You have failed to log in many times, please wait {} seconds and try again!'.format(int(self.limit_expire_time - time.time()))),json_header
|
||||
return public.returnJson(False,'Invalid username or password. You have [{}] times left to try!',(str(num),)),json_header
|
||||
_key_file = "/www/server/panel/data/two_step_auth.txt"
|
||||
#登陆告警
|
||||
public.run_thread(public.login_send_body,("Userinfo",userInfo['username'],public.GetClientIp(),str(request.environ.get('REMOTE_PORT'))))
|
||||
|
||||
# 密码过期检测
|
||||
if sys.path[0] != 'class/': sys.path.insert(0,'class/')
|
||||
if not public.password_expire_check():
|
||||
session['password_expire'] = True
|
||||
|
||||
# public.login_send_body("Userinfo",userInfo['username'],public.GetClientIp(),str(request.environ.get('REMOTE_PORT')))
|
||||
if hasattr(post,'vcode'):
|
||||
if not re.match(r"^\d+$",post.vcode): return public.returnJson(False,'Incorrect format of verification code'),json_header
|
||||
if self.limit_address('?',v="vcode") < 1: return public.returnJson(False,'You have failed verification many times, forbidden for 10 minutes'),json_header
|
||||
import pyotp
|
||||
secret_key = public.readFile(_key_file)
|
||||
@@ -62,6 +93,7 @@ class userlogin:
|
||||
num = self.limit_address('++',v="vcode")
|
||||
return public.returnJson(False, 'Invalid Verification code. You have [{}] times left to try!'.format(num)), json_header
|
||||
now = int(time.time())
|
||||
# public.run_thread(public.login_send_body,("account",userInfo['username'],public.GetClientIp(),str(int(request.environ.get('REMOTE_PORT')))))
|
||||
public.writeFile("/www/server/panel/data/dont_vcode_ip.txt",json.dumps({"client_ip":public.GetClientIp(),"add_time":now}))
|
||||
self.limit_address('--',v="vcode")
|
||||
self.set_cdn_host(post)
|
||||
@@ -70,6 +102,7 @@ class userlogin:
|
||||
acc_client_ip = self.check_two_step_auth()
|
||||
|
||||
if not os.path.exists(_key_file) or acc_client_ip:
|
||||
# public.run_thread(public.login_send_body,("account",userInfo['username'],public.GetClientIp(),str(int(request.environ.get('REMOTE_PORT')))))
|
||||
self.set_cdn_host(post)
|
||||
return self._set_login_session(userInfo)
|
||||
self.limit_address('-')
|
||||
@@ -82,28 +115,30 @@ class userlogin:
|
||||
public.ExecShell("rm -f /www/wwwlogs/*log")
|
||||
public.ServiceReload()
|
||||
return public.returnJson(False,'USER_INODE_ERR'),json_header
|
||||
public.WriteLog('TYPE_LOGIN','LOGIN_ERR_PASS',('****','******',public.GetClientIp()))
|
||||
public.write_log_gettext('Login','Password is incorrect, Username:{}, Password:{}, Login IP:{}',('****','******',public.GetClientIp()))
|
||||
num = self.limit_address('+')
|
||||
return public.returnJson(False,'LOGIN_USER_ERR',(str(num),)),json_header
|
||||
if not num: return public.returnJson(False,'You have failed to log in many times, please wait {} seconds and try again!'.format(int(self.limit_expire_time - time.time()))),json_header
|
||||
return public.returnJson(False,'Invalid username or password. You have [{}] times left to try!',(str(num),)),json_header
|
||||
|
||||
def request_tmp(self,get):
|
||||
try:
|
||||
if not hasattr(get,'tmp_token'): return public.returnJson(False,'INIT_ARGS_ERR'),json_header
|
||||
if not hasattr(get,'tmp_token'): return public.returnJson(False,'Parameter ERROR!'),json_header
|
||||
if len(get.tmp_token) == 48:
|
||||
return self.request_temp(get)
|
||||
if len(get.tmp_token) != 64: return public.returnJson(False,'INIT_ARGS_ERR'),json_header
|
||||
if not re.match(r"^\w+$",get.tmp_token):return public.returnJson(False,'INIT_ARGS_ERR'),json_header
|
||||
if len(get.tmp_token) != 64: return public.returnJson(False,'Parameter ERROR!'),json_header
|
||||
if not re.match(r"^\w+$",get.tmp_token):return public.returnJson(False,'Parameter ERROR!'),json_header
|
||||
save_path = '/www/server/panel/config/api.json'
|
||||
data = json.loads(public.ReadFile(save_path))
|
||||
if not 'tmp_token' in data or not 'tmp_time' in data: return public.returnJson(False,'VERIFICATION_FAILED'),json_header
|
||||
if (time.time() - data['tmp_time']) > 120: return public.returnJson(False,'EXPIRED_TOKEN'),json_header
|
||||
if get.tmp_token != data['tmp_token']: return public.returnJson(False,'INIT_TOKEN_ERR'),json_header
|
||||
if not 'tmp_token' in data or not 'tmp_time' in data: return public.returnJson(False,'Verification failed'),json_header
|
||||
if (time.time() - data['tmp_time']) > 120: return public.returnJson(False,'Expired Token'),json_header
|
||||
if get.tmp_token != data['tmp_token']: return public.returnJson(False,'Invalid Token!'),json_header
|
||||
userInfo = public.M('users').where("id=?",(1,)).field('id,username').find()
|
||||
session['login'] = True
|
||||
session['username'] = userInfo['username']
|
||||
session['tmp_login'] = True
|
||||
session['uid'] = userInfo['id']
|
||||
public.WriteLog('TYPE_LOGIN','LOGIN_SUCCESS',(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
|
||||
ids = public.write_log_gettext('Login','Login success',(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
|
||||
public.cache_set(public.GetClientIp() + ":" + str(request.environ.get('REMOTE_PORT')), ids)
|
||||
self.limit_address('-')
|
||||
cache.delete('panelNum')
|
||||
cache.delete('dologin')
|
||||
@@ -121,28 +156,32 @@ class userlogin:
|
||||
|
||||
def request_temp(self,get):
|
||||
try:
|
||||
if len(get.__dict__.keys()) > 2: return public.getMsg('INIT_ARGS_ERR')
|
||||
if not hasattr(get,'tmp_token'): return public.getMsg('INIT_ARGS_ERR')
|
||||
if len(get.tmp_token) != 48: return public.getMsg('INIT_ARGS_ERR')
|
||||
if not re.match(r"^\w+$",get.tmp_token):return public.getMsg('INIT_ARGS_ERR')
|
||||
if len(get.__dict__.keys()) > 2: return public.get_msg_gettext('Parameter ERROR!')
|
||||
if not hasattr(get,'tmp_token'): return public.get_msg_gettext('Parameter ERROR!')
|
||||
if len(get.tmp_token) != 48: return public.get_msg_gettext('Parameter ERROR!')
|
||||
if not re.match(r"^\w+$",get.tmp_token):return public.get_msg_gettext('Parameter ERROR!')
|
||||
skey = public.GetClientIp() + '_temp_login'
|
||||
if not public.get_error_num(skey,10): return public.getMsg('AUTH_FAILED')
|
||||
if not public.get_error_num(skey,10): return public.get_msg_gettext('10 consecutive authentication failures are prohibited for 1 hour')
|
||||
s_time = int(time.time())
|
||||
if public.M('temp_login').where('state=? and expire>?',(0,s_time)).field('id,token,salt,expire').count()==0:
|
||||
public.set_error_num(skey)
|
||||
return public.get_msg_gettext('Verification failed')
|
||||
|
||||
data = public.M('temp_login').where('state=? and expire>?',(0,s_time)).field('id,token,salt,expire').find()
|
||||
if not data:
|
||||
public.set_error_num(skey)
|
||||
return public.getMsg('VERIFICATION_FAILED')
|
||||
return public.get_msg_gettext('Verification failed')
|
||||
if not isinstance(data,dict):
|
||||
public.set_error_num(skey)
|
||||
return public.getMsg('VERIFICATION_FAILED')
|
||||
return public.get_msg_gettext('Verification failed')
|
||||
r_token = public.md5(get.tmp_token + data['salt'])
|
||||
if r_token != data['token']:
|
||||
public.set_error_num(skey)
|
||||
return public.getMsg('VERIFICATION_FAILED')
|
||||
return public.get_msg_gettext('Verification failed')
|
||||
public.set_error_num(skey,True)
|
||||
userInfo = public.M('users').where("id=?",(1,)).field('id,username').find()
|
||||
session['login'] = True
|
||||
session['username'] = public.getMsg('TEMPORARY_ID',(data['id'],))
|
||||
session['username'] = public.get_msg_gettext('TEMPORARY_ID',(data['id'],))
|
||||
session['tmp_login'] = True
|
||||
session['tmp_login_id'] = str(data['id'])
|
||||
session['tmp_login_expire'] = time.time() + 3600
|
||||
@@ -152,7 +191,8 @@ class userlogin:
|
||||
os.makedirs(sess_path,384)
|
||||
public.writeFile(sess_path + '/' + str(data['id']),'')
|
||||
login_addr = public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))
|
||||
public.WriteLog('TYPE_LOGIN','LOGIN_SUCCESS',(userInfo['username'],login_addr))
|
||||
ids = public.write_log_gettext('Login','Login succeed, Username: {}, Login IP: {}',(userInfo['username'],login_addr))
|
||||
public.cache_set(public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT')),ids)
|
||||
public.M('temp_login').where('id=?',(data['id'],)).update({"login_time":s_time,'state':1,'login_addr':login_addr})
|
||||
self.limit_address('-')
|
||||
cache.delete('panelNum')
|
||||
@@ -161,10 +201,10 @@ class userlogin:
|
||||
self.set_request_token()
|
||||
self.login_token()
|
||||
self.set_cdn_host(get)
|
||||
public.login_send_body("Temporary authorization",userInfo['username'],public.GetClientIp(),str(request.environ.get('REMOTE_PORT')))
|
||||
public.run_thread(public.login_send_body("Temporary authorization",userInfo['username'],public.GetClientIp(),str(request.environ.get('REMOTE_PORT'))))
|
||||
return redirect('/')
|
||||
except:
|
||||
return public.getMsg('LOGIN_FAIL')
|
||||
return public.get_msg_gettext('Login failed')
|
||||
|
||||
|
||||
def login_token(self):
|
||||
@@ -172,40 +212,40 @@ class userlogin:
|
||||
config.config().reload_session()
|
||||
|
||||
def request_get(self,get):
|
||||
#if os.path.exists('/www/server/panel/install.pl'): raise redirect('/install');
|
||||
'''
|
||||
@name 验证登录页面请求权限
|
||||
@author hwliang
|
||||
@return False | Response
|
||||
'''
|
||||
# 获取标题
|
||||
if not 'title' in session: session['title'] = public.getMsg('NAME')
|
||||
domain = public.readFile('data/domain.conf')
|
||||
|
||||
if domain:
|
||||
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:
|
||||
iplist = iplist.strip()
|
||||
if not public.GetClientIp() in iplist.split(','):
|
||||
errorStr = public.ReadFile('./BTPanel/templates/' + public.GetConfigValue('template') + '/error2.html')
|
||||
try:
|
||||
errorStr = errorStr.format(public.getMsg('PAGE_ERR_TITLE'),public.getMsg('PAGE_ERR_IP_H1'),public.getMsg('PAGE_ERR_IP_P1',(public.GetClientIp(),)),public.getMsg('PAGE_ERR_IP_P2'),public.getMsg('PAGE_ERR_IP_P3'),public.getMsg('NAME'),public.getMsg('PAGE_ERR_HELP'))
|
||||
except IndexError:pass
|
||||
return errorStr
|
||||
|
||||
# 验证是否使用限制的域名访问
|
||||
domain_check = public.check_domain_panel()
|
||||
if domain_check: return domain_check
|
||||
|
||||
# 验证是否使用限制的IP地址访问
|
||||
ip_check = public.check_ip_panel()
|
||||
if ip_check: return ip_check
|
||||
|
||||
# 验证是否已经登录
|
||||
if 'login' in session:
|
||||
if session['login'] == True:
|
||||
return redirect('/')
|
||||
|
||||
# 复位验证码
|
||||
if not 'code' in session:
|
||||
session['code'] = False
|
||||
|
||||
# 记录错误次数
|
||||
self.error_num(False)
|
||||
|
||||
#生成request_token
|
||||
def set_request_token(self):
|
||||
session['request_token_head'] = public.GetRandomString(48)
|
||||
html_token_key = public.get_csrf_html_token_key()
|
||||
session[html_token_key] = public.GetRandomString(48)
|
||||
session[html_token_key.replace("https_","")] = public.GetRandomString(48)
|
||||
|
||||
|
||||
def set_cdn_host(self,get):
|
||||
try:
|
||||
@@ -227,21 +267,22 @@ class userlogin:
|
||||
num = 1
|
||||
if s: cache.inc(nKey,1)
|
||||
if num > 6: session['code'] = True
|
||||
|
||||
|
||||
#IP限制
|
||||
def limit_address(self,type,v=""):
|
||||
import time
|
||||
clientIp = public.GetClientIp()
|
||||
numKey = 'limitIpNum_' + v + clientIp
|
||||
limit = 6
|
||||
outTime = 600
|
||||
limit = 5
|
||||
outTime = 300
|
||||
try:
|
||||
#初始化
|
||||
num1 = cache.get(numKey)
|
||||
if not num1:
|
||||
cache.set(numKey,1,outTime)
|
||||
num1 = 1
|
||||
|
||||
cache.set(numKey,0,outTime)
|
||||
num1 = 0
|
||||
|
||||
self.limit_expire_time = cache.get_expire_time(numKey)
|
||||
|
||||
#计数
|
||||
if type == '+':
|
||||
cache.inc(numKey,1)
|
||||
@@ -278,27 +319,36 @@ class userlogin:
|
||||
session['username'] = userInfo['username']
|
||||
session['uid'] = userInfo['id']
|
||||
session['login_user_agent'] = public.md5(request.headers.get('User-Agent',''))
|
||||
public.WriteLog('TYPE_LOGIN','LOGIN_SUCCESS',(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
|
||||
ids = public.write_log_gettext('Login','Login succeed, Username: {}, Login IP: {}',(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
|
||||
public.cache_set(public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT')),ids)
|
||||
self.limit_address('-')
|
||||
cache.delete('panelNum')
|
||||
cache.delete('dologin')
|
||||
session['session_timeout'] = time.time() + public.get_session_timeout()
|
||||
if 'last_login_token' in session: del(session['last_login_token'])
|
||||
self.set_request_token()
|
||||
self.login_token()
|
||||
login_type = 'data/app_login.pl'
|
||||
if os.path.exists(login_type):
|
||||
os.remove(login_type)
|
||||
return public.returnJson(True,'LOGIN_SUCCESS'),json_header
|
||||
try:
|
||||
default_pl = "{}/default.pl".format(public.get_panel_path())
|
||||
public.writeFile(default_pl,"********")
|
||||
public.run_thread(public.login_send_body, (
|
||||
"Userinfo", userInfo['username'], public.GetClientIp(), str(request.environ.get('REMOTE_PORT'))))
|
||||
except:
|
||||
pass
|
||||
return public.returnJson(True,'Login succeeded, loading...'),json_header
|
||||
except Exception as ex:
|
||||
stringEx = str(ex)
|
||||
if stringEx.find('unsupported') != -1 or stringEx.find('-1') != -1:
|
||||
public.ExecShell("rm -f /tmp/sess_*")
|
||||
public.ExecShell("rm -f /www/wwwlogs/*log")
|
||||
public.ServiceReload()
|
||||
return public.returnJson(False,'USER_INODE_ERR'),json_header
|
||||
public.WriteLog('TYPE_LOGIN','LOGIN_ERR_PASS',('****','******',public.GetClientIp()))
|
||||
return public.returnJson(False,'Disk inode has been exhausted, the panel has attempted to release the inode. Please try again ...'),json_header
|
||||
public.write_log_gettext('Login','Password is incorrect, Username:{}, Password:{}, Login IP:{}',('****','******',public.GetClientIp()))
|
||||
num = self.limit_address('+')
|
||||
return public.returnJson(False,'LOGIN_USER_ERR',(str(num),)),json_header
|
||||
return public.returnJson(False,'Invalid username or password. You have [{}] times left to try!',(str(num),)),json_header
|
||||
|
||||
|
||||
# 检查是否需要进行二次验证
|
||||
|
||||
Binary file not shown.
+29
-16
@@ -13,6 +13,7 @@ if not 'class/' in sys.path:
|
||||
import public
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
from BTPanel import session,cache,request
|
||||
|
||||
class wxapp():
|
||||
@@ -24,24 +25,28 @@ class wxapp():
|
||||
def _check(self, get):
|
||||
if get['fun'] in ['set_login', 'is_scan_ok', 'login_qrcode']:
|
||||
return True
|
||||
return public.returnMsg(False, 'UNAUTHORIZED')
|
||||
return public.returnMsg(False, 'Unauthorized')
|
||||
|
||||
# 验证是否扫码成功
|
||||
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) > 60:
|
||||
return public.returnMsg(False, 'QRCORE_EXPIRE')
|
||||
session_id = public.get_session_id()
|
||||
if cache.get(session_id) == 'True':
|
||||
return public.returnMsg(True, 'Scan QRCORE successfully')
|
||||
try:
|
||||
key, init_time, tid, status = public.readFile(self.app_path+'app_login_check.pl').split(':')
|
||||
if time.time() - float(init_time) > 60:
|
||||
return public.returnMsg(False, 'QR code expired')
|
||||
session_id = public.get_session_id()
|
||||
if cache.get(session_id) == public.md5(uuid.UUID(int=uuid.getnode()).hex):
|
||||
return public.returnMsg(True, 'Scan QRCORE successfully')
|
||||
except:
|
||||
os.remove(self.app_path + "app_login_check.pl")
|
||||
return public.returnMsg(False, '')
|
||||
return public.returnMsg(False, '')
|
||||
|
||||
# 返回二维码地址
|
||||
def login_qrcode(self, get):
|
||||
tid = public.GetRandomString(12)
|
||||
tid = public.GetRandomString(32)
|
||||
qrcode_str = 'https://app.bt.cn/app.html?&panel_url='+public.getPanelAddr()+'&v=' + public.GetRandomString(3)+'?login&tid=' + tid
|
||||
data = public.get_session_id() + ':' + str(time.time())
|
||||
data = public.get_session_id() + ':' + str(time.time()) + ':' + tid + ':' + tid
|
||||
public.writeFile(self.app_path + "app_login_check.pl", data)
|
||||
cache.set(tid,public.get_session_id(),360)
|
||||
cache.set(public.get_session_id(),tid,360)
|
||||
@@ -50,15 +55,20 @@ class wxapp():
|
||||
# 设置登录状态
|
||||
def set_login(self, get):
|
||||
session_id = public.get_session_id()
|
||||
if cache.get(session_id) == 'True':
|
||||
return self.check_app_login(get)
|
||||
if cache.get(session_id):
|
||||
if cache.get(session_id) == public.md5(uuid.UUID(int=uuid.getnode()).hex):
|
||||
return self.check_app_login(get)
|
||||
else:
|
||||
cache.delete(cache.get(session_id))
|
||||
cache.delete(session_id)
|
||||
return public.returnMsg(False, 'Login failed 2')
|
||||
return public.returnMsg(False, 'Login failed 1')
|
||||
|
||||
#验证APP是否登录成功
|
||||
def check_app_login(self,get):
|
||||
#判断是否存在绑定
|
||||
btapp_info = json.loads(public.readFile('/www/server/panel/config/api.json'))
|
||||
if not btapp_info:return public.returnMsg(False,'Unbound')
|
||||
if not btapp_info:return public.returnMsg(False,'Unbound!')
|
||||
if not btapp_info['open']:return public.returnMsg(False,'API is not turned on')
|
||||
if not 'apps' in btapp_info:return public.returnMsg(False,'Unbound phone')
|
||||
if not btapp_info['apps']:return public.returnMsg(False,'Unbound phone')
|
||||
@@ -67,19 +77,22 @@ class wxapp():
|
||||
if not os.path.exists(self.app_path+'app_login_check.pl'):return public.returnMsg(False,'Waiting for APP scan code login 1')
|
||||
data = public.readFile(self.app_path+'app_login_check.pl')
|
||||
public.ExecShell('rm ' + self.app_path+"app_login_check.pl")
|
||||
secret_key, init_time = data.split(':')
|
||||
secret_key, init_time, tid, status = 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 session_id != secret_key:
|
||||
return public.returnMsg(False,'QR code expired')
|
||||
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')
|
||||
import uuid
|
||||
if status != uuid.UUID(int=uuid.getnode()).hex[-12:]: return public.returnMsg(False, '当前二维码失效222')
|
||||
cache.delete(session_id)
|
||||
cache.delete(tid)
|
||||
userInfo = public.M('users').where("id=?",(1,)).field('id,username').find()
|
||||
session['login'] = True
|
||||
session['username'] = userInfo['username']
|
||||
session['tmp_login'] = True
|
||||
public.WriteLog('TYPE_LOGIN','APP scan code login, account: {}, login IP: {}'.format(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
|
||||
public.WriteLog('Login','APP scan code login, account: {}, login IP: {}'.format(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
|
||||
cache.delete('panelNum')
|
||||
cache.delete('dologin')
|
||||
session['session_timeout'] = time.time() + public.get_session_timeout()
|
||||
|
||||
Reference in New Issue
Block a user