diff --git a/class/common.py b/class/common.py index 0f55d9e8..070e76a2 100644 --- a/class/common.py +++ b/class/common.py @@ -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; diff --git a/class/crontab.py b/class/crontab.py index 61a002f4..4170e453 100644 --- a/class/crontab.py +++ b/class/crontab.py @@ -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 #取任务日志 diff --git a/class/panelDnsapi.py b/class/panelDnsapi.py index 63effd13..42fceaa7 100644 --- a/class/panelDnsapi.py +++ b/class/panelDnsapi.py @@ -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") diff --git a/class/panelLets.py b/class/panelLets.py index 3d7675ba..a035dcf5 100644 --- a/class/panelLets.py +++ b/class/panelLets.py @@ -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 '

签发失败,您今天尝试申请证书的次数已达上限!

' + return '

The signing failed, and the number of attempts to apply for a certificate today has reached the limit!

' 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 '

签发失败,域名解析错误,或解析未生效,或域名未备案!

' + return '

The signing failed, the domain name resolution error, or the resolution is not valid, or the domain name is not filed!

' 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'] = "签发失败,我们无法验证您的域名:

1、检查域名是否绑定到对应站点

2、检查域名是否正确解析到本服务器,或解析还未完全生效

3、如果您的站点设置了反向代理,或使用了CDN,请先将其关闭

4、如果您的站点设置了301重定向,请先将其关闭

5、如果以上检查都确认没有问题,请尝试更换DNS服务商

'" + result['msg'] = "The signing failed, we were unable to verify your domain name:

1. Check if the domain name is bound to the corresponding site.

2. Check if the domain name is correctly resolved to the server, or the resolution is not fully effective.

3. If your site has a reverse proxy set up, or if you are using a CDN, please turn it off first.

4. If your site has a 301 redirect, please turn it off first

5. If the above checks confirm that there is no problem, please try to change the DNS service provider.

'" 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'])) diff --git a/class/panelSite.py b/class/panelSite.py index 35b57218..aea6405b 100644 --- a/class/panelSite.py +++ b/class/panelSite.py @@ -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): diff --git a/class/public.py b/class/public.py index cd02a026..aed39145 100644 --- a/class/public.py +++ b/class/public.py @@ -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 + diff --git a/data/libList.conf b/data/libList.conf index 636a0a72..05348248 100644 --- a/data/libList.conf +++ b/data/libList.conf @@ -1,57 +1,15 @@ [{ - "name":"七牛云存储", - "type":"计划任务", - "ps":"将网站或数据库打包备份到七牛对象存储空间,七牛提供10GB免费存储空间, 点击申请", - "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免费存储空间, 点击申请", - "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"] }] \ No newline at end of file diff --git a/init.sh b/init.sh index 8564df54..e11f1569 100644 --- a/init.sh +++ b/init.sh @@ -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 <&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