Compare commits

..
40 Commits
Author SHA1 Message Date
Mr Chen a1b3e70816 Merge pull request #531 from midoks/dev
0.16.4
2024-04-04 12:32:06 +08:00
Mr Chen 6f4479558f Update README.md 2024-04-04 12:31:17 +08:00
Mr Chen f817792aeb Update config_api.py 2024-04-04 12:29:34 +08:00
Mr Chen c8c0e44143 Update op_waf.js 2024-04-04 12:26:29 +08:00
Mr Chen 6668c2e14b update 2024-04-04 11:42:19 +08:00
Mr Chen 721f041c65 Update README.md 2024-04-04 00:20:05 +08:00
Mr Chen 87239f5361 Merge pull request #530 from midoks/dev
更新为支付宝
2024-04-04 00:18:55 +08:00
Mr Chen b48e3cbfcc update 2024-04-04 00:17:58 +08:00
Mr Chen 4b41c6df57 update 2024-04-02 00:17:20 +08:00
Mr Chen b491a6e913 Update README.md 2024-03-29 15:38:01 +08:00
Mr Chen 42271c5562 Merge pull request #529 from midoks/dev
discord
2024-03-29 15:30:24 +08:00
Mr Chen ef63465aea Update README.md 2024-03-29 15:28:40 +08:00
Mr Chen 98745e8134 Merge pull request #528 from midoks/dev
简单优化+ whatapp
2024-03-29 11:21:41 +08:00
Mr Chen 2fb293c89c Update README.md 2024-03-29 11:20:59 +08:00
Mr Chen 4e0db8d0a1 Update commit.tpl.ssh 2024-03-27 21:11:53 +08:00
Mr Chen 4b1e40b42d Update index.html 2024-03-26 17:47:26 +08:00
Mr Chen 935bee90f7 Update index.html 2024-03-26 17:42:25 +08:00
Mr Chen 0489a9df2c Update config_api.py 2024-03-19 23:29:27 +08:00
Mr Chen 20a4154240 update 2024-03-19 23:27:17 +08:00
Mr Chen a8ced31d32 Update mw.py 2024-03-19 23:24:40 +08:00
Mr Chen ac97b8f7ec Update tools.py 2024-03-19 23:21:19 +08:00
Mr Chen a797cd3741 Update push_notice_msg.py 2024-03-18 15:42:27 +08:00
Mr Chen a616736bf1 Merge pull request #526 from midoks/dev
AD及 二次验证
2024-03-18 15:26:22 +08:00
Mr Chen 8a90f5cb90 ad 2024-03-18 15:25:30 +08:00
Mr Chen 419d4abe8e Update login.html 2024-03-10 19:21:18 +08:00
Mr Chen ba555fba63 Update __init__.py 2024-03-10 19:16:05 +08:00
Mr Chen 7ead8708bc Update __init__.py 2024-03-10 19:15:42 +08:00
Mr Chen bd5b066afe Update __init__.py 2024-03-10 19:10:57 +08:00
Mr Chen 6d08c160e0 Update __init__.py 2024-03-10 19:10:27 +08:00
Mr Chen f24f8a3a16 Update config_api.py 2024-03-10 18:35:05 +08:00
Mr Chen 707b0d4b53 Update tools.py 2024-03-10 18:34:26 +08:00
Mr Chen d19e9cd8f4 二次验证,加强安全登录 2024-03-10 18:27:39 +08:00
Mr Chen a2d0cc6cfe Update requirements.txt 2024-03-10 14:43:53 +08:00
Mr Chen 356fd831fb Update requirements.txt 2024-03-10 14:33:09 +08:00
Mr Chen ec4988e732 update 2024-02-19 18:41:32 +08:00
Mr Chen 3a694b8d7d ad
# 海外服务器 高防CDN 解决移动屏蔽 | 19/m | next,2/19 | @YYCDNFW
2024-02-19 18:35:37 +08:00
Mr Chen d5945fd449 Merge pull request #524 from midoks/dev
更换GitHub Proxy
2024-02-08 16:47:46 +08:00
Mr Chen 10186786d9 更换GitHub Proxy
更换GitHub Proxy
2024-02-08 16:46:43 +08:00
Mr Chen 0eb8791e84 Merge pull request #523 from midoks/dev
Update sql_mysql.py
2024-02-07 01:57:51 +08:00
Mr Chen 5234b55798 Update sql_mysql.py 2024-02-07 01:54:30 +08:00
34 changed files with 341 additions and 121 deletions
+1 -2
View File
@@ -154,6 +154,7 @@ data/notify.json
data/api.json
data/bind_domain.pl
data/unauthorized_status.pl
data/auth_secret.pl
plugins/vip_*
plugins/own_*
@@ -175,7 +176,5 @@ plugins/proxysql
debug.out
mdioks.session-journal
*.session
+6 -11
View File
@@ -30,7 +30,7 @@
- 吹水组 - https://t.me/mdserver_web
- 交流论坛 - https://bbs.midoks.icu
- discord - https://discord.gg/3zXk4mES
```
如果出现问题,最好私给我面板信息。不要让我猜。如果不提供,不要提出问题,自行解决。 — 座右铭
Talk is cheap, show me the code. -- linus
@@ -90,7 +90,7 @@ PHP[72-83]支持phpMyAdmin[5.2.0]
# 特别赞助
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.pw/)
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan1.cc)
# AD - VPS推荐 - 🙏
@@ -110,15 +110,10 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
```
### 版本更新 0.16.3
### 版本更新 0.16.4
* 面板配置-可以配置时区。
* PHP(GD)扩展安装优化。
* PHP界面功能调整。
* PHP-FPM设置多个应用池(提高高并发稳定性)。
* MySQL(apt/yum)调整优化。
* 网站类型优化。
* 增加数据管理插件。
* 二次验证。
* OP防火墙修复。
### JSDelivr安装地址
@@ -196,7 +191,7 @@ TVbNgrpeGBGZVm5gTLa21ADP7RpnPFhjya
### 微信赞助
[![截图](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/weixin_zz.jpg)](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/weixin_zz.jpg)
[![截图](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/alipay_zz.jpg)](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/alipay_zz.jpg)
### 无图不真相
+105 -47
View File
@@ -28,9 +28,26 @@ from flask import request
class config_api:
__version = '0.16.3'
__version = '0.16.4'
__api_addr = 'data/api.json'
# 统一默认配置文件
__file = {
'api' : 'data/api.json', # API文件
'debug' : 'data/debug.pl', # DEBUG文件
'close' : 'data/close.pl', # 识别关闭面板文件
'basic_auth' : 'data/basic_auth.json', # 面板Basic验证
'admin_path' : 'data/admin_path.pl', # 面板后缀路径设置
'ipv6' : 'data/ipv6.pl', # ipv6识别文件
'bind_domain' : 'data/bind_domain.pl', # 面板域名绑定
'unauth_status' : 'data/unauthorized_status.pl', # URL路径未成功显示状态
'auth_secret': 'data/auth_secret.pl', # 二次验证密钥
'ssl':'data/ssl.pl', # ssl设置
'hook_database' : 'data/hook_database.json', # 数据库钩子
'hook_menu' : 'data/hook_menu.json', # 菜单钩子
'hook_global_static' : 'data/hook_global_static.json', # 静态文件钩子
}
def __init__(self):
pass
@@ -179,7 +196,7 @@ class config_api:
basic_open = request.form.get('is_open', '').strip()
salt = '_md_salt'
path = 'data/basic_auth.json'
path = self.__file['basic_auth']
is_open = True
if basic_open == 'false':
@@ -224,7 +241,7 @@ class config_api:
backup_path = request.form.get('backup_path', '')
if domain != '':
reg = "^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$"
reg = "^([\\w\\-\\*]{1,100}\\.){1,4}(\\w{1,10}|\\w{1,10}\\.\\w{1,10})$"
if not re.match(reg, domain):
return mw.returnJson(False, '主域名格式不正确')
@@ -286,7 +303,7 @@ class config_api:
return mw.returnJson(False, '安全入口地址长度不能小于6位!')
if admin_path in admin_path_checks:
return mw.returnJson(False, '该入口已被面板占用,请使用其它入口!')
if not re.match("^/[\w\./-_]+$", admin_path):
if not re.match("^/[\\w\\./-_]+$", admin_path):
return mw.returnJson(False, '入口地址格式不正确,示例: /mw_rand')
# else:
# domain = mw.readFile('data/bind_domain.pl')
@@ -300,7 +317,7 @@ class config_api:
# '警告,关闭安全入口等于直接暴露你的后台地址在外网,十分危险,至少开启以下一种安全方式才能关闭:<a
# style="color:red;"><br>1、绑定访问域名<br>2、绑定授权IP</a>')
admin_path_file = 'data/admin_path.pl'
admin_path_file = self.__file['admin_path']
admin_path_old = '/'
if os.path.exists(admin_path_file):
admin_path_old = mw.readFile(admin_path_file).strip()
@@ -311,7 +328,7 @@ class config_api:
return mw.returnJson(True, '修改成功!')
def closePanelApi(self):
filename = 'data/close.pl'
filename = self.__file['close']
if os.path.exists(filename):
os.remove(filename)
return mw.returnJson(True, '开启成功')
@@ -329,8 +346,8 @@ class config_api:
return mw.returnJson(True, '开发模式开启!')
def setIpv6StatusApi(self):
ipv6_file = 'data/ipv6.pl'
if os.path.exists('data/ipv6.pl'):
ipv6_file = self.__file['ipv6']
if os.path.exists(ipv6_file):
os.remove(ipv6_file)
mw.writeLog('面板设置', '关闭面板IPv6兼容!')
else:
@@ -400,7 +417,7 @@ class config_api:
# 设置面板SSL证书设置
def setPanelHttpToHttpsApi(self):
bind_domain = 'data/bind_domain.pl'
bind_domain = self.__file['bind_domain']
if not os.path.exists(bind_domain):
return mw.returnJson(False, '先要绑定域名!')
@@ -430,9 +447,9 @@ class config_api:
else:
conf = mw.readFile(panel_ssl)
if conf:
rep = "\n\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
rep = "\n\\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
conf = re.sub(rep, '', conf)
rep = "\s+if.+server_port.+\n.+\n\s+\s*}"
rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}"
conf = re.sub(rep, '', conf)
mw.writeFile(panel_ssl, conf)
@@ -445,7 +462,7 @@ class config_api:
# 删除面板证书
def delPanelSslApi(self):
bind_domain = 'data/bind_domain.pl'
bind_domain = self.__file['bind_domain']
if not os.path.exists(bind_domain):
return mw.returnJson(False, '未绑定域名!')
@@ -474,7 +491,7 @@ class config_api:
def applyPanelLetSslApi(self):
# check domain is bind?
bind_domain = 'data/bind_domain.pl'
bind_domain = self.__file['bind_domain']
if not os.path.exists(bind_domain):
return mw.returnJson(False, '先要绑定域名!')
@@ -531,7 +548,7 @@ class config_api:
panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf"
dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf"
cfg_domain = 'data/bind_domain.pl'
cfg_domain = self.__file['bind_domain']
if domain == '':
os.remove(cfg_domain)
os.remove(dst_panel_path)
@@ -560,7 +577,7 @@ class config_api:
# 设置面板SSL
def setPanelSslApi(self):
sslConf = mw.getRunDir() + '/data/ssl.pl'
sslConf = mw.getRunDir() + '/' + self.__file['ssl']
panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf"
dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf"
@@ -569,35 +586,35 @@ class config_api:
conf = mw.readFile(dst_panel_path)
if conf:
rep = "\s+ssl_certificate\s+.+;\s+ssl_certificate_key\s+.+;"
rep = "\\s+ssl_certificate\\s+.+;\\s+ssl_certificate_key\\s+.+;"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_protocols\s+.+;\n"
rep = "\\s+ssl_protocols\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_ciphers\s+.+;\n"
rep = "\\s+ssl_ciphers\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_prefer_server_ciphers\s+.+;\n"
rep = "\\s+ssl_prefer_server_ciphers\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_session_cache\s+.+;\n"
rep = "\\s+ssl_session_cache\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_session_timeout\s+.+;\n"
rep = "\\s+ssl_session_timeout\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_ecdh_curve\s+.+;\n"
rep = "\\s+ssl_ecdh_curve\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_session_tickets\s+.+;\n"
rep = "\\s+ssl_session_tickets\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_stapling\s+.+;\n"
rep = "\\s+ssl_stapling\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl_stapling_verify\s+.+;\n"
rep = "\\s+ssl_stapling_verify\\s+.+;\n"
conf = re.sub(rep, '', conf)
rep = "\s+ssl\s+on;"
rep = "\\s+ssl\\s+on;"
conf = re.sub(rep, '', conf)
rep = "\s+error_page\s497.+;"
rep = "\\s+error_page\\s497.+;"
conf = re.sub(rep, '', conf)
rep = "\s+if.+server_port.+\n.+\n\s+\s*}"
rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}"
conf = re.sub(rep, '', conf)
rep = "\s+listen\s+443.*;"
rep = "\\s+listen\\s+443.*;"
conf = re.sub(rep, '', conf)
rep = "\s+listen\s+\[\:\:\]\:443.*;"
rep = "\\s+listen\\s+\\[\\:\\:\\]\\:443.*;"
conf = re.sub(rep, '', conf)
mw.writeFile(dst_panel_path, conf)
@@ -628,7 +645,7 @@ class config_api:
conf = conf.replace('#error_page 404/404.html;', sslStr)
rep = "listen\s+([0-9]+)\s*[default_server]*;"
rep = "listen\\s+([0-9]+)\\s*[default_server]*;"
tmp = re.findall(rep, conf)
if not mw.inArray(tmp, '443'):
listen = re.search(rep, conf).group()
@@ -744,15 +761,15 @@ class config_api:
def setStatusCodeApi(self):
status_code = request.form.get('status_code', '').strip()
if re.match("^\d+$", status_code):
if re.match("^\\d+$", status_code):
status_code = int(status_code)
if status_code != 0:
if status_code < 100 or status_code > 999:
return mw.returnJson(False, '状态码范围错误!')
else:
return mw.returnJson(False, '状态码范围错误!')
mw.writeFile('data/unauthorized_status.pl', str(status_code))
unauthorized_status = self.__file['unauth_status']
mw.writeFile(unauthorized_status, str(status_code))
mw.writeLog('面板设置', '将未授权响应状态码设置为:{}'.format(status_code))
return mw.returnJson(True, '设置成功!')
@@ -871,8 +888,7 @@ class config_api:
if not 'token_crypt' in data:
token = mw.getRandomString(32)
data['token'] = mw.md5(token)
data['token_crypt'] = mw.enCrypt(
data['token'], token).decode('utf-8')
data['token_crypt'] = mw.enCrypt(data['token'], token).decode('utf-8')
token = stats[data['open']] + '成功!'
mw.writeLog('API配置', '%sAPI接口' % stats[data['open']])
@@ -888,7 +904,7 @@ class config_api:
return mw.returnJson(True, '保存成功!')
def renderUnauthorizedStatus(self, data):
cfg_unauth_status = 'data/unauthorized_status.pl'
cfg_unauth_status = self.__file['unauth_status']
if os.path.exists(cfg_unauth_status):
status_code = mw.readFile(cfg_unauth_status)
data['status_code'] = status_code
@@ -927,6 +943,37 @@ class config_api:
return mw.returnJson(True, '设置成功!')
def getAuthSecretApi(self):
reset = request.form.get('reset', '')
import pyotp
auth = self.__file['auth_secret']
tag = 'mdserver-web'
if os.path.exists(auth) and reset != '1':
content = mw.readFile(auth)
sec = mw.deDoubleCrypt(tag,content)
else:
sec = pyotp.random_base32()
crypt_data = mw.enDoubleCrypt(tag, sec)
mw.writeFile(auth, crypt_data)
ip = mw.getHostAddr()
url = pyotp.totp.TOTP(sec).provisioning_uri(name=ip, issuer_name='mdserver-web')
rdata = {}
rdata['secret'] = sec
rdata['url'] = url
return mw.returnJson(True, '设置成功!', rdata)
def setAuthSecretApi(self):
auth = self.__file['auth_secret']
if os.path.exists(auth):
os.remove(auth)
return mw.returnJson(True, '关闭成功!', 0)
else:
return mw.returnJson(True, '开启成功!', 1)
def get(self):
data = {}
@@ -939,31 +986,38 @@ class config_api:
data['port'] = mw.getHostPort()
data['ip'] = mw.getHostAddr()
admin_path_file = 'data/admin_path.pl'
admin_path_file = self.__file['admin_path']
if not os.path.exists(admin_path_file):
data['admin_path'] = '/'
else:
data['admin_path'] = mw.readFile(admin_path_file)
ipv6_file = 'data/ipv6.pl'
ipv6_file = self.__file['ipv6']
if os.path.exists(ipv6_file):
data['ipv6'] = 'checked'
else:
data['ipv6'] = ''
debug_file = 'data/debug.pl'
debug_file = self.__file['debug']
if os.path.exists(debug_file):
data['debug'] = 'checked'
else:
data['debug'] = ''
ssl_file = 'data/ssl.pl'
if os.path.exists('data/ssl.pl'):
ssl_file = self.__file['ssl']
if os.path.exists(ssl_file):
data['ssl'] = 'checked'
else:
data['ssl'] = ''
basic_auth = 'data/basic_auth.json'
auth_secret = self.__file['auth_secret']
if os.path.exists(auth_secret):
data['auth_secret'] = 'checked'
else:
data['auth_secret'] = ''
basic_auth = self.__file['basic_auth']
if os.path.exists(basic_auth):
bac = mw.readFile(basic_auth)
bac = json.loads(bac)
@@ -972,7 +1026,7 @@ class config_api:
else:
data['basic_auth'] = ''
cfg_domain = 'data/bind_domain.pl'
cfg_domain = self.__file['bind_domain']
if os.path.exists(cfg_domain):
domain = mw.readFile(cfg_domain)
data['bind_domain'] = domain.strip()
@@ -981,6 +1035,7 @@ class config_api:
data = self.renderUnauthorizedStatus(data)
#api
api_token = self.__api_addr
if os.path.exists(api_token):
bac = mw.readFile(api_token)
@@ -990,6 +1045,9 @@ class config_api:
else:
data['api_token'] = ''
#auth
data['site_count'] = mw.M('sites').count()
data['username'] = mw.M('users').where(
@@ -998,7 +1056,7 @@ class config_api:
data['hook_tag'] = request.args.get('tag', '')
# databases hook
database_hook_file = 'data/hook_database.json'
database_hook_file = self.__file['hook_database']
if os.path.exists(database_hook_file):
df = mw.readFile(database_hook_file)
df = json.loads(df)
@@ -1007,7 +1065,7 @@ class config_api:
data['hook_database'] = []
# menu hook
menu_hook_file = 'data/hook_menu.json'
menu_hook_file = self.__file['hook_menu']
if os.path.exists(menu_hook_file):
df = mw.readFile(menu_hook_file)
df = json.loads(df)
@@ -1016,7 +1074,7 @@ class config_api:
data['hook_menu'] = []
# global_static hook
global_static_hook_file = 'data/hook_global_static.json'
global_static_hook_file = self.__file['hook_global_static']
if os.path.exists(global_static_hook_file):
df = mw.readFile(global_static_hook_file)
df = json.loads(df)
+7 -7
View File
@@ -246,7 +246,7 @@ def isInstalledWeb():
def isIpAddr(ip):
check_ip = re.compile(
'^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$')
'^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$')
if check_ip.match(ip):
return True
else:
@@ -1176,10 +1176,10 @@ def getLocalIpBack():
url = 'http://pv.sohu.com/cityjson?ie=utf-8'
req = urllib.request.urlopen(url, timeout=10)
content = req.read().decode('utf-8')
ipaddress = re.search('\d+.\d+.\d+.\d+', content).group(0)
ipaddress = re.search('\\d+.\\d+.\\d+.\\d+', content).group(0)
writeFile(filename, ipaddress)
ipaddress = re.search('\d+.\d+.\d+.\d+', ipaddress).group(0)
ipaddress = re.search('\\d+.\\d+.\\d+.\\d+', ipaddress).group(0)
return ipaddress
except Exception as ex:
# print(ex)
@@ -1244,7 +1244,7 @@ def checkIp(ip):
# 检查是否为IPv4地址
import re
p = re.compile(
'^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
'^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$')
if p.match(ip):
return True
else:
@@ -1382,13 +1382,13 @@ def getCpuType():
# 取CPU类型
cpuinfo = open('/proc/cpuinfo', 'r').read()
rep = "model\s+name\s+:\s+(.+)"
rep = "model\\s+name\\s+:\\s+(.+)"
tmp = re.search(rep, cpuinfo, re.I)
if tmp:
cpuType = tmp.groups()[0]
else:
cpuinfo = execShell('LANG="en_US.UTF-8" && lscpu')[0]
rep = "Model\s+name:\s+(.+)"
rep = "Model\\s+name:\\s+(.+)"
tmp = re.search(rep, cpuinfo, re.I)
if tmp:
cpuType = tmp.groups()[0]
@@ -1772,7 +1772,7 @@ def getSSHPort():
try:
file = '/etc/ssh/sshd_config'
conf = readFile(file)
rep = "(#*)?Port\s+([0-9]+)\s*\n"
rep = "(#*)?Port\\s+([0-9]+)\\s*\n"
port = re.search(rep, conf).groups(0)[1]
return int(port)
except:
+5
View File
@@ -202,6 +202,11 @@ class nosqlMySQLCtr():
sql = 'select * from ' + table + where_sql + ' limit '+str(start_index)+',10';
# print(sql)
result = my_instance.query(sql)
for i in range(len(result)):
for f in result[i]:
result[i][f] = str(result[i][f])
# print(result)
page_args = {}
+1 -1
View File
@@ -38,7 +38,7 @@ Install_App()
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
HTTP_PREFIX="https://"
if [ ! -z "$cn" ];then
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
# FlameGraph start
+3 -1
View File
@@ -15,7 +15,9 @@ if [ ! -d $GIT_PROJECT_DIR ];then
fi
unset GIT_DIR
git config pull.rebase false
git config pull.rebase true
git config credential.helper store
cd $GIT_PROJECT_DIR && git pull
+6
View File
@@ -2598,6 +2598,10 @@ def trySlaveSyncBugfix(version=''):
gtid_purged = ''
var_slave_gtid = sdb.query('show VARIABLES like "%gtid_purged%"')
if len(var_slave_gtid) > 0:
gtid_purged += var_slave_gtid[0]['Value'] + ','
for i in range(len(slave_sync_data)):
port = slave_sync_data[i]['port']
password = slave_sync_data[i]['pass']
@@ -2617,6 +2621,8 @@ def trySlaveSyncBugfix(version=''):
if len(var_gtid) > 0:
gtid_purged += var_gtid[0]['Value'] + ','
gtid_purged = gtid_purged.strip(',')
sql = "set @@global.gtid_purged='" + gtid_purged + "'"
+6
View File
@@ -579,6 +579,12 @@ def reload():
mw.opWeb('start')
return 'ok'
def reload_hook():
s = status()
if s == 'start':
return reload()
return 'ok'
def getJsonPath(name):
path = getServerDir() + "/waf/" + name + ".json"
+3 -3
View File
@@ -5,9 +5,9 @@
"site_cb": {
"title":"网站统计",
"name":"op_waf",
"add":{"func":"reload"},
"update":{"func":"reload"},
"delete":{"func":"reload"}
"add":{"func":"reload_hook"},
"update":{"func":"reload_hook"},
"delete":{"func":"reload_hook"}
}
}
],
+1 -1
View File
@@ -87,7 +87,7 @@ Install_App(){
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
HTTP_PREFIX="https://"
if [ ! -z "$cn" ];then
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
# download GeoLite Data
+2 -1
View File
@@ -1614,8 +1614,9 @@ function wafSite(){
<label class="btswitch-btn" for="closeget_'+ i + '" onclick="setSiteObjState(\'' + k + '\',\'open\')"></label>\
</div>\
</td>\
<td class="text-right"><a onclick="wafLogs(\''+ k + '\')" class="btlink ' + (v.log_size > 0 ? 'dot' : '') + '">日志</a> | <a onclick="siteWafConfig(\'' + k + '\')" class="btlink">设置</a></td>\
<td class="text-right"><a onclick="wafLogs(\''+ k + '\')" class="btlink ' + (v.log_size > 0 ? 'dot' : '') + '">日志</a> </td>\
</tr>';
//| <a onclick="siteWafConfig(\'' + k + '\')" class="btlink">设置</a>
});
var con = '<div class="lib-box">\
+1 -1
View File
@@ -18,7 +18,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
if [ ! -d ${SERVER_ROOT}/icu ];then
+1 -1
View File
@@ -20,7 +20,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
if [ ! -d ${SERVER_ROOT}/libiconv ];then
+1 -1
View File
@@ -20,7 +20,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
# HTTP_PREFIX="https://"
+1 -1
View File
@@ -16,7 +16,7 @@ SOURCE_ROOT=$rootPath/source/lib
HTTP_PREFIX="https://"
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
which onig-config
+1 -1
View File
@@ -19,7 +19,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
if [ ! -d ${SERVER_ROOT}/openssl10 ];then
+1 -1
View File
@@ -20,7 +20,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
# HTTP_PREFIX="https://"
+2 -1
View File
@@ -84,7 +84,8 @@
<script type="text/javascript">
resetPluginWinWidth(700);
resetPluginWinWidth(800);
resetPluginWinHeight(400);
// $.getScript("/plugins/file?name=rsyncd&f=js/base64.js", function() {
// console.log('base64 load');
// });
+6 -2
View File
@@ -42,11 +42,15 @@ def send_msg(bot, tag='ad', trigger_time=300):
# 信号只在一个周期内执行一次|end
# https://t.me/gjgzs2022 | 22/m | @GJ_gzs
# https://zhaoziyuan.pw/ | web | 15/m | 2m | next,3/15 | @baleite
# 腾云机场 |9/m
# https://zhaoziyuan1.cc | web | 15/m | 2m | next,5/15 | @baleite
# 综合包网/NG接口开户 | 28/m | 3m | next,4/28 | @aabbcx888
# 实名认证/过人脸🕵️‍♀️各种账号处理✅ | 30/m| next,6/30 | @nngzs
# 海外服务器 高防CDN 解决移动屏蔽 | 19/m | next,4/19 | @YYCDNFW
keyboard = [
[
types.InlineKeyboardButton(
text="海外服务器 高防CDN 解决移动屏蔽", url='https://t.me/kltfuwuqi')
],
[
types.InlineKeyboardButton(
text="👑 综合包网/NG接口开户", url='https://t.me/NG_Tony')
@@ -51,11 +51,15 @@ def send_msg(bot, tag='ad', trigger_time=300):
# 信号只在一个周期内执行一次|end
# https://t.me/gjgzs2022 | 22/m | @GJ_gzs
# https://zhaoziyuan.pw/ | web | 15/m | 2m | next,3/15 | @baleite
# 腾云机场 |9/m
# https://zhaoziyuan1.cc | web | 15/m | 2m | next,5/15 | @baleite
# 综合包网/NG接口开户 | 28/m | 3m | next,4/28 | @aabbcx888
# 实名认证/过人脸🕵️‍♀️各种账号处理✅ | 30/m| next,6/30 | @nngzs
# 海外服务器 高防CDN 解决移动屏蔽 | 19/m | next,4/19 | @YYCDNFW
keyboard = [
[
types.InlineKeyboardButton(
text="海外服务器 高防CDN 解决移动屏蔽", url='https://t.me/kltfuwuqi')
],
[
types.InlineKeyboardButton(
text="🚀 综合包网/NG接口开户", url='https://t.me/NG_Tony')
+2 -1
View File
@@ -21,7 +21,7 @@ configparser==5.2.0
python-engineio==4.3.2
python-socketio>=4.2.0
flask-socketio==5.2.0
flask_sockets==0.2.1
flask-sockets==0.2.1
zmq==0.0.0
paramiko>=2.8.0
pymongo
@@ -31,6 +31,7 @@ pillow
Jinja2>=2.11.2
PyMySQL==1.0.2
whitenoise==5.3.0
pyotp
pytz
pyTelegramBotAPI
telebot
+41 -15
View File
@@ -187,8 +187,7 @@ def requestAfter(response):
def isLogined():
if 'login' in session and 'username' in session and session['login'] == True:
userInfo = mw.M('users').where(
"id=?", (1,)).field('id,username,password').find()
userInfo = mw.M('users').where("id=?", (1,)).field('id,username,password').find()
# print(userInfo)
if userInfo['username'] != session['username']:
return False
@@ -312,6 +311,34 @@ def checkLogin():
return "false"
@app.route("/verify_login", methods=['POST'])
def verifyLogin():
username = request.form.get('username', '').strip()
password = request.form.get('password', '').strip()
password = mw.md5(password)
userInfo = mw.M('users').where("id=?", (1,)).field('id,username,password').find()
if userInfo['username'] != username or userInfo['password'] != password:
return mw.returnJson(-1, "密码错误?")
auth = request.form.get('auth', '').strip()
import pyotp
auth_file = 'data/auth_secret.pl'
if os.path.exists(auth_file):
content = mw.readFile(auth_file)
sec = mw.deDoubleCrypt('mdserver-web', content)
totp = pyotp.TOTP(sec)
if totp.verify(auth):
userInfo = mw.M('users').where("id=?", (1,)).field('id,username,password').find()
session['login'] = True
session['username'] = userInfo['username']
session['overdue'] = int(time.time()) + 7 * 24 * 60 * 60
return mw.returnJson(1, '二次验证成功!')
return mw.returnJson(-1, '二次验证失败!')
@app.route("/do_login", methods=['POST'])
def doLogin():
login_cache_count = 5
@@ -343,13 +370,8 @@ def doLogin():
mw.writeLog('用户登录', code_msg)
return mw.returnJson(False, code_msg)
userInfo = mw.M('users').where(
"id=?", (1,)).field('id,username,password').find()
# print(userInfo)
# print(password)
userInfo = mw.M('users').where("id=?", (1,)).field('id,username,password').find()
password = mw.md5(password)
# print('md5-pass', password)
if userInfo['username'] != username or userInfo['password'] != password:
msg = "<a style='color: red'>密码错误</a>,帐号:{1},密码:{2},登录IP:{3}", ((
@@ -367,17 +389,23 @@ def doLogin():
cache.set('login_cache_limit', login_cache_limit, timeout=10000)
login_cache_limit = cache.get('login_cache_limit')
mw.writeLog('用户登录', mw.getInfo(msg))
return mw.returnJson(False, mw.getInfo("用户名或密码错误,您还可以尝试[{1}]次!", (str(login_cache_count - login_cache_limit))))
return mw.returnJson(-1, mw.getInfo("用户名或密码错误,您还可以尝试[{1}]次!", (str(login_cache_count - login_cache_limit))))
cache.delete('login_cache_limit')
# 二次验证密钥
auth_secret = 'data/auth_secret.pl'
if os.path.exists(auth_secret):
return mw.returnJson(2, '绑定二次验证了...')
session['login'] = True
session['username'] = userInfo['username']
session['overdue'] = int(time.time()) + 7 * 24 * 60 * 60
# session['overdue'] = int(time.time()) + 7
# fix 跳转时,数据消失,可能是跨域问题
# mw.writeFile('data/api_login.txt', userInfo['username'])
return mw.returnJson(True, '登录成功,正在跳转...')
return mw.returnJson(1, '登录成功,正在跳转...')
@app.errorhandler(404)
@@ -419,8 +447,7 @@ def login_temp_user(token):
return '连续10次验证失败,禁止1小时'
stime = int(time.time())
data = mw.M('temp_login').where('state=? and expire>?',
(0, stime)).field('id,token,salt,expire,addtime').find()
data = mw.M('temp_login').where('state=? and expire>?',(0, stime)).field('id,token,salt,expire,addtime').find()
if not data:
setErrorNum(skey)
return '验证失败!'
@@ -434,8 +461,7 @@ def login_temp_user(token):
setErrorNum(skey)
return '验证失败!'
userInfo = mw.M('users').where(
"id=?", (1,)).field('id,username').find()
userInfo = mw.M('users').where("id=?", (1,)).field('id,username').find()
session['login'] = True
session['username'] = userInfo['username']
session['tmp_login'] = True
+59 -1
View File
@@ -1002,7 +1002,7 @@ function setTempAccess(){
shift: 0,
type: 1,
content: "<div class=\"login_view_table pd20\">\
<button class=\"btn btn-success btn-sm create_temp_login\" >临时访问授权</button>\
<button class=\"btn btn-success btn-sm create_temp_login\">临时访问授权</button>\
<div class=\"divtable mt10\">\
<table class=\"table table-hover\">\
<thead>\
@@ -1062,6 +1062,64 @@ function setTempAccess(){
});
}
//二次验证
function setAuthBind(){
$.post('/config/get_auth_secret', {}, function(rdata){
console.log(rdata);
var tip = layer.open({
area: ['500px', '355px'],
title: '二次验证设置',
closeBtn:1,
shift: 0,
type: 1,
content: '<div class="bt-form pd20">\
<div class="line">\
<span class="tname">绑定密钥</span>\
<div class="info-r">\
<input class="bt-input-text mr5" name="secret" type="text" style="width: 310px;" disabled>\
<button class="btn btn-success btn-xs reset_secret" style="margin-left: -50px;">重置</button>\
</div>\
</div>\
<div class="line">\
<span class="tname" style="width: 90px; overflow: initial; height: 20px; line-height: 20px;">二维码</span>\
<div class="info-r"><div class="qrcode"></div></div>\
</div>\
<ul class="help-info-text c7">\
</ul>\
</div>',
success:function(layero,index){
$('input[name="secret"]').val(rdata.data['secret']);
$('.qrcode').qrcode({ text: rdata.data['url']});
$('.reset_secret').click(function(){
layer.confirm('您确定要重置当前密钥吗?<br/><span style="color: red; ">重置密钥后,已关联密钥产品,将失效,请重新添加新密钥至产品。</span>',{title:'重置密钥',closeBtn:2,icon:13,cancel:function(){
}}, function() {
$.post('/config/get_auth_secret', {'reset':"1"},function(rdata){
showMsg("接口密钥已生成,重置密钥后,已关联密钥产品,将失效,请重新添加新密钥至产品。", function(){
$('input[name="secret"]').val(rdata.data['secret']);
$('.qrcode').html('').qrcode({ text: rdata.data['url']});
} ,{icon:1}, 2000);
},'json');
});
});
},
});
},'json');
}
function setAuthSecretApi(){
var cfg_panel_auth = $('#cfg_panel_auth').prop("checked");
$.post('/config/set_auth_secret', {'op_type':"2"},function(rdata){
showMsg(rdata.msg, function(){
if (rdata.data == 1){
setAuthBind();
}
} ,{icon:rdata.status?1:2}, 1000);
},'json');
}
function setBasicAuthTip(callback){
var tip = layer.open({
area: ['500px', '385px'],
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

+9 -1
View File
@@ -128,7 +128,7 @@
<p class="mtb15">
<span class="set-tit text-right" title="API接口" style="float: left;">API接口</span>
<input class="btswitch btswitch-ios" id="cfg_panel_api" type="checkbox" {{data['api_token']}}/>
<input class="btswitch btswitch-ios" id="cfg_panel_api" type="checkbox" {{data['api_token']}}/>
<label class="btswitch-btn ml5" for="cfg_panel_api" style="float: left;margin-top:4px;" onclick="setPanelApi()"></label>
<button ype="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="showPanelApi();">API接口配置</button>
<span class="set-info c7">提供面板API接口访问的支持</span>
@@ -146,6 +146,14 @@
<button type="button" class="btn btn-success btn-sm ml5" onclick="setTempAccess()">临时访问授权管理</button>
<span class="set-info c7">为非管理员临时提供面板访问权限</span>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="二次验证" style="float: left;">二次验证</span>
<input class="btswitch btswitch-ios" id="cfg_panel_auth" type="checkbox" {{data['auth_secret']}}/>
<label class="btswitch-btn ml5" for="cfg_panel_auth" style="float: left;margin-top:4px;" onclick="setAuthSecretApi()"></label>
<button type="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="setAuthBind();">绑定设置</button>
<span class="set-info c7">二次验证,加强安全登录</span>
</p>
</div>
+1
View File
@@ -92,6 +92,7 @@
<script src="/static/js/jquery.dragsort-0.5.2.min.js"></script>
<script src="/static/js/jquery-qrcode-0.18.0.min.js?v={{config.version}}"></script>
<script src="/static/js/xm-select.js"></script>
{% block content %}{% endblock %}
+44 -7
View File
@@ -8,6 +8,7 @@
<link rel="icon" href="/static/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon" />
<title>{{data['title']}}</title>
<link rel="stylesheet" type="text/css" href="/static/layer/skin/default/layer.css?v={{config.version}}">
<link rel="stylesheet" type="text/css" href="/static/css/site.css?v={{config.version}}">
<link rel="stylesheet" type="text/css" href="/static/css/login.css?v={{config.version}}">
<style type="text/css">
@@ -29,6 +30,7 @@
.bg_img.pc:hover{
background-position: -60px -60px;
}
.qrCode{
text-align: center;
padding-top: 20px;
@@ -70,9 +72,11 @@
padding: 20px;
background-color: #fff;
}
.list_scan .weChatSamll img{
width: 100%;
}
.list_scan .weChatSamll em{
position: absolute;
border: 7px solid #ececec;
@@ -83,6 +87,7 @@
bottom: -14px;
margin-left: -6px;
}
.tips{
width: 115px;
position: absolute;
@@ -94,6 +99,7 @@
text-align: center;
border-radius: 4px;
}
.tips em{
position: absolute;
border: 6px solid #dff0d8;
@@ -104,6 +110,7 @@
top: 8px;
margin-left: -6px;
}
.tips img{
height: 16px;
width: 16px;
@@ -115,6 +122,10 @@
margin-top: 15px;
margin-bottom: 25px;
}
.layui-layer .layui-layer-btn{
width: 235px;
}
</style>
</head>
<body>
@@ -123,11 +134,14 @@
<div class="account">
<form class="loginform" method="post" action="/login" onsubmit="return false;">
<div class="rlogo">{{data['title']}}</div>
<div class="line"><input class="inputtxt" value="" name="username" datatype="*" nullmsg="请填写账户" errormsg="请填写账户" placeholder="账户" type="text"><div class="Validform_checktip"></div></div>
<div class="line">
<input class="inputtxt" value="" name="username" datatype="*" nullmsg="请填写账户" errormsg="请填写账户" placeholder="账户" type="text">
<div class="Validform_checktip"></div>
</div>
<div class="line"><input class="inputtxt" name="password" value="" datatype="*" nullmsg="请填写密码" errormsg="请填写密码" placeholder="密码" type="password">
<div class="Validform_checktip"></div>
</div>
<div style="color: red;position: relative;top: -14px;" id="errorStr"></div>
<div style="color: red;position: relative;top: -14px;" id="error"></div>
<div class="line yzm" style="top: -5px;{% if not session['code'] %}display:none;{% endif %}">
<input type="text" class="inputtxt" name="code" nullmsg="请填写4位验证码" errormsg="验证码" datatype="*" placeholder="验证码">
<div class="Validform_checktip"></div>
@@ -150,6 +164,7 @@
$(function(){
wreset();
})
window.onresize=function(){
wreset();
}
@@ -188,19 +203,21 @@ $('#login-button').click(function(){
}
var data = 'username='+username+'&password='+password+'&code='+code;
var loadT = layer.msg("正在登录中",{icon:16,time:0,shade: [0.3, '#000']});
var loadT = layer.msg("正在登录中...",{icon:16,time:0,shade: [0.3, '#000']});
$.post('/do_login',data,function(rdata){
console.log(rdata);
layer.close(loadT);
if(!rdata.status){
if(status < 0){
if(username == 'admin' && rdata.msg.indexOf('用户名') != -1){
rdata.msg += ', <br>获取默认用户和密码命令: mw default';
}
$("#errorStr").html(rdata.msg);
$("#error").html(rdata.msg);
$("input[name='password']").val('');
num = rdata.msg.substring(rdata.msg.indexOf('[')+1,rdata.msg.indexOf(']'))
if(num < 5){
$('#mw_yzm').html('<img width="100" height="40" class="passcode" onClick="this.src=this.src.split(\'?\')[0] + \'?\'+new Date().getTime()" src="/code" style="border: 1px solid #ccc; float: right;" title="" >');
$(".login").css("height","332px");
var code_html = '<img width="100" height="40" class="passcode" onClick="this.src=this.src.split(\'?\')[0] + \'?\'+new Date().getTime()" src="/code" style="border: 1px solid #ccc; float: right;">';
$('#mw_yzm').html(code_html);
// $(".login").css("height","332px");
$("input[name='code']").val('');
$(".passcode").click();
}
@@ -209,6 +226,26 @@ $('#login-button').click(function(){
layer.msg(rdata.msg,{icon:2,time:5000});
return;
}
if (rdata.status == 2){
layer.prompt({
formType: 3,
value: '',
title: '二次验证',
}, function(value, index, elem){
$.post('/verify_login',{'auth':value,'username':username,'password':password},function(vdata){
if (vdata.status < 0){
layer.msg(vdata.msg,{icon:2,time:5000});
return;
}
layer.close(index);
window.location.href = '/';
},'json');
});
return;
}
layer.msg(rdata.msg,{icon:16,time:0,shade: [0.3, '#000']});
window.location.href = '/';
+2 -2
View File
@@ -64,7 +64,7 @@ fi
# ping -c 1 github.com > /dev/null 2>&1
# if [ "$?" != "0" ];then
# LOCAL_ADDR=cn
# HTTP_PREFIX="https://ghproxy.com/"
# HTTP_PREFIX="https://mirror.ghproxy.com/"
# fi
HTTP_PREFIX="https://"
@@ -72,7 +72,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
echo "local:${LOCAL_ADDR}"
+2 -2
View File
@@ -67,7 +67,7 @@ fi
# ping -c 1 github.com > /dev/null 2>&1
# if [ "$?" != "0" ];then
# LOCAL_ADDR=cn
# HTTP_PREFIX="https://ghproxy.com/"
# HTTP_PREFIX="https://mirror.ghproxy.com/"
# fi
HTTP_PREFIX="https://"
@@ -75,7 +75,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
echo "local:${LOCAL_ADDR}"
+2 -2
View File
@@ -62,14 +62,14 @@ fi
# ping -c 1 github.com > /dev/null 2>&1
# if [ "$?" != "0" ];then
# LOCAL_ADDR=cn
# HTTP_PREFIX="https://ghproxy.com/"
# HTTP_PREFIX="https://mirror.ghproxy.com/"
# fi
HTTP_PREFIX="https://"
LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
PIPSRC="https://pypi.python.org/simple"
+1 -1
View File
@@ -62,7 +62,7 @@ LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
echo "local:${LOCAL_ADDR}"
+2 -2
View File
@@ -61,14 +61,14 @@ fi
# ping -c 1 github.com > /dev/null 2>&1
# if [ "$?" != "0" ];then
# LOCAL_ADDR=cn
# HTTP_PREFIX="https://ghproxy.com/"
# HTTP_PREFIX="https://mirror.ghproxy.com/"
# fi
HTTP_PREFIX="https://"
LOCAL_ADDR=common
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
LOCAL_ADDR=cn
HTTP_PREFIX="https://ghproxy.com/"
HTTP_PREFIX="https://mirror.ghproxy.com/"
fi
echo "local:${LOCAL_ADDR}"
+10 -2
View File
@@ -61,6 +61,7 @@ def mwcli(mw_input=0):
print("(22) 开启IPV6支持")
print("(23) 关闭IPV6支持")
print("(24) 开启防火墙SSH端口")
print("(25) 关闭二次验证")
print("(100) 开启PHP52显示")
print("(101) 关闭PHP52显示")
print("(200) 切换Linux系统软件源")
@@ -74,7 +75,7 @@ def mwcli(mw_input=0):
except:
mw_input = 0
nums = [1, 2, 3, 4, 5, 10, 11, 12, 13, 20, 21, 22, 23, 24, 100, 101, 200, 201]
nums = [1, 2, 3, 4, 5, 10, 11, 12, 13, 20, 21, 22, 23, 24, 25, 100, 101, 200, 201]
if not mw_input in nums:
print(raw_tip)
print("已取消!")
@@ -145,6 +146,13 @@ def mwcli(mw_input=0):
elif mw_input == 24:
open_ssh_port()
print("|-已开启!")
elif mw_input == 25:
auth_secret = 'data/auth_secret.pl'
if os.path.exists(auth_secret):
os.remove(auth_secret)
print("|-关闭二次验证成功!")
else:
print("|-二次验证已关闭!")
elif mw_input == 100:
php_conf = 'plugins/php/info.json'
if os.path.exists(php_conf):
@@ -169,7 +177,7 @@ def mwcli(mw_input=0):
def open_ssh_port():
import firewall_api
find_ssh_port_cmd = "cat /etc/ssh/sshd_config | grep '^Port \d*' | tail -1"
find_ssh_port_cmd = "cat /etc/ssh/sshd_config | grep '^Port \\d*' | tail -1"
cmd_data = mw.execShell(find_ssh_port_cmd)
ssh_port = cmd_data[0].replace("Port ", '').strip()
if ssh_port == '':