Commit df1ca5bb authored by jose's avatar jose

Optimize the ssl application process

parent 1af51411
...@@ -27,7 +27,7 @@ class panelSetup: ...@@ -27,7 +27,7 @@ class panelSetup:
if ua: if ua:
ua = ua.lower(); ua = ua.lower();
if ua.find('spider') != -1 or ua.find('bot') != -1: return redirect('https://www.baidu.com'); 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.title = public.GetConfigValue('title')
g.uri = request.path g.uri = request.path
session['version'] = g.version; session['version'] = g.version;
......
...@@ -259,20 +259,26 @@ class crontab: ...@@ -259,20 +259,26 @@ class crontab:
def GetDataList(self,get): def GetDataList(self,get):
data = {} data = {}
data['data'] = public.M(get['type']).field('name,ps').select() data['data'] = public.M(get['type']).field('name,ps').select()
data['orderOpt'] = []; data['orderOpt'] = []
import json import json
tmp = public.readFile('data/libList.conf'); tmp = public.readFile('data/libList.conf')
libs = json.loads(tmp) libs = json.loads(tmp)
import imp; import imp
for lib in libs: for lib in libs:
try: try:
imp.find_module(lib['module']); imp.find_module(lib['module'])
tmp = {} tmp = {}
tmp['name'] = lib['name']; tmp['name'] = lib['name']
tmp['value']= lib['opt'] tmp['value']= lib['opt']
data['orderOpt'].append(tmp); data['orderOpt'].append(tmp)
except: 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 return data
#取任务日志 #取任务日志
......
...@@ -110,9 +110,9 @@ class AliyunDns(object): ...@@ -110,9 +110,9 @@ class AliyunDns(object):
req = requests.get(url=self.url, params=paramsdata) req = requests.get(url=self.url, params=paramsdata)
if req.status_code != 200: if req.status_code != 200:
if req.json()['Code'] == 'IncorrectDomainUser' or req.json()['Code'] == 'InvalidDomainName.NoExist': 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': 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: else:
raise ValueError(json.dumps({"data": req.json()['Message'], "msg": req.json()})) raise ValueError(json.dumps({"data": req.json()['Message'], "msg": req.json()}))
print("create_dns_record end") print("create_dns_record end")
...@@ -165,7 +165,7 @@ class AliyunDns(object): ...@@ -165,7 +165,7 @@ class AliyunDns(object):
paramsdata['Signature'] = Signature paramsdata['Signature'] = Signature
req = requests.get(url=self.url, params=paramsdata) req = requests.get(url=self.url, params=paramsdata)
if req.status_code != 200: 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) print("delete_dns_record end: ", acme_txt)
class CloudxnsDns(object): class CloudxnsDns(object):
...@@ -216,7 +216,7 @@ class CloudxnsDns(object): ...@@ -216,7 +216,7 @@ class CloudxnsDns(object):
root, _, acme_txt = self.extract_zone(domain_name) root, _, acme_txt = self.extract_zone(domain_name)
domain = self.get_domain_id(root) domain = self.get_domain_id(root)
if not domain: 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) print("create_dns_record,", acme_txt, domain_dns_value)
url = "https://www.cloudxns.net/api2/record" url = "https://www.cloudxns.net/api2/record"
...@@ -278,15 +278,17 @@ class Dns_com(object): ...@@ -278,15 +278,17 @@ class Dns_com(object):
def create_dns_record(self, domain_name, domain_dns_value): def create_dns_record(self, domain_name, domain_dns_value):
root, _, acme_txt = self.extract_zone(domain_name) 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) result = self.get_dns_obj().add_txt(acme_txt + '.' + root,domain_dns_value)
if result == "False": if result == "False":
raise ValueError('[DNS]当前绑定的宝塔DNS云解析账户里面不存在这个域名,添加解析失败!') raise ValueError('[DNS] This domain name does not exist in the currently bound Pagoda DNS cloud resolution account. Adding parsing failed!')
print("[DNS]TXT记录创建成功") 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): def delete_dns_record(self, domain_name, domain_dns_value):
root, _, acme_txt = self.extract_zone(domain_name) 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) result = self.get_dns_obj().remove_txt(acme_txt + '.' + root)
print("[DNS]TXT记录删除成功") print("[DNS] TXT record deleted successfully")
...@@ -12,12 +12,22 @@ os.chdir(setup_path) ...@@ -12,12 +12,22 @@ os.chdir(setup_path)
sys.path.append("class/") sys.path.append("class/")
import requests,sewer,public import requests,sewer,public
from OpenSSL import crypto from OpenSSL import crypto
requests.packages.urllib3.disable_warnings() try:
requests.packages.urllib3.disable_warnings()
except:pass
import BTPanel import BTPanel
try:
import dns.resolver
except:
os.system("pip install dnspython")
try:
import dns.resolver
except:
pass
class panelLets: class panelLets:
let_url = "https://acme-v02.api.letsencrypt.org/directory" 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 #安装路径 setupPath = None #安装路径
server_type = None server_type = None
...@@ -72,17 +82,17 @@ class panelLets: ...@@ -72,17 +82,17 @@ class panelLets:
def get_error(self,error): def get_error(self,error):
if error.find("Max checks allowed") >= 0 : 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: 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: 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: 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: 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: 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: else:
return error; return error;
...@@ -111,10 +121,10 @@ class panelLets: ...@@ -111,10 +121,10 @@ class panelLets:
def renew_lest_cert(self,data): def renew_lest_cert(self,data):
#续签网站 #续签网站
path = self.setupPath + '/panel/vhost/cert/'+ data['siteName']; 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" 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) data['account_key'] = public.readFile(account_path)
...@@ -138,7 +148,9 @@ class panelLets: ...@@ -138,7 +148,9 @@ class panelLets:
pfx_buffer = p12.export() pfx_buffer = p12.export()
public.writeFile(path + "/fullchain.pfx",pfx_buffer,'wb+') 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): def apple_lest_cert(self,get):
...@@ -149,7 +161,7 @@ class panelLets: ...@@ -149,7 +161,7 @@ class panelLets:
data['email'] = get.email data['email'] = get.email
data['dnssleep'] = get.dnssleep 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] data['first_domain'] = data['domains'][0]
...@@ -174,7 +186,6 @@ class panelLets: ...@@ -174,7 +186,6 @@ class panelLets:
if data['app_root'] == '1': if data['app_root'] == '1':
domain_list = [] 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']: for domain in data['domains']:
rootDoamin = self.get_root_domain(domain) rootDoamin = self.get_root_domain(domain)
if not rootDoamin in domain_list: domain_list.append(rootDoamin) if not rootDoamin in domain_list: domain_list.append(rootDoamin)
...@@ -190,10 +201,13 @@ class panelLets: ...@@ -190,10 +201,13 @@ class panelLets:
else: else:
#手动解析提前返回 #手动解析提前返回
result = self.crate_let_by_oper(data) result = self.crate_let_by_oper(data)
public.writeFile(domain_path, json.dumps(result)) if 'status' in result and not result['status']: return result
result['code'] = 2
result['status'] = True 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 return result
elif get.dnsapi == 'dns_bt': elif get.dnsapi == 'dns_bt':
data['dnsapi'] = get.dnsapi data['dnsapi'] = get.dnsapi
...@@ -236,9 +250,13 @@ class panelLets: ...@@ -236,9 +250,13 @@ class panelLets:
cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
shell = 'python %s/panel/class/panelLets.py renew_lets_ssl ' % (self.setupPath) shell = 'python %s/panel/class/panelLets.py renew_lets_ssl ' % (self.setupPath)
public.writeFile(cronPath,shell) 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, 'Successful application.')
return public.returnMsg(True, '申请成功.')
#手动解析 #手动解析
def crate_let_by_oper(self,data): def crate_let_by_oper(self,data):
...@@ -282,6 +300,7 @@ class panelLets: ...@@ -282,6 +300,7 @@ class panelLets:
dns['finalize_url'] = finalize_url dns['finalize_url'] = finalize_url
return dns return dns
else: else:
responders = data['dns']['responders'] responders = data['dns']['responders']
dns_names_to_delete = data['dns']['dns_names'] dns_names_to_delete = data['dns']['dns_names']
finalize_url = data['dns']['finalize_url'] finalize_url = data['dns']['finalize_url']
...@@ -305,7 +324,7 @@ class panelLets: ...@@ -305,7 +324,7 @@ class panelLets:
result['status'] = True result['status'] = True
BTPanel.dns_client = None BTPanel.dns_client = None
else: else:
result['msg'] = '证书获取失败,请稍后重试.' result['msg'] = 'Certificate acquisition failed, please try again later.'
except Exception as e: except Exception as e:
print(public.get_error_info()) print(public.get_error_info())
...@@ -316,7 +335,7 @@ class panelLets: ...@@ -316,7 +335,7 @@ class panelLets:
def crate_let_by_dns(self,data): def crate_let_by_dns(self,data):
dns_class = self.get_dns_class(data) dns_class = self.get_dns_class(data)
if not dns_class: 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 = {}
result['status'] = False result['status'] = False
...@@ -341,8 +360,13 @@ class panelLets: ...@@ -341,8 +360,13 @@ class panelLets:
acme_keyauthorization, domain_dns_value = client.get_keyauthorization(dns_token) acme_keyauthorization, domain_dns_value = client.get_keyauthorization(dns_token)
dns_class.create_dns_record(dns_name, domain_dns_value) 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}) 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} ) responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"dns_challenge_url": dns_challenge_url} )
n = 0
while n<2:
print(n+1," verification")
try:
for i in responders: for i in responders:
auth_status_response = client.check_authorization_status(i["authorization_url"]) auth_status_response = client.check_authorization_status(i["authorization_url"])
r_data = auth_status_response.json() r_data = auth_status_response.json()
...@@ -350,6 +374,9 @@ class panelLets: ...@@ -350,6 +374,9 @@ class panelLets:
client.respond_to_challenge(i["acme_keyauthorization"], i["dns_challenge_url"]) 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_url = client.send_csr(finalize_url)
certificate = client.download_certificate(certificate_url) certificate = client.download_certificate(certificate_url)
...@@ -360,6 +387,7 @@ class panelLets: ...@@ -360,6 +387,7 @@ class panelLets:
result['key'] = client.certificate_key result['key'] = client.certificate_key
result['account_key'] = client.account_key result['account_key'] = client.account_key
result['status'] = True result['status'] = True
except Exception as e: except Exception as e:
print(public.get_error_info()) print(public.get_error_info())
raise e raise e
...@@ -378,6 +406,7 @@ class panelLets: ...@@ -378,6 +406,7 @@ class panelLets:
def crate_let_by_file(self,data): def crate_let_by_file(self,data):
result = {} result = {}
result['status'] = False result['status'] = False
result['clecks'] = []
try: try:
log_level = "INFO" log_level = "INFO"
if data['account_key']: log_level = 'ERROR' if data['account_key']: log_level = 'ERROR'
...@@ -404,9 +433,20 @@ class panelLets: ...@@ -404,9 +433,20 @@ class panelLets:
wellknown_path = acme_dir + '/' + http_token wellknown_path = acme_dir + '/' + http_token
public.writeFile(wellknown_path,acme_keyauthorization) public.writeFile(wellknown_path,acme_keyauthorization)
wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(http_name, http_token) wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(http_name, http_token)
result['clecks'].append({'wellknown_url':wellknown_url,'http_token':http_token});
retkey = public.httpGet(wellknown_url) is_check = False
n = 0
while n < 5:
print("wait_check_authorization_status")
try:
retkey = public.httpGet(wellknown_url,20)
if retkey == acme_keyauthorization: if retkey == acme_keyauthorization:
is_check = True
break
except :
pass
n += 1
if is_check:
sucess_domains.append(http_name) sucess_domains.append(http_name)
responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"http_challenge_url": http_challenge_url}) responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"http_challenge_url": http_challenge_url})
...@@ -431,9 +471,9 @@ class panelLets: ...@@ -431,9 +471,9 @@ class panelLets:
result['account_key'] = client.account_key result['account_key'] = client.account_key
result['status'] = True result['status'] = True
else: else:
result['msg'] = '证书获取失败,请稍后重试.' result['msg'] = 'Certificate acquisition failed, please try again later.'
else: 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: except Exception as e:
result['msg'] = self.get_error(str(e)) result['msg'] = self.get_error(str(e))
return result return result
...@@ -466,6 +506,30 @@ class panelLets: ...@@ -466,6 +506,30 @@ class panelLets:
} }
return identifier_auth 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): def get_cert_data(self,path):
try: try:
...@@ -514,18 +578,18 @@ class panelLets: ...@@ -514,18 +578,18 @@ class panelLets:
def renew_lets_ssl(self): def renew_lets_ssl(self):
cpath = self.setupPath + '/panel/vhost/cert/crontab.json' cpath = self.setupPath + '/panel/vhost/cert/crontab.json'
if not os.path.exists(cpath): if not os.path.exists(cpath):
print("|-当前没有可以续订的证书. " ); print("|-There are currently no certificates to renew." );
else: else:
old_list = json.loads(public.ReadFile(cpath)) old_list = json.loads(public.ReadFile(cpath))
print('=======================================================================') 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) cron_list = self.get_renew_lets_bytimeout(old_list)
tlist = [] tlist = []
for siteName in old_list: for siteName in old_list:
if not siteName in cron_list: tlist.append(siteName) if not siteName in cron_list: tlist.append(siteName)
print('|-[%s]未到期或网站未使用Let\'s Encrypt证书.' % (','.join(tlist))) print('|-[%s]Not expired or the site does not use the Let\'s Encrypt certificate.' % (','.join(tlist)))
print('|-%s 等待续签[%s].' % (time.strftime('%Y-%m-%d %X',time.localtime()),len(cron_list))) print('|-%s Waiting for renewal[%s].' % (time.strftime('%Y-%m-%d %X',time.localtime()),len(cron_list)))
sucess_list = [] sucess_list = []
err_list = [] err_list = []
...@@ -536,11 +600,11 @@ class panelLets: ...@@ -536,11 +600,11 @@ class panelLets:
sucess_list.append(siteName) sucess_list.append(siteName)
else: else:
err_list.append({"siteName":siteName,"msg":ret['msg']}) 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: if len(sucess_list) > 0:
print("|-续订成功%s" % (','.join(sucess_list))) print("|-Renewal success%s" % (','.join(sucess_list)))
if len(err_list) > 0: if len(err_list) > 0:
print("|-续订失败:") print("|-Renewal failed:")
for x in err_list: for x in err_list:
print(" %s ->> %s" % (x['siteName'],x['msg'])) print(" %s ->> %s" % (x['siteName'],x['msg']))
......
...@@ -934,7 +934,9 @@ class panelSite(panelRedirect): ...@@ -934,7 +934,9 @@ class panelSite(panelRedirect):
if match: apis[i]['data'][j]['value'] = match.groups()[0] if match: apis[i]['data'][j]['value'] = match.groups()[0]
if apis[i]['data'][j]['value']: is_write = True if apis[i]['data'][j]['value']: is_write = True
if is_write: public.writeFile('./config/dns_api.json',json.dumps(apis)) 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 #设置DNS-API
def SetDnsApi(self,get): def SetDnsApi(self,get):
......
...@@ -778,12 +778,17 @@ def getStrBetween(startStr,endStr,srcStr): ...@@ -778,12 +778,17 @@ def getStrBetween(startStr,endStr,srcStr):
#取CPU类型 #取CPU类型
def getCpuType(): def getCpuType():
cpuinfo = open('/proc/cpuinfo','r').read(); cpuinfo = open('/proc/cpuinfo','r').read()
rep = "model\s+name\s+:\s+(.+)" rep = "model\s+name\s+:\s+(.+)"
tmp = re.search(rep,cpuinfo); tmp = re.search(rep,cpuinfo,re.I);
cpuType = None cpuType = ''
if tmp: 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; return cpuType;
...@@ -1259,3 +1264,13 @@ def set_own(filename,user,group=None): ...@@ -1259,3 +1264,13 @@ def set_own(filename,user,group=None):
group = user_info.pw_gid group = user_info.pw_gid
os.chown(filename,user,group) os.chown(filename,user,group)
return True 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
[{ [{
"name":"七牛云存储", "name":"Google Cloud Storage",
"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",
"type":"Cron job", "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, "status":false,
"opt":"beta", "opt":"gcloud",
"module":"beta", "module":"google.cloud",
"script":"beta", "script":"google",
"help":"http://www.bt.cn/bbs/thread-1392-1-1.html", "help":"http://forum.aapanel.com",
"key":"", "key":"",
"secret":"", "secret":"",
"bucket":"", "bucket":"",
"domain":"", "domain":"",
"check":["data/beta.pl"] "check":["/www/server/panel/plugin/gcloud_storage/gcloud_storage_main.py","/www/server/panel/script/backup_gcloud.py"]
}] }]
\ No newline at end of file
...@@ -78,7 +78,7 @@ echo " ...@@ -78,7 +78,7 @@ echo "
+---------------------------------------------------------------------- +----------------------------------------------------------------------
" "
get_node_url(){ 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; i=1;
if [ ! -f /bin/curl ];then if [ ! -f /bin/curl ];then
if [ -f /usr/local/curl/bin/curl ];then if [ -f /usr/local/curl/bin/curl ];then
...@@ -201,7 +201,7 @@ timedatectl set-ntp 1 ...@@ -201,7 +201,7 @@ timedatectl set-ntp 1
#ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#echo 'Synchronizing system time...' #echo 'Synchronizing system time...'
#ntpdate 0.asia.pool.ntp.org ntpdate 0.asia.pool.ntp.org
startTime=`date +%s` startTime=`date +%s`
setenforce 0 setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
...@@ -374,18 +374,7 @@ Install_chardet() ...@@ -374,18 +374,7 @@ Install_chardet()
Install_setuptools Install_setuptools
Install_pip Install_pip
if [ "${download_Url}" = "$CN" ]; then curl -Ss --connect-timeout 3 -m 60 http://download.bt.cn/install/pip_select.sh|bash
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
isPsutil=`python -m psutil 2>&1|grep package` isPsutil=`python -m psutil 2>&1|grep package`
if [ "$isPsutil" != "" ];then if [ "$isPsutil" != "" ];then
...@@ -403,7 +392,9 @@ pip install paramiko==2.0.2 ...@@ -403,7 +392,9 @@ pip install paramiko==2.0.2
pip install flask-socketio==3.0.2 pip install flask-socketio==3.0.2
pip install python-socketio==2.1.2 pip install python-socketio==2.1.2
pip install Werkzeug==0.15.1 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 do
pip install ${p_name} pip install ${p_name}
done done
...@@ -418,7 +409,7 @@ if [ "$is_gevent" = "" ];then ...@@ -418,7 +409,7 @@ if [ "$is_gevent" = "" ];then
fi fi
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_Pillow
Install_psutil Install_psutil
...@@ -493,6 +484,9 @@ chkconfig --add bt ...@@ -493,6 +484,9 @@ chkconfig --add bt
chkconfig --level 2345 bt on chkconfig --level 2345 bt on
chmod -R 600 $setup_path/server/panel chmod -R 600 $setup_path/server/panel
chmod -R +x $setup_path/server/panel/script 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 ln -sf /etc/init.d/bt /usr/bin/bt
echo "$port" > $setup_path/server/panel/data/port.pl echo "$port" > $setup_path/server/panel/data/port.pl
/etc/init.d/bt start /etc/init.d/bt start
...@@ -617,6 +611,11 @@ fi ...@@ -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.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 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 echo /www > /var/bt_setupPath.conf
/etc/init.d/bt start /etc/init.d/bt start
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment