mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-17 21:25:47 +02:00
Optimize the ssl application process
This commit is contained in:
+1
-1
@@ -27,7 +27,7 @@ class panelSetup:
|
||||
if ua:
|
||||
ua = ua.lower();
|
||||
if ua.find('spider') != -1 or ua.find('bot') != -1: return redirect('https://www.baidu.com');
|
||||
g.version = '6.1.2'
|
||||
g.version = '6.1.3'
|
||||
g.title = public.GetConfigValue('title')
|
||||
g.uri = request.path
|
||||
session['version'] = g.version;
|
||||
|
||||
+13
-7
@@ -259,20 +259,26 @@ class crontab:
|
||||
def GetDataList(self,get):
|
||||
data = {}
|
||||
data['data'] = public.M(get['type']).field('name,ps').select()
|
||||
data['orderOpt'] = [];
|
||||
data['orderOpt'] = []
|
||||
import json
|
||||
tmp = public.readFile('data/libList.conf');
|
||||
tmp = public.readFile('data/libList.conf')
|
||||
libs = json.loads(tmp)
|
||||
import imp;
|
||||
import imp
|
||||
for lib in libs:
|
||||
try:
|
||||
imp.find_module(lib['module']);
|
||||
imp.find_module(lib['module'])
|
||||
tmp = {}
|
||||
tmp['name'] = lib['name'];
|
||||
tmp['name'] = lib['name']
|
||||
tmp['value']= lib['opt']
|
||||
data['orderOpt'].append(tmp);
|
||||
data['orderOpt'].append(tmp)
|
||||
except:
|
||||
continue;
|
||||
import sys
|
||||
if lib['module'] == "google.cloud" and "google.cloud" in sys.modules.keys():
|
||||
tmp1 = {}
|
||||
tmp1['name'] = lib['name']
|
||||
tmp1['value'] = lib['opt']
|
||||
data['orderOpt'].append(tmp1)
|
||||
continue
|
||||
return data
|
||||
|
||||
#取任务日志
|
||||
|
||||
+11
-9
@@ -110,9 +110,9 @@ class AliyunDns(object):
|
||||
req = requests.get(url=self.url, params=paramsdata)
|
||||
if req.status_code != 200:
|
||||
if req.json()['Code'] == 'IncorrectDomainUser' or req.json()['Code'] == 'InvalidDomainName.NoExist':
|
||||
raise ValueError(json.dumps({"data": "这个阿里云账户下面不存在这个域名,添加解析失败", "msg": req.json()}))
|
||||
raise ValueError(json.dumps({"data": "This domain name does not exist under this Ali cloud account. Adding parsing failed.", "msg": req.json()}))
|
||||
elif req.json()['Code'] == 'InvalidAccessKeyId.NotFound' or req.json()['Code'] == 'SignatureDoesNotMatch':
|
||||
raise ValueError(json.dumps({"data": "API密钥错误,添加解析失败", "msg": req.json()}))
|
||||
raise ValueError(json.dumps({"data": "API key error, add parsing failed", "msg": req.json()}))
|
||||
else:
|
||||
raise ValueError(json.dumps({"data": req.json()['Message'], "msg": req.json()}))
|
||||
print("create_dns_record end")
|
||||
@@ -165,7 +165,7 @@ class AliyunDns(object):
|
||||
paramsdata['Signature'] = Signature
|
||||
req = requests.get(url=self.url, params=paramsdata)
|
||||
if req.status_code != 200:
|
||||
raise ValueError(json.dumps({"data": "删除解析记录失败", "msg": req.json()}))
|
||||
raise ValueError(json.dumps({"data": "Deleting a parse record failed", "msg": req.json()}))
|
||||
print("delete_dns_record end: ", acme_txt)
|
||||
|
||||
class CloudxnsDns(object):
|
||||
@@ -216,7 +216,7 @@ class CloudxnsDns(object):
|
||||
root, _, acme_txt = self.extract_zone(domain_name)
|
||||
domain = self.get_domain_id(root)
|
||||
if not domain:
|
||||
raise ValueError('域名不存在这个cloudxns用户下面,添加解析失败。')
|
||||
raise ValueError('The domain name does not exist under this cloudxns user, adding parsing failed.')
|
||||
|
||||
print("create_dns_record,", acme_txt, domain_dns_value)
|
||||
url = "https://www.cloudxns.net/api2/record"
|
||||
@@ -278,15 +278,17 @@ class Dns_com(object):
|
||||
|
||||
def create_dns_record(self, domain_name, domain_dns_value):
|
||||
root, _, acme_txt = self.extract_zone(domain_name)
|
||||
print("[DNS]创建TXT记录,", acme_txt, domain_dns_value)
|
||||
print("[DNS]Create a TXT record,", acme_txt, domain_dns_value)
|
||||
result = self.get_dns_obj().add_txt(acme_txt + '.' + root,domain_dns_value)
|
||||
if result == "False":
|
||||
raise ValueError('[DNS]当前绑定的宝塔DNS云解析账户里面不存在这个域名,添加解析失败!')
|
||||
print("[DNS]TXT记录创建成功")
|
||||
raise ValueError('[DNS] This domain name does not exist in the currently bound Pagoda DNS cloud resolution account. Adding parsing failed!')
|
||||
print("[DNS] TXT record created successfully")
|
||||
print("[DNS] Try to verify TXT record")
|
||||
time.sleep(10)
|
||||
|
||||
def delete_dns_record(self, domain_name, domain_dns_value):
|
||||
root, _, acme_txt = self.extract_zone(domain_name)
|
||||
print("[DNS]准备删除TXT记录: ", acme_txt, domain_dns_value)
|
||||
print("[DNS] ready to delete TXT records: ", acme_txt, domain_dns_value)
|
||||
result = self.get_dns_obj().remove_txt(acme_txt + '.' + root)
|
||||
print("[DNS]TXT记录删除成功")
|
||||
print("[DNS] TXT record deleted successfully")
|
||||
|
||||
|
||||
+106
-42
@@ -12,12 +12,22 @@ os.chdir(setup_path)
|
||||
sys.path.append("class/")
|
||||
import requests,sewer,public
|
||||
from OpenSSL import crypto
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
try:
|
||||
requests.packages.urllib3.disable_warnings()
|
||||
except:pass
|
||||
import BTPanel
|
||||
try:
|
||||
import dns.resolver
|
||||
except:
|
||||
os.system("pip install dnspython")
|
||||
try:
|
||||
import dns.resolver
|
||||
except:
|
||||
pass
|
||||
|
||||
class panelLets:
|
||||
let_url = "https://acme-v02.api.letsencrypt.org/directory"
|
||||
#let_url_test = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
#let_url = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
|
||||
setupPath = None #安装路径
|
||||
server_type = None
|
||||
@@ -72,17 +82,17 @@ class panelLets:
|
||||
def get_error(self,error):
|
||||
|
||||
if error.find("Max checks allowed") >= 0 :
|
||||
return "CA服务器验证超时,请等待5-10分钟后重试."
|
||||
return "CA server verification timed out, please wait 5-10 minutes and try again."
|
||||
elif error.find("Max retries exceeded with") >= 0:
|
||||
return "CA服务器连接超时,请确保服务器网络通畅."
|
||||
return "The CA server connection timed out, please make sure the server network is unobstructed."
|
||||
elif error.find("The domain name belongs") >= 0:
|
||||
return "域名不属于此DNS服务商,请确保域名填写正确."
|
||||
return "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 'DNS服务器连接失败,请检查密钥是否正确.'
|
||||
return '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 or "Error creating new account :: too many registrations for this IP" in error:
|
||||
return '<h2>签发失败,您今天尝试申请证书的次数已达上限!</h2>'
|
||||
return '<h2>The signing failed, and the number of attempts to apply for a certificate today has reached the limit!</h2>'
|
||||
elif "DNS problem: NXDOMAIN looking up A for" in error or "No valid IP addresses found for" in error or "Invalid response from" in error:
|
||||
return '<h2>签发失败,域名解析错误,或解析未生效,或域名未备案!</h2>'
|
||||
return '<h2>The signing failed, the domain name resolution error, or the resolution is not valid, or the domain name is not filed!</h2>'
|
||||
else:
|
||||
return error;
|
||||
|
||||
@@ -111,10 +121,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, '续签失败,证书目录不存在.')
|
||||
if not os.path.exists(path): return public.returnMsg(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, '续签失败,缺少account_key.')
|
||||
if not os.path.exists(account_path): return public.returnMsg(False, 'Renewal failed, missing account_key.')
|
||||
|
||||
#续签
|
||||
data['account_key'] = public.readFile(account_path)
|
||||
@@ -138,7 +148,9 @@ class panelLets:
|
||||
pfx_buffer = p12.export()
|
||||
public.writeFile(path + "/fullchain.pfx",pfx_buffer,'wb+')
|
||||
|
||||
return public.returnMsg(True, '[%s]证书续签成功.' % data['siteName'])
|
||||
return public.returnMsg(True, '[%s]The certificate renewal was successful.' % data['siteName'])
|
||||
|
||||
|
||||
|
||||
#申请证书
|
||||
def apple_lest_cert(self,get):
|
||||
@@ -149,7 +161,7 @@ class panelLets:
|
||||
data['email'] = get.email
|
||||
data['dnssleep'] = get.dnssleep
|
||||
|
||||
if len(data['domains']) <=0 : return public.returnMsg(False, '申请域名列表不能为空.')
|
||||
if len(data['domains']) <=0 : return public.returnMsg(False, 'The list of applied domain names cannot be empty.')
|
||||
|
||||
data['first_domain'] = data['domains'][0]
|
||||
|
||||
@@ -173,8 +185,7 @@ class panelLets:
|
||||
domain_list = data['domains']
|
||||
if data['app_root'] == '1':
|
||||
domain_list = []
|
||||
data['first_domain'] = self.get_root_domain(data['first_domain'])
|
||||
|
||||
data['first_domain'] = self.get_root_domain(data['first_domain'])
|
||||
for domain in data['domains']:
|
||||
rootDoamin = self.get_root_domain(domain)
|
||||
if not rootDoamin in domain_list: domain_list.append(rootDoamin)
|
||||
@@ -190,10 +201,13 @@ class panelLets:
|
||||
else:
|
||||
#手动解析提前返回
|
||||
result = self.crate_let_by_oper(data)
|
||||
public.writeFile(domain_path, json.dumps(result))
|
||||
result['code'] = 2
|
||||
if 'status' in result and not result['status']: return result
|
||||
|
||||
result['status'] = True
|
||||
result['msg'] = '获取成功,请手动解析域名'
|
||||
public.writeFile(domain_path, json.dumps(result))
|
||||
result['msg'] = 'Get successful, please manually resolve the domain name'
|
||||
result['code'] = 2;
|
||||
|
||||
return result
|
||||
elif get.dnsapi == 'dns_bt':
|
||||
data['dnsapi'] = get.dnsapi
|
||||
@@ -236,9 +250,13 @@ class panelLets:
|
||||
cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
|
||||
shell = 'python %s/panel/class/panelLets.py renew_lets_ssl ' % (self.setupPath)
|
||||
public.writeFile(cronPath,shell)
|
||||
public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("续签Let's Encrypt证书",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),1,'','localhost','toShell','',shell,''))
|
||||
public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("Renew the Letter's Encrypt certificate",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),1,'','localhost','toShell','',shell,''))
|
||||
|
||||
return public.returnMsg(True, '申请成功.')
|
||||
return public.returnMsg(True, 'Successful application.')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#手动解析
|
||||
def crate_let_by_oper(self,data):
|
||||
@@ -282,6 +300,7 @@ class panelLets:
|
||||
dns['finalize_url'] = finalize_url
|
||||
return dns
|
||||
else:
|
||||
|
||||
responders = data['dns']['responders']
|
||||
dns_names_to_delete = data['dns']['dns_names']
|
||||
finalize_url = data['dns']['finalize_url']
|
||||
@@ -305,7 +324,7 @@ class panelLets:
|
||||
result['status'] = True
|
||||
BTPanel.dns_client = None
|
||||
else:
|
||||
result['msg'] = '证书获取失败,请稍后重试.'
|
||||
result['msg'] = 'Certificate acquisition failed, please try again later.'
|
||||
|
||||
except Exception as e:
|
||||
print(public.get_error_info())
|
||||
@@ -313,10 +332,10 @@ class panelLets:
|
||||
return result
|
||||
|
||||
#dns验证
|
||||
def crate_let_by_dns(self,data):
|
||||
dns_class = self.get_dns_class(data)
|
||||
def crate_let_by_dns(self,data):
|
||||
dns_class = self.get_dns_class(data)
|
||||
if not dns_class:
|
||||
return public.returnMsg(False, 'DNS连接失败,请检查密钥是否正确.')
|
||||
return public.returnMsg(False, 'The DNS connection failed. Please check if the key is correct.')
|
||||
|
||||
result = {}
|
||||
result['status'] = False
|
||||
@@ -341,15 +360,23 @@ class panelLets:
|
||||
|
||||
acme_keyauthorization, domain_dns_value = client.get_keyauthorization(dns_token)
|
||||
dns_class.create_dns_record(dns_name, domain_dns_value)
|
||||
self.check_dns(self.get_acme_name(dns_name),domain_dns_value)
|
||||
dns_names_to_delete.append({"dns_name": dns_name, "domain_dns_value": domain_dns_value})
|
||||
responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"dns_challenge_url": dns_challenge_url} )
|
||||
for i in responders:
|
||||
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"])
|
||||
n = 0
|
||||
while n<2:
|
||||
print(n+1," verification")
|
||||
try:
|
||||
for i in responders:
|
||||
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: client.check_authorization_status(i["authorization_url"], ["valid"])
|
||||
for i in responders: client.check_authorization_status(i["authorization_url"], ["valid"])
|
||||
break
|
||||
except:
|
||||
n+=1
|
||||
|
||||
certificate_url = client.send_csr(finalize_url)
|
||||
certificate = client.download_certificate(certificate_url)
|
||||
@@ -360,6 +387,7 @@ class panelLets:
|
||||
result['key'] = client.certificate_key
|
||||
result['account_key'] = client.account_key
|
||||
result['status'] = True
|
||||
|
||||
except Exception as e:
|
||||
print(public.get_error_info())
|
||||
raise e
|
||||
@@ -378,6 +406,7 @@ class panelLets:
|
||||
def crate_let_by_file(self,data):
|
||||
result = {}
|
||||
result['status'] = False
|
||||
result['clecks'] = []
|
||||
try:
|
||||
log_level = "INFO"
|
||||
if data['account_key']: log_level = 'ERROR'
|
||||
@@ -404,9 +433,20 @@ class panelLets:
|
||||
wellknown_path = acme_dir + '/' + http_token
|
||||
public.writeFile(wellknown_path,acme_keyauthorization)
|
||||
wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(http_name, http_token)
|
||||
|
||||
retkey = public.httpGet(wellknown_url)
|
||||
if retkey == acme_keyauthorization:
|
||||
result['clecks'].append({'wellknown_url':wellknown_url,'http_token':http_token});
|
||||
is_check = False
|
||||
n = 0
|
||||
while n < 5:
|
||||
print("wait_check_authorization_status")
|
||||
try:
|
||||
retkey = public.httpGet(wellknown_url,20)
|
||||
if retkey == acme_keyauthorization:
|
||||
is_check = True
|
||||
break
|
||||
except :
|
||||
pass
|
||||
n += 1
|
||||
if is_check:
|
||||
sucess_domains.append(http_name)
|
||||
responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"http_challenge_url": http_challenge_url})
|
||||
|
||||
@@ -431,9 +471,9 @@ class panelLets:
|
||||
result['account_key'] = client.account_key
|
||||
result['status'] = True
|
||||
else:
|
||||
result['msg'] = '证书获取失败,请稍后重试.'
|
||||
result['msg'] = 'Certificate acquisition failed, please try again later.'
|
||||
else:
|
||||
result['msg'] = "签发失败,我们无法验证您的域名:<p>1、检查域名是否绑定到对应站点</p><p>2、检查域名是否正确解析到本服务器,或解析还未完全生效</p><p>3、如果您的站点设置了反向代理,或使用了CDN,请先将其关闭</p><p>4、如果您的站点设置了301重定向,请先将其关闭</p><p>5、如果以上检查都确认没有问题,请尝试更换DNS服务商</p>'"
|
||||
result['msg'] = "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:
|
||||
result['msg'] = self.get_error(str(e))
|
||||
return result
|
||||
@@ -465,7 +505,31 @@ class panelLets:
|
||||
"http_challenge_url": http_challenge_url,
|
||||
}
|
||||
return identifier_auth
|
||||
|
||||
|
||||
#检查DNS记录
|
||||
def check_dns(self,domain,value,type='TXT'):
|
||||
time.sleep(5)
|
||||
n = 0
|
||||
while n < 10:
|
||||
try:
|
||||
import dns.resolver
|
||||
ns = dns.resolver.query(domain,type)
|
||||
for j in ns.response.answer:
|
||||
for i in j.items:
|
||||
txt_value = i.to_text().replace('"','').strip()
|
||||
print(txt_value)
|
||||
if txt_value == value:
|
||||
print("Successful verification:",txt_value)
|
||||
return True
|
||||
except:
|
||||
try:
|
||||
import dns.resolver
|
||||
except:
|
||||
return False
|
||||
n+=1
|
||||
time.sleep(5)
|
||||
return True
|
||||
|
||||
#获取证书哈希
|
||||
def get_cert_data(self,path):
|
||||
try:
|
||||
@@ -514,18 +578,18 @@ class panelLets:
|
||||
def renew_lets_ssl(self):
|
||||
cpath = self.setupPath + '/panel/vhost/cert/crontab.json'
|
||||
if not os.path.exists(cpath):
|
||||
print("|-当前没有可以续订的证书. " );
|
||||
print("|-There are currently no certificates to renew." );
|
||||
else:
|
||||
old_list = json.loads(public.ReadFile(cpath))
|
||||
print('=======================================================================')
|
||||
print('|-%s 共计[%s]续签证书任务.' % (time.strftime('%Y-%m-%d %X',time.localtime()),len(old_list)))
|
||||
print('|-%s Total [%s] renewal of visa tasks' % (time.strftime('%Y-%m-%d %X',time.localtime()),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('|-[%s]未到期或网站未使用Let\'s Encrypt证书.' % (','.join(tlist)))
|
||||
print('|-%s 等待续签[%s].' % (time.strftime('%Y-%m-%d %X',time.localtime()),len(cron_list)))
|
||||
print('|-[%s]Not expired or the site does not use the Let\'s Encrypt certificate.' % (','.join(tlist)))
|
||||
print('|-%s Waiting for renewal[%s].' % (time.strftime('%Y-%m-%d %X',time.localtime()),len(cron_list)))
|
||||
|
||||
sucess_list = []
|
||||
err_list = []
|
||||
@@ -536,11 +600,11 @@ class panelLets:
|
||||
sucess_list.append(siteName)
|
||||
else:
|
||||
err_list.append({"siteName":siteName,"msg":ret['msg']})
|
||||
print("|-任务执行完毕,共需续订[%s],续订成功[%s],续订失败[%s]. " % (len(cron_list),len(sucess_list),len(err_list)));
|
||||
print("|-After the task is completed, a total of renewals are required.[%s], renewal success [%s], renewal failed [%s]. " % (len(cron_list),len(sucess_list),len(err_list)));
|
||||
if len(sucess_list) > 0:
|
||||
print("|-续订成功:%s" % (','.join(sucess_list)))
|
||||
print("|-Renewal success:%s" % (','.join(sucess_list)))
|
||||
if len(err_list) > 0:
|
||||
print("|-续订失败:")
|
||||
print("|-Renewal failed:")
|
||||
for x in err_list:
|
||||
print(" %s ->> %s" % (x['siteName'],x['msg']))
|
||||
|
||||
|
||||
+3
-1
@@ -934,7 +934,9 @@ class panelSite(panelRedirect):
|
||||
if match: apis[i]['data'][j]['value'] = match.groups()[0]
|
||||
if apis[i]['data'][j]['value']: is_write = True
|
||||
if is_write: public.writeFile('./config/dns_api.json',json.dumps(apis))
|
||||
return apis
|
||||
result = []
|
||||
for i in apis: result.insert(0,i)
|
||||
return result
|
||||
|
||||
#设置DNS-API
|
||||
def SetDnsApi(self,get):
|
||||
|
||||
+19
-4
@@ -778,12 +778,17 @@ def getStrBetween(startStr,endStr,srcStr):
|
||||
|
||||
#取CPU类型
|
||||
def getCpuType():
|
||||
cpuinfo = open('/proc/cpuinfo','r').read();
|
||||
cpuinfo = open('/proc/cpuinfo','r').read()
|
||||
rep = "model\s+name\s+:\s+(.+)"
|
||||
tmp = re.search(rep,cpuinfo);
|
||||
cpuType = None
|
||||
tmp = re.search(rep,cpuinfo,re.I);
|
||||
cpuType = ''
|
||||
if tmp:
|
||||
cpuType = tmp.groups()[0];
|
||||
cpuType = tmp.groups()[0]
|
||||
else:
|
||||
cpuinfo = ExecShell('LANG="en_US.UTF-8" && lscpu')[0]
|
||||
rep = "Model\s+name:\s+(.+)"
|
||||
tmp = re.search(rep,cpuinfo,re.I)
|
||||
if tmp: cpuType = tmp.groups()[0]
|
||||
return cpuType;
|
||||
|
||||
|
||||
@@ -1259,3 +1264,13 @@ def set_own(filename,user,group=None):
|
||||
group = user_info.pw_gid
|
||||
os.chown(filename,user,group)
|
||||
return True
|
||||
|
||||
#校验路径安全
|
||||
def path_safe_check(path):
|
||||
checks = ['..','./','\\','%','$','^','&','*','~','@','#']
|
||||
for c in checks:
|
||||
if path.find(c) != -1: return False
|
||||
rep = "^[\w\s\.\/-]+$"
|
||||
if not re.match(rep,path): return False
|
||||
return True
|
||||
|
||||
|
||||
+7
-49
@@ -1,57 +1,15 @@
|
||||
[{
|
||||
"name":"七牛云存储",
|
||||
"type":"计划任务",
|
||||
"ps":"将网站或数据库打包备份到七牛对象存储空间,七牛提供10GB免费存储空间, <a class='link' href='https://portal.qiniu.com/signup?code=3liz7nbopjd5e' target='_blank'>点击申请</a>",
|
||||
"status":false,
|
||||
"opt":"qiniu",
|
||||
"module":"qiniu",
|
||||
"script":"qiniu",
|
||||
"help":"http://www.bt.cn/bbs/thread-839-1-1.html",
|
||||
"key":"access_key|请输入AccessKey|七牛秘钥中的AK",
|
||||
"secret":"secret_key|请输入SecretKey|七牛秘钥中的SK",
|
||||
"bucket":"存储空间|请输入对象存储空间名称|七牛对象存储中您创建的空间名称",
|
||||
"domain":"外链域名|请输入绑定域名或测试域名|绑定的七牛外链域名,若没有则填测试域名",
|
||||
"check":["/usr/lib/python2.6/site-packages/qiniu/auth.py","/usr/lib/python2.7/site-packages/qiniu/auth.py"]
|
||||
},{
|
||||
"name":"阿里云OSS",
|
||||
"type":"计划任务",
|
||||
"ps":"将网站或数据库打包备份到阿里云OSS对象存储空间,阿里云OSS提供5GB免费存储空间, <a class='link' href='https://www.aliyun.com/product/oss?spm=5176.8142029.388261.46.psCRgl' target='_blank'>点击申请</a>",
|
||||
"status":false,
|
||||
"opt":"alioss",
|
||||
"module":"oss2",
|
||||
"script":"alioss",
|
||||
"help":"http://www.bt.cn/bbs/thread-1061-1-1.html",
|
||||
"key":"AccessKeyId|请输入AccessKeyId|阿里云的AccessKeyId",
|
||||
"secret":"AccessKeySecret|请输入AccessKeySecret|阿里云的AccessKeySecret",
|
||||
"bucket":"Bucket|请输入Bucket名称|阿里云OSS中您创建的Bucket名称",
|
||||
"domain":"外链域名|请输入Endpoint域名|阿里云OSS外链域名,不包括Bucket名",
|
||||
"check":["/usr/lib/python2.6/site-packages/oss2/auth.py","/usr/lib/python2.7/site-packages/oss2/auth.py"]
|
||||
},{
|
||||
"name":"FTP storage",
|
||||
"name":"Google Cloud Storage",
|
||||
"type":"Cron job",
|
||||
"ps":"将网站或数据库打包备份到FTP存储空间.",
|
||||
"ps":"Back up your website or database to Google Cloud Storage.",
|
||||
"status":false,
|
||||
"opt":"ftp",
|
||||
"module":"ftp",
|
||||
"script":"ftp",
|
||||
"help":"http://www.bt.cn/bbs",
|
||||
"key":"Host|请输入主机地址|FTP服务器地址,例:192.168.0.1:21",
|
||||
"secret":"用户名|请输入登陆用户名|指定FTP用户名",
|
||||
"bucket":"密码|请输入登陆密码|指定FTP密码",
|
||||
"domain":"存储位置|请输入存储位置|相对于FTP根目录的路径,如 /backup",
|
||||
"check":["/www/server/panel/script/backup_ftp.py"]
|
||||
},{
|
||||
"name":"申请内测资格",
|
||||
"type":"其它",
|
||||
"ps":"申请内测资格,审核完成后将会获得内测版本更新推送,并可在宝塔论坛内测专用版块参与讨论",
|
||||
"status":false,
|
||||
"opt":"beta",
|
||||
"module":"beta",
|
||||
"script":"beta",
|
||||
"help":"http://www.bt.cn/bbs/thread-1392-1-1.html",
|
||||
"opt":"gcloud",
|
||||
"module":"google.cloud",
|
||||
"script":"google",
|
||||
"help":"http://forum.aapanel.com",
|
||||
"key":"",
|
||||
"secret":"",
|
||||
"bucket":"",
|
||||
"domain":"",
|
||||
"check":["data/beta.pl"]
|
||||
"check":["/www/server/panel/plugin/gcloud_storage/gcloud_storage_main.py","/www/server/panel/script/backup_gcloud.py"]
|
||||
}]
|
||||
@@ -78,7 +78,7 @@ echo "
|
||||
+----------------------------------------------------------------------
|
||||
"
|
||||
get_node_url(){
|
||||
nodes=(http://125.88.182.172:5880 http://183.235.223.101:3389 http://103.224.251.67 http://128.1.164.196);
|
||||
nodes=(http://183.235.223.101:3389 http://119.188.210.21:5880 http://125.88.182.172:5880 http://103.224.251.67 http://45.32.116.160 http://download.bt.cn);
|
||||
i=1;
|
||||
if [ ! -f /bin/curl ];then
|
||||
if [ -f /usr/local/curl/bin/curl ];then
|
||||
@@ -201,7 +201,7 @@ timedatectl set-ntp 1
|
||||
#ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
#echo 'Synchronizing system time...'
|
||||
#ntpdate 0.asia.pool.ntp.org
|
||||
ntpdate 0.asia.pool.ntp.org
|
||||
startTime=`date +%s`
|
||||
setenforce 0
|
||||
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
|
||||
@@ -374,18 +374,7 @@ Install_chardet()
|
||||
Install_setuptools
|
||||
Install_pip
|
||||
|
||||
if [ "${download_Url}" = "$CN" ]; then
|
||||
if [ ! -d "/root/.pip" ];then
|
||||
mkdir ~/.pip
|
||||
fi
|
||||
cat > ~/.pip/pip.conf <<EOF
|
||||
[global]
|
||||
index-url = https://pypi.doubanio.com/simple/
|
||||
|
||||
[install]
|
||||
trusted-host=pypi.doubanio.com
|
||||
EOF
|
||||
fi
|
||||
curl -Ss --connect-timeout 3 -m 60 http://download.bt.cn/install/pip_select.sh|bash
|
||||
|
||||
isPsutil=`python -m psutil 2>&1|grep package`
|
||||
if [ "$isPsutil" != "" ];then
|
||||
@@ -403,7 +392,9 @@ pip install paramiko==2.0.2
|
||||
pip install flask-socketio==3.0.2
|
||||
pip install python-socketio==2.1.2
|
||||
pip install Werkzeug==0.15.1
|
||||
for p_name in psutil chardet virtualenv Flask Flask-Session Flask-SocketIO flask-sqlalchemy Pillow gunicorn gevent-websocket requests;
|
||||
pip install Pillow==5.4.1
|
||||
pip install -I requests==2.20
|
||||
for p_name in psutil chardet virtualenv Flask Flask-Session Flask-SocketIO flask-sqlalchemy Pillow gunicorn gevent-websocket pyopenssl cryptography;
|
||||
do
|
||||
pip install ${p_name}
|
||||
done
|
||||
@@ -418,7 +409,7 @@ if [ "$is_gevent" = "" ];then
|
||||
fi
|
||||
fi
|
||||
|
||||
pip install psutil chardet virtualenv Flask Flask-Session Flask-SocketIO flask-sqlalchemy Pillow gunicorn gevent-websocket paramiko
|
||||
pip install psutil chardet virtualenv Flask Flask-Session Flask-SocketIO flask-sqlalchemy Pillow gunicorn gevent-websocket paramiko requests pyopenssl cryptography
|
||||
Install_Pillow
|
||||
Install_psutil
|
||||
|
||||
@@ -493,6 +484,9 @@ chkconfig --add bt
|
||||
chkconfig --level 2345 bt on
|
||||
chmod -R 600 $setup_path/server/panel
|
||||
chmod -R +x $setup_path/server/panel/script
|
||||
chmod 655 $setup_path/server/panel
|
||||
chmod 655 $setup_path/server/panel/data
|
||||
chmod 655 $setup_path/server/panel/data/empty.html
|
||||
ln -sf /etc/init.d/bt /usr/bin/bt
|
||||
echo "$port" > $setup_path/server/panel/data/port.pl
|
||||
/etc/init.d/bt start
|
||||
@@ -617,6 +611,11 @@ fi
|
||||
|
||||
curl -sS --connect-timeout 10 -m 60 https://www.bt.cn/Api/SetupCount?type=Linux\&o=EN > /dev/null 2>&1
|
||||
curl -sS --connect-timeout 10 -m 60 https://www.aapanel.com/Api/SetupCount?type=Linux > /dev/null 2>&1
|
||||
if [ "$1" != "" ];then
|
||||
echo $1 > /www/server/panel/data/o.pl
|
||||
cd /www/server/panel
|
||||
python tools.py o
|
||||
fi
|
||||
echo /www > /var/bt_setupPath.conf
|
||||
/etc/init.d/bt start
|
||||
|
||||
|
||||
Reference in New Issue
Block a user