Compare commits

...
60 Commits
Author SHA1 Message Date
Mr Chen 1bc24b12fc Merge pull request #278 from midoks/dev
0.11.1
2022-11-29 10:47:24 +08:00
midoks b2fdc8212f 0.11.1
* 提供面板API接口访问的支持。
* rockylinux系统安装优化。
* 网站统计记录POST请求原文优化。
* 针对mysql下载速度优化。
* mysql初始化默认参数优化。
* OP防火墙安全设置BUG解决。
* Gitea优化。
2022-11-29 10:42:35 +08:00
midoks ab763f444b up 2022-11-29 10:19:56 +08:00
midoks c0738ff1bd Update config_api.py 2022-11-29 03:06:03 +08:00
midoks 82dd2553e6 网站统计记录POST请求原文优化 2022-11-29 02:58:52 +08:00
midoks ae371be91a Update install.sh 2022-11-29 02:47:09 +08:00
midoks 48e1ecaec6 up 2022-11-28 21:46:56 +08:00
midoks 5a21c4dac8 优化下载速度 2022-11-28 21:35:07 +08:00
midoks 7e014dfa94 提供面板API接口访问的支持
还有功能要上,肯能会影响使用,,测试使用即可。
2022-11-28 20:14:45 +08:00
midoks 93785a2472 Update ioncube.sh 2022-11-28 17:05:51 +08:00
midoks cd0f5fd8a0 Update rocky.sh 2022-11-28 16:05:03 +08:00
midoks d12524debd Update info.json 2022-11-28 11:52:44 +08:00
midoks 297fb60fcb Update mw.tpl 2022-11-28 11:50:55 +08:00
midoks d3781edad0 Update close.html 2022-11-28 11:50:51 +08:00
midoks 78667460e6 up 2022-11-28 11:50:36 +08:00
midoks decc579c2d up 2022-11-28 10:35:32 +08:00
midoks 34a64eafa2 Update install_dev.sh 2022-11-28 02:06:52 +08:00
midoks 38b263e689 Update rocky.sh 2022-11-28 02:04:37 +08:00
midoks 0ad3e8d42c Update rocky.sh 2022-11-28 02:02:39 +08:00
midoks 5243f6f4c3 Update rocky.sh 2022-11-28 01:53:52 +08:00
midoks 976c8c3271 Update lib.sh 2022-11-28 01:42:10 +08:00
midoks b627b222bc Update lib.sh 2022-11-28 01:40:40 +08:00
midoks 8df8365eaa Update rocky.sh 2022-11-28 01:32:44 +08:00
midoks d735d857a4 Update rocky.sh 2022-11-28 01:22:21 +08:00
midoks 211764060f up 2022-11-28 01:21:00 +08:00
midoks b07be2d004 Update lib.sh 2022-11-28 01:17:33 +08:00
midoks c6edd2221c Update backup.py 2022-11-28 00:08:36 +08:00
midoks be8dd153a3 up 2022-11-27 23:31:48 +08:00
midoks e4aef4592e Update index.py 2022-11-27 22:34:41 +08:00
midoks 4f5b25a680 Update index.py 2022-11-27 22:12:37 +08:00
midoks abc4486311 up 2022-11-27 21:51:32 +08:00
midoks baeb788148 up 2022-11-27 20:46:31 +08:00
midoks e30dcf1fbe 修改优惠码 2022-11-27 14:12:52 +08:00
midoks e7347c4a4c Update index.py 2022-11-27 11:20:41 +08:00
midoks 044cad1e64 API接口 后台ui 完成。 功能50% 2022-11-27 00:28:09 +08:00
midoks c0d0efb756 up 2022-11-26 16:23:58 +08:00
midoks 49d1579782 Update index.py 2022-11-26 13:20:24 +08:00
midoks b6f7ec11c2 Update install.sh 2022-11-25 23:52:09 +08:00
midoks 0860ffc713 Update install.sh 2022-11-25 23:48:12 +08:00
midoks cd3f7603e8 Update install.sh 2022-11-25 23:47:15 +08:00
midoks bc0e7764b2 Update install.sh 2022-11-25 23:45:19 +08:00
midoks cfe185b105 Update gitea.service.tpl 2022-11-25 23:24:28 +08:00
midoks 3094a0af32 Update index.py 2022-11-25 16:47:44 +08:00
midoks 7f010caa6e Update index.py 2022-11-25 16:46:25 +08:00
midoks 2b6d287cf1 Update index.py 2022-11-25 16:43:13 +08:00
midoks e525323a7d Update index.py 2022-11-25 16:38:11 +08:00
midoks 69670aa1f6 Update index.py 2022-11-25 16:26:13 +08:00
midoks d741677b66 Update index.py 2022-11-25 16:21:22 +08:00
midoks 7fd4ea28c1 Update .gitignore 2022-11-25 13:27:21 +08:00
midoks 41294a23a2 Update .gitignore 2022-11-25 12:10:39 +08:00
midoks 86edf89474 Update .gitignore 2022-11-25 09:25:15 +08:00
midoks e2f4043569 Create fastdfs.conf 2022-11-24 19:10:33 +08:00
midoks 6ebcb8e005 up 2022-11-24 18:21:25 +08:00
midoks 088b7425d7 Update backup.py 2022-11-23 19:56:41 +08:00
midoks f854eed924 Update config.js 2022-11-23 19:42:56 +08:00
Mr Chen ba706e070e Merge pull request #269 from midoks/dev
ipv6识别启动优化
2022-11-23 11:50:23 +08:00
midoks 2cdaa36744 Update mw.tpl 2022-11-23 11:46:26 +08:00
midoks 7937189935 up 2022-11-23 02:38:03 +08:00
midoks 1b7f1e2f13 Update info.json 2022-11-23 02:29:19 +08:00
midoks a88483e2ba Update .gitignore 2022-11-22 20:15:18 +08:00
56 changed files with 688 additions and 120 deletions
+6 -1
View File
@@ -107,7 +107,6 @@ venv.bak/
tmp/*
*.swp
*.zip
scripts/init.d/mw
logs/*
data/*.db
data/control.conf
@@ -132,7 +131,9 @@ include
share
pip-selfcheck.json
scripts/init.d/mw
scripts/mdserver-web
data/api_login.txt
data/sessions
data/ssl.pl
@@ -147,6 +148,7 @@ data/system.db-journal
data/hook_*.json
data/letsencrypt.json
data/basic_auth.json
data/api.json
plugins/l2tp
plugins/openlitespeed
@@ -155,6 +157,9 @@ plugins/mtproxy
plugins/zimg
plugins/bk_demo
plugins/mail
plugins/fastdfs
plugins/v2ray
plugins/frp
debug.out
+10 -12
View File
@@ -78,7 +78,7 @@ PHP[72-81]支持phpMyAdmin[5.2.0]
| 服务商 | LOGO | 推广地址 | 优惠码 |
| ------------- |----------|-----------|-------|
| digitalvirt |[![digitalvirt](https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg)](https://digitalvirt.com/aff.php?aff=154) | https://digitalvirt.com/aff.php?aff=154 | 9SYDY7UH0U |
| digitalvirt |[![digitalvirt](https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg)](https://digitalvirt.com/aff.php?aff=154) | https://digitalvirt.com/aff.php?aff=154 | mdserver-web |
| 搬瓦工 |[![搬瓦工](https://bwh81.net/templates/organicbandwagon/images/logo.png)](https://bwh81.net/aff.php?aff=54161) | https://bwh81.net/aff.php?aff=54161 | BWH3HYATVBJW |
# Docker
@@ -91,18 +91,16 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
```
### 版本更新 0.11.0
### 版本更新 0.11.1
* 提供面板API接口访问的支持。
* rockylinux系统安装优化。
* 网站统计记录POST请求原文优化。
* 针对mysql下载速度优化。
* mysql初始化默认参数优化。
* OP防火墙安全设置BUG解决。
* Gitea优化。
* 改造HTTPS升级,为lets和acme申请。
* 改造SSH管理,加入`禁止密码登陆`。
* 计划任务BUG,修改时错误提示。
* PG在debian11优化。
* PHP默认配置curl,openssl ssl配置优化。
* 初始花安装提示。
* 面板设置UI优化。
* 加入BasicAuth认证功能。
* MySQL[APT,YUM]安装检查优化。
* MySQL导入优化,对sql后缀支持。
### JSDelivr安装地址
+90 -1
View File
@@ -27,7 +27,8 @@ from flask import request
class config_api:
__version = '0.11.0'
__version = '0.11.1.1'
__api_addr = 'data/api.json'
def __init__(self):
pass
@@ -489,6 +490,85 @@ class config_api:
'id,type,uid,log,addtime').select()
return mw.returnJson(False, 'ok', data)
def checkPanelToken(self):
api_file = self.__api_addr
if not os.path.exists(api_file):
return False, ''
tmp = mw.readFile(api_file)
data = json.loads(tmp)
if data['open']:
return True, data
else:
return False, ''
def getPanelTokenApi(self):
api_file = self.__api_addr
tmp = mw.readFile(api_file)
if not os.path.exists(api_file):
ready_data = {"open": False, "token": "", "limit_addr": []}
mw.writeFile(api_file, json.dumps(ready_data))
mw.execShell("chmod 600 " + api_file)
tmp = mw.readFile(api_file)
data = json.loads(tmp)
if not 'key' in data:
data['key'] = mw.getRandomString(16)
mw.writeFile(api_file, json.dumps(data))
if 'token_crypt' in data:
data['token'] = mw.deCrypt(data['token'], data['token_crypt'])
else:
token = mw.getRandomString(32)
data['token'] = mw.md5(token)
data['token_crypt'] = mw.enCrypt(
data['token'], token).decode('utf-8')
mw.writeFile(api_file, json.dumps(data))
data['token'] = "***********************************"
data['limit_addr'] = '\n'.join(data['limit_addr'])
del(data['key'])
return mw.returnJson(True, 'ok', data)
def setPanelTokenApi(self):
op_type = request.form.get('op_type', '').strip()
api_file = self.__api_addr
tmp = mw.readFile(api_file)
data = json.loads(tmp)
if op_type == '1':
token = mw.getRandomString(32)
data['token'] = mw.md5(token)
data['token_crypt'] = mw.enCrypt(
data['token'], token).decode('utf-8')
mw.writeLog('API配置', '重新生成API-Token')
mw.writeFile(api_file, json.dumps(data))
return mw.returnJson(True, 'ok', token)
elif op_type == '2':
data['open'] = not data['open']
stats = {True: '开启', False: '关闭'}
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')
token = stats[data['open']] + '成功!'
mw.writeLog('API配置', '%sAPI接口' % stats[data['open']])
mw.writeFile(api_file, json.dumps(data))
return mw.returnJson(not not data['open'], token)
elif op_type == '3':
limit_addr = request.form.get('limit_addr', '').strip()
data['limit_addr'] = limit_addr.split('\n')
mw.writeLog('API配置', '变更IP限制为[%s]' % limit_addr)
mw.writeFile(api_file, json.dumps(data))
return mw.returnJson(True, '保存成功!')
def get(self):
data = {}
@@ -534,6 +614,15 @@ class config_api:
else:
data['basic_auth'] = ''
api_token = self.__api_addr
if os.path.exists(api_token):
bac = mw.readFile(api_token)
bac = json.loads(bac)
if bac['open']:
data['api_token'] = 'checked'
else:
data['api_token'] = ''
data['site_count'] = mw.M('sites').count()
data['username'] = mw.M('users').where(
+29 -1
View File
@@ -541,6 +541,34 @@ def dePunycode(domain):
return newdomain[0:-1]
def enCrypt(key, strings):
# 加密字符串
try:
if type(strings) != bytes:
strings = strings.encode('utf-8')
from cryptography.fernet import Fernet
f = Fernet(key)
result = f.encrypt(strings)
return result.decode('utf-8')
except:
# print(get_error_info())
return strings
def deCrypt(key, strings):
# 解密字符串
try:
if type(strings) != bytes:
strings = strings.decode('utf-8')
from cryptography.fernet import Fernet
f = Fernet(key)
result = f.decrypt(strings).decode('utf-8')
return result
except:
# print(get_error_info())
return strings
def buildSoftLink(src, dst, force=False):
'''
建立软连接
@@ -899,7 +927,7 @@ def setOwn(filename, user, group=None):
def checkPort(port):
# 检查端口是否合法
ports = ['21', '25', '443', '888']
ports = ['21', '443', '888']
if port in ports:
return False
intport = int(port)
+2 -2
View File
@@ -15,8 +15,8 @@ server
#PROXY-START
#ERROR-PAGE-START
error_page 404 /404.html;
error_page 502 /502.html;
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END
#PHP-INFO-START
+2 -2
View File
@@ -12,8 +12,8 @@ server
#SSL-END
#ERROR-PAGE-START
error_page 404 /404.html;
error_page 502 /502.html;
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END
#PHP-INFO-START
+1 -1
View File
@@ -11,7 +11,7 @@ Group=git
WorkingDirectory={$SERVER_PATH}/gitea
ExecStart={$SERVER_PATH}/gitea/gitea web
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
Environment=USER=git HOME=/home/git GITEA_WORK_DIR={$SERVER_PATH}/gitea
RemainAfterExit=yes
#AmbientCapabilities=CAP_NET_BIND_SERVICE
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
+18 -16
View File
@@ -16,15 +16,11 @@ fi
URL_DOWNLOAD=https://dl.gitea.io/
getOs(){
os=`uname`
if [ "Darwin" == "$os" ];then
echo 'darwin'
else
echo 'linux'
fi
return 0
}
bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
getBit(){
echo `getconf LONG_BIT`
@@ -32,26 +28,32 @@ getBit(){
Install_App()
{
{
mkdir -p $serverPath/source/gitea
if id git &> /dev/null ;then
echo "git UID is `id -u git`"
echo "git Shell is `grep "^git:" /etc/passwd |cut -d':' -f7 `"
echo "git uid is `id -u git`"
echo "git shell is `grep "^git:" /etc/passwd |cut -d':' -f7 `"
else
groupadd git
useradd -g git git
fi
if [ "macos" != "$OSNAME" ];then
if [ ! -d /home/git ];then
mkdir -p /home/git
chown -R git:git /home/git
fi
fi
echo '正在安装脚本文件...' > $install_tmp
version=$1
os=`getOs`
git config --global push.default simple
if [ "darwin" == "$os" ];then
if [ "macos" == "$OSNAME" ];then
file=gitea-${version}-darwin-10.12-amd64
else
file=gitea-${version}-linux-amd64
@@ -60,7 +62,7 @@ Install_App()
file_xz="${file}.xz"
echo "wget -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}"
if [ ! -f $serverPath/source/gitea/$file_xz ];then
wget -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}
wget --no-check-certificate -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}
fi
cd $serverPath/source/gitea && xz -k -d $file_xz
+1 -1
View File
@@ -53,7 +53,7 @@ Install_gogs()
fi
if [ ! -f $serverPath/source/gogs/$file ];then
wget -O $serverPath/source/gogs/$file ${GOGS_DOWNLOAD}/${version}/${file}
wget --no-check-certificate -O $serverPath/source/gogs/$file ${GOGS_DOWNLOAD}/${version}/${file}
fi
cd $serverPath/source/gogs && unzip -o $file -d gogs_${version}
+1 -1
View File
@@ -29,7 +29,7 @@ Install_App()
if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then
if [ $sysName == 'Darwin' ]; then
wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
wget --no-check-certificate -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
else
curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
fi
+2 -2
View File
@@ -4,8 +4,8 @@
"name": "imail",
"title": "邮件服务",
"shell": "install.sh",
"versions":["0.0.17"],
"updates":["0.0.17"],
"versions":["0.0.19"],
"updates":["0.0.19"],
"tip": "soft",
"checks": "server/imail",
"path": "server/imail",
@@ -8,7 +8,7 @@ rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=0.0.17
VERSION=0.0.19
# bash install.sh install 0.0.16
## cd /www/server/mdserver-web/plugins/imail && bash install.sh install 0.0.16
+1 -1
View File
@@ -18,7 +18,7 @@ Install_mem(){
echo '正在安装脚本文件...' > $install_tmp
if [ ! -f $serverPath/source/memcached.tar.gz ];then
wget -O $serverPath/source/memcached.tar.gz http://www.memcached.org/files/memcached-${VERSION}.tar.gz
wget --no-check-certificate -O $serverPath/source/memcached.tar.gz http://www.memcached.org/files/memcached-${VERSION}.tar.gz
fi
cd $serverPath/source && tar -zxvf memcached.tar.gz
+1 -1
View File
@@ -29,7 +29,7 @@ lower_case_table_names=0
character-set-server = UTF8MB4
query_cache_type = 1
query_cache_size = 8M
query_cache_size = 64M
max_connections = 500
max_connect_errors = 100
+1 -1
View File
@@ -43,7 +43,7 @@ APT_INSTALL()
mkdir -p $myDir
mkdir -p $serverPath/mysql-apt/bin
wget -O ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar https://cdn.mysql.com/archives/mysql-5.7/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
wget --no-check-certificate -O ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar https://cdn.mysql.com/archives/mysql-5.7/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
chmod +x ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
cd ${myDir} && tar vxf ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
+1 -1
View File
@@ -35,7 +35,7 @@ APT_INSTALL()
mkdir -p $myDir
mkdir -p $serverPath/mysql-apt/bin
wget -O ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar https://cdn.mysql.com/archives/mysql-8.0/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
wget --no-check-certificate -O ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar https://cdn.mysql.com/archives/mysql-8.0/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
chmod +x ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
cd ${myDir} && tar vxf ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
+1 -1
View File
@@ -30,7 +30,7 @@ tmp_table_size = 8M
character-set-server = UTF8MB4
query_cache_type = 1
query_cache_size = 8M
query_cache_size = 64M
max_connections = 500
max_connect_errors = 100
+1 -1
View File
@@ -52,7 +52,7 @@ YUM_INSTALL()
#######
mkdir -p $myDir
wget -O $myDir/mysql-${SUFFIX_NAME}.rpm-bundle.tar https://cdn.mysql.com/archives/mysql-5.7/mysql-${SUFFIX_NAME}.rpm-bundle.tar
wget --no-check-certificate -O $myDir/mysql-${SUFFIX_NAME}.rpm-bundle.tar https://cdn.mysql.com/archives/mysql-5.7/mysql-${SUFFIX_NAME}.rpm-bundle.tar
cd ${myDir} && tar vxf mysql-${SUFFIX_NAME}.rpm-bundle.tar
mkdir -p ${serverPath}/mysql-yum/bin && cd ${serverPath}/mysql-yum/bin
+1 -1
View File
@@ -48,7 +48,7 @@ YUM_INSTALL()
#######
mkdir -p $myDir
wget -O $myDir/mysql-${SUFFIX_NAME}.rpm-bundle.tar https://cdn.mysql.com/archives/mysql-8.0/mysql-${SUFFIX_NAME}.rpm-bundle.tar
wget --no-check-certificate -O $myDir/mysql-${SUFFIX_NAME}.rpm-bundle.tar https://cdn.mysql.com/archives/mysql-8.0/mysql-${SUFFIX_NAME}.rpm-bundle.tar
cd ${myDir} && tar vxf mysql-${SUFFIX_NAME}.rpm-bundle.tar
mkdir -p ${serverPath}/mysql-yum/bin && cd ${serverPath}/mysql-yum/bin
+1 -1
View File
@@ -33,7 +33,7 @@ tmp_table_size = 8M
query_cache_type = 1
query_cache_size = 4M
query_cache_size = 64M
max_connections = 500
max_connect_errors = 100
+1 -1
View File
@@ -35,7 +35,7 @@ lower_case_table_names=0
tmp_table_size = 8M
query_cache_type = 1
query_cache_size = 4M
query_cache_size = 64M
max_connections = 500
max_connect_errors = 100
+1 -1
View File
@@ -36,7 +36,7 @@ tmp_table_size = 8M
character-set-server = UTF8MB4
query_cache_type = 1
query_cache_size = 4M
query_cache_size = 64M
max_connections = 500
max_connect_errors = 100
+14 -9
View File
@@ -2233,7 +2233,7 @@ def initSlaveStatus(version=''):
ssh.connect(hostname=ip, port=int(master_port),
username='root', pkey=key)
cmd = 'cd /www/server/mdserver-web && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"","db":""}'
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"","db":""}'
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
result = result.decode('utf-8')
@@ -2254,11 +2254,11 @@ def initSlaveStatus(version=''):
# 保证同步IP一致
cmd = cmd_data['data']['cmd']
if cmd.find('SOURCE_HOST') > -1:
cmd = re.sub(r"SOURCE_HOST='(.*)'",
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
"SOURCE_HOST='" + ip + "'", cmd, 1)
if cmd.find('MASTER_HOST') > -1:
cmd = re.sub(r"MASTER_HOST='(.*)'",
cmd = re.sub(r"MASTER_HOST='(.*?)'",
"MASTER_HOST='" + ip + "'", cmd, 1)
db.query(cmd)
db.query("start slave user='{}' password='{}';".format(
@@ -2318,11 +2318,12 @@ def dumpMysqlData(version=''):
if args['db'].lower() == 'all':
dlist = findBinlogDoDb()
cmd = mysql_dir + "/bin/mysqldump --defaults-file=" + myconf + " " + option + " -uroot -p" + \
pwd + " --databases " + \
pwd + " --force --databases " + \
' '.join(dlist) + " | gzip > /tmp/dump.sql.gz"
else:
cmd = mysql_dir + "/bin/mysqldump --defaults-file=" + myconf + " " + option + " -uroot -p" + \
pwd + " --databases " + args['db'] + " | gzip > /tmp/dump.sql.gz"
pwd + " --force --databases " + \
args['db'] + " | gzip > /tmp/dump.sql.gz"
ret = mw.execShell(cmd)
if ret[0] == '':
@@ -2392,7 +2393,7 @@ def doFullSync(version=''):
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
dbname = args['db']
cmd = "cd /www/server/mdserver-web && python3 plugins/mysql/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
cmd = "cd /www/server/mdserver-web && source bin/activate && python3 plugins/mysql/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
print(cmd)
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
@@ -2415,7 +2416,7 @@ def doFullSync(version=''):
if copy_status == None:
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
cmd = 'cd /www/server/mdserver-web && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
result = result.decode('utf-8')
@@ -2427,10 +2428,12 @@ def doFullSync(version=''):
cmd = cmd_data['data']['cmd']
# 保证同步IP一致
if cmd.find('SOURCE_HOST') > -1:
cmd = re.sub(r"SOURCE_HOST='(.*)'", "SOURCE_HOST='" + ip + "'", cmd, 1)
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
"SOURCE_HOST='" + ip + "'", cmd, 1)
if cmd.find('MASTER_HOST') > -1:
cmd = re.sub(r"MASTER_HOST='(.*)'", "SOURCE_HOST='" + ip + "'", cmd, 1)
cmd = re.sub(r"MASTER_HOST='(.*?)'",
"MASTER_HOST='" + ip + "'", cmd, 1)
db.query(cmd)
uinfo = cmd_data['data']['info']
@@ -2444,6 +2447,8 @@ def doFullSync(version=''):
mw.execShell("cd /tmp && gzip -d dump.sql.gz")
cmd = root_dir + "/bin/mysql -S " + msock + \
" -uroot -p" + pwd + " < /tmp/dump.sql"
print(cmd)
import_data = mw.execShell(cmd)
if import_data[0] == '':
print(import_data[1])
+1 -1
View File
@@ -17,7 +17,7 @@ which rpcgen
if [ "$?" != "0" ];then
if [ ! -f ${SOURCE_ROOT}/rpcsvc-proto-1.4.tar.gz ];then
wget -O ${SOURCE_ROOT}/rpcsvc-proto-1.4.tar.gz https://github.com/thkukuk/rpcsvc-proto/releases/download/v1.4/rpcsvc-proto-1.4.tar.gz
wget --no-check-certificate -O ${SOURCE_ROOT}/rpcsvc-proto-1.4.tar.gz https://github.com/thkukuk/rpcsvc-proto/releases/download/v1.4/rpcsvc-proto-1.4.tar.gz
fi
if [ ! -d ${SERVER_ROOT}/rpcsvc-proto-1.4 ];then
+1 -1
View File
@@ -59,7 +59,7 @@ Install_mysql()
# ----- cpu end ------
if [ ! -f ${mysqlDir}/mysql-5.5.62.tar.gz ];then
wget -O ${mysqlDir}/mysql-5.5.62.tar.gz --tries=3 https://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.62.tar.gz
wget --no-check-certificate -O ${mysqlDir}/mysql-5.5.62.tar.gz --tries=3 https://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.62.tar.gz
fi
if [ ! -d ${mysqlDir}/mysql-5.5.62 ];then
+1 -1
View File
@@ -63,7 +63,7 @@ Install_mysql()
if [ ! -f ${mysqlDir}/mysql-5.6.50.tar.gz ];then
wget -O ${mysqlDir}/mysql-5.6.50.tar.gz --tries=3 https://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.50.tar.gz
wget --no-check-certificate -O ${mysqlDir}/mysql-5.6.50.tar.gz --tries=3 https://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.50.tar.gz
fi
if [ ! -d ${mysqlDir}/mysql-5.6.50 ];then
+2 -2
View File
@@ -66,7 +66,7 @@ Install_mysql()
cd ${rootPath}/plugins/mysql/lib && /bin/bash rpcgen.sh
if [ ! -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
fi
#检测文件是否损坏.
@@ -78,7 +78,7 @@ Install_mysql()
else
# 重新下载
rm -rf ${mysqlDir}/mysql-${VERSION}
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
fi
fi
+3 -3
View File
@@ -109,7 +109,7 @@ Install_mysql()
fi
if [ ! -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
fi
#检测文件是否损坏.
@@ -121,7 +121,7 @@ Install_mysql()
else
# 重新下载
rm -rf ${mysqlDir}/mysql-${VERSION}
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
fi
fi
@@ -163,7 +163,7 @@ Install_mysql()
LIBTIRPC_VER=`pkg-config libtirpc --modversion`
if [ ! -f ${mysqlDir}/libtirpc_1.2.5.orig.tar.bz2 ];then
wget -O ${mysqlDir}/libtirpc_1.2.5.orig.tar.bz2 https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/libtirpc/1.2.5-1ubuntu0.1/libtirpc_1.2.5.orig.tar.bz2
wget --no-check-certificate -O ${mysqlDir}/libtirpc_1.2.5.orig.tar.bz2 https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/libtirpc/1.2.5-1ubuntu0.1/libtirpc_1.2.5.orig.tar.bz2
cd ${mysqlDir} && tar -jxvf libtirpc_1.2.5.orig.tar.bz2
cd libtirpc-1.2.5 && ./configure
fi
+1 -1
View File
@@ -842,7 +842,7 @@ def setSafeVerify():
cobj = json.loads(content)
cobj['safe_verify']['time'] = args['time']
cobj['safe_verify']['cpu'] = args['cpu']
cobj['safe_verify']['cpu'] = int(args['cpu'])
if args['auto'] == '0':
cobj['safe_verify']['auto'] = False
+1 -1
View File
@@ -300,7 +300,7 @@ def runInfo():
# 取Openresty负载状态
try:
url = 'http://127.0.0.1/nginx_status'
result = mw.httpGet(url)
result = mw.httpGet(url, timeout=1)
tmp = result.split()
data = {}
data['active'] = tmp[2]
+1
View File
@@ -63,6 +63,7 @@ if [ "${action}" == "install" ] && [ -d ${serverPath}/php/${type} ];then
cd ${rootPath}/plugins/php/versions/common && bash intl.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash mcrypt.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash openssl.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash bcmath.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash gettext.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash redis.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash memcached.sh install ${type}
+1
View File
@@ -56,6 +56,7 @@ fi
ZIP_OPTION='--enable-zip'
libzip_version=`pkg-config libzip --modversion`
if version_lt "$libzip_version" "0.11.0" ;then
cd ${rootPath}/plugins/php/lib && /bin/bash libzip.sh
export PKG_CONFIG_PATH=$serverPath/lib/libzip/lib/pkgconfig
ZIP_OPTION="--with-libzip=$serverPath/lib/libzip"
fi
+1
View File
@@ -72,6 +72,7 @@ echo "$sourcePath/php/php${PHP_VER}"
ZIP_OPTION='--with-zip'
libzip_version=`pkg-config libzip --modversion`
if version_lt "$libzip_version" "0.11.0" ;then
cd ${rootPath}/plugins/php/lib && /bin/bash libzip.sh
export PKG_CONFIG_PATH=$serverPath/lib/libzip/lib/pkgconfig
ZIP_OPTION="--with-zip=$serverPath/lib/libzip"
fi
+6 -1
View File
@@ -19,12 +19,17 @@ sysName=`uname`
actionType=$1
version=$2
IC_VERSION=${version:0:1}.${version:1:2}
ARCH=`uname -m`
if [ "$version" -gt "74" ];then
echo "not need"
exit 1
fi
DEFAULT_ARCH='x86-64'
if [ "$ARCH" == "aarch64" ];then
DEFAULT_ARCH='aarch64'
fi
LIB_PATH_NAME=lib/php
if [ -d $serverPath/php/${version}/lib64 ];then
@@ -55,7 +60,7 @@ Install_lib()
php_lib=$sourcePath/php_lib
mkdir -p $php_lib
if [ ! -f $php_lib/ioncube_loaders_lin.tar.gz ];then
wget -O $php_lib/ioncube_loaders_lin.tar.gz https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
wget -O $php_lib/ioncube_loaders_lin.tar.gz https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_${DEFAULT_ARCH}.tar.gz
cd $php_lib && tar -zxvf ioncube_loaders_lin.tar.gz
fi
cd $php_lib/ioncube
+18 -12
View File
@@ -381,9 +381,9 @@ def addRec():
args_ps = args['ps']
if not mw.isAppleSystem():
mw.execShell("mkdir -p " + args_path)
mw.execShell("chown -R www:www " + args_path)
mw.execShell("chmdo -R 755 " + args_path)
os.system("mkdir -p " + args_path + " &")
os.system("chown -R www:www " + args_path + " &")
os.system("chmod -R 755 " + args_path + " &")
delRecBy(args_name)
@@ -710,8 +710,7 @@ def lsyncdAdd():
import base64
args = getArgs()
data = checkArgs(args, ['ip', 'conn_type', 'path',
'secret_key', 'delay', 'period'])
data = checkArgs(args, ['ip', 'conn_type', 'path', 'delay', 'period'])
if not data[0]:
return data[1]
@@ -719,12 +718,12 @@ def lsyncdAdd():
path = args['path']
if not mw.isAppleSystem():
mw.execShell("mkdir -p " + path)
mw.execShell("chown -R www:www " + path)
mw.execShell("chmod -R 755 " + path)
os.system("mkdir -p " + path + " &")
os.system("chown -R www:www " + path + " &")
os.system("chmod -R 755 " + path + " &")
conn_type = args['conn_type']
secret_key = args['secret_key']
delete = args['delete']
realtime = args['realtime']
delay = args['delay']
@@ -750,6 +749,12 @@ def lsyncdAdd():
}
if conn_type == "key":
secret_key_check = checkArgs(args, ['secret_key'])
if not secret_key_check[0]:
return secret_key_check[1]
secret_key = args['secret_key']
try:
m = base64.b64decode(secret_key)
m = json.loads(m)
@@ -759,12 +764,13 @@ def lsyncdAdd():
except Exception as e:
return mw.returnJson(False, "接收密钥格式错误!")
else:
data = checkArgs(args, ['uname'])
data = checkArgs(args, ['sname', 'password'])
if not data[0]:
return data[1]
info['name'] = args['uname']
info['password'] = args['uname']
info['name'] = args['sname']
info['password'] = args['password']
info['port'] = args['port']
rsync = {
'bwlimit': bwlimit,
+1 -1
View File
@@ -324,7 +324,7 @@ def startJob():
data = mw.execShell(cmd)
if data[0] != '':
if data[1] != '':
return mw.returnJson(False, action + '[' + name + ']失败!')
return mw.returnJson(True, action + '[' + name + ']成功!')
+4 -1
View File
@@ -32,4 +32,7 @@ net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000
vm.overcommit_memory=1
vm.overcommit_memory=1
net.ipv4.ip_conntrack_max = 81920
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1500
+1 -1
View File
@@ -207,7 +207,7 @@
</div>
</div>
<script type="text/javascript">
resetPluginWinWidth(900);
resetPluginWinWidth(950);
$.getScript( "/static/js/echarts.min.js", function(){
console.log("echarts load done");
});
+17
View File
@@ -95,6 +95,22 @@ def loadConfigFile():
content = mw.readFile(conf_tpl)
content = json.loads(content)
dst_conf_json = getServerDir() + "/lua/config.json"
if not os.path.exists(dst_conf_json):
mw.writeFile(dst_conf_json, json.dumps(content))
dst_conf_lua = getServerDir() + "/lua/webstats_config.lua"
if not os.path.exists(dst_conf_lua):
listToLuaFile(dst_conf_lua, content)
def loadConfigFileReload():
lua_dir = getServerDir() + "/lua"
conf_tpl = getPluginDir() + "/conf/config.json"
content = mw.readFile(conf_tpl)
content = json.loads(content)
dst_conf_json = getServerDir() + "/lua/config.json"
mw.writeFile(dst_conf_json, json.dumps(content))
@@ -262,6 +278,7 @@ def restart():
def reload():
initDreplace()
loadConfigFileReload()
loadDebugLogFile()
mw.opWeb("reload")
+42 -4
View File
@@ -2232,7 +2232,12 @@ function wsTableLogRequest(page){
list += '<td>' + toSecond(data[i]['request_time']) +'</td>';
list += '<td><span class="overflow_hide" style="width:130px;">' + data[i]['uri'] +'</span></td>';
list += '<td>'+spider_tip+'<span class="overflow_hide" style="width:60px;">' + data[i]['status_code']+'/' + data[i]['method'] +'</span></td>';
list += '<td><a data-id="'+i+'" href="javascript:;" class="btlink details" title="详情">详情</a></td>';
var http_data = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
if (data[i]['request_headers']!=''){
http_data = '<a data-id="'+i+'" href="javascript:;" class="btlink http_data" title="HTTP">HTTP</a>&nbsp;|&nbsp;';
}
list += '<td><span>'+http_data+'<a data-id="'+i+'" href="javascript:;" class="btlink details" title="详情">详情</a></span></td>';
list += '</tr>';
}
} else{
@@ -2277,19 +2282,52 @@ function wsTableLogRequest(page){
<div><b style="margin-left:10px">协议</b></div>\
<div class="lib-con mt10"><div class="divpre">' + res.protocol + '</div></div>\
<div><b style="margin-left:10px">URL</b></div>\
<div class="lib-con mt10"><div class="divpre">' + $('<div ></div>').text(res.uri).html() + '</div></div>\
<div class="lib-con mt10"><div class="divpre">' + $('<div></div>').text(res.uri).html() + '</div></div>\
<div><b style="margin-left:10px">完整IP列表</b></div>\
<div class="lib-con mt10"><div class="divpre" style="max-height: 66px;">' + $('<div ></div>').text(res.ip_list).html() + '</div></div>\
<div><b style="margin-left:10px">来路</b></div>\
<div class="lib-con mt10"><div class="divpre">' + $('<div ></div>').text(res.referer == null ?'None':res.referer).html() + '</div></div>\
<div class="lib-con mt10"><div class="divpre">' + $('<div></div>').text(res.referer == null ?'None':res.referer).html() + '</div></div>\
<div><b style="margin-left:10px">User-Agent</b></div>\
<div class="lib-con mt10"><div class="divpre">' + $('<div ></div>').text(res.user_agent).html() + '</div></div>\
<div class="lib-con mt10"><div class="divpre">' + $('<div></div>').text(res.user_agent).html() + '</div></div>\
<div><b style="margin-left:10px">处理耗时</b></div>\
<div class="lib-con mt10"><div class="divpre">' +res.request_time + ' ms</div></div>\
</div>',
});
});
$(".tablescroll .http_data").click(function(){
var index = $(this).attr('data-id');
var res = data[index];
var request_headers = res.request_headers;
var req_data = $.parseJSON(request_headers);
var req_data_html = res.method +' ' + res.uri + '<br/>';
for (var d in req_data) {
if (d == 'payload'){
req_data_html += '<b style="color:red;">'+d +"</b>:"+req_data[d]+"<br/>";
} else{
req_data_html += d+":"+req_data[d]+"<br/>";
}
}
layer.open({
type: 1,
title: "【"+res.domain + "】HTTP详情",
area: ['600px','375px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="pd15 lib-box">\
<div class="lib-con mt10"><div class="divpre" style="max-height:250px;white-space: break-spaces;">' + req_data_html + '</div></div>\
<ul class="help-info-text c7 mtb15">\
<li style="list-style: none;">payload: POST请求中客户端提交的参数。</li>\
</ul>\
</div>',
});
});
$('[data-toggle="tooltip"]').tooltip();
});
}
+4
View File
@@ -76,6 +76,10 @@ function _M.getTotalKey(self)
return self.total_key
end
function _M.to_json(self, msg)
return json.encode(msg)
end
function _M.setConfData( self, config, site_config )
self.config = config
self.site_config = site_config
+1 -2
View File
@@ -373,8 +373,7 @@ log_by_lua_block {
local client_stat_fields = {}
if not excluded then
if status_code == 500 or (method=="POST" and config["record_post_args"] == true) or (status_code==403 and config["record_get_403_args"] == true) then
if status_code == 500 or (method=="POST" and config['global']["record_post_args"] == true) or (status_code==403 and config['global']["record_get_403_args"] == true) then
local data = ""
local ok, err = pcall(function() data = C:get_http_origin() end)
if ok and not err then
+5
View File
@@ -0,0 +1,5 @@
location ~/group([0-9])/M00 {
# Need to cooperate with it
# https://github.com/mw-plugin/fastdfs
ngx_fastdfs_module;
}
+3 -3
View File
@@ -1,4 +1,4 @@
location / {
rewrite ^(.*)-htm-(.*)$ $1.php?$2 last;
rewrite ^(.*)/simple/([a-z0-9\_]+\.html)$ $1/simple/index.php?$2 last;
}
rewrite ^(.*)-htm-(.*)$ $1.php?$2 last;
rewrite ^(.*)/simple/([a-z0-9\_]+\.html)$ $1/simple/index.php?$2 last;
}
+48 -4
View File
@@ -133,8 +133,6 @@ def funConvert(fun):
func += suf
return func
# Flask请求勾子
def sendAuthenticated():
# 发送http认证信息
@@ -148,6 +146,7 @@ def sendAuthenticated():
@app.before_request
def requestCheck():
# Flask请求勾子
if app.config['BASIC_AUTH_OPEN']:
auth = request.authorization
if request.path in ['/download', '/hook', '/down']:
@@ -407,6 +406,51 @@ def login_temp_user(token):
return redirect('/')
@app.route('/api/<reqClass>/<reqAction>', methods=['POST', 'GET'])
def api(reqClass=None, reqAction=None, reqData=None):
comReturn = common.local()
if comReturn:
return comReturn
import config_api
isOk, data = config_api.config_api().checkPanelToken()
if not isOk:
return mw.returnJson(False, '未开启API')
request_time = request.form.get('request_time', '')
request_token = request.form.get('request_token', '')
request_ip = request.remote_addr
token_md5 = mw.md5(str(request_time) + mw.md5(data['token_crypt']))
if not (token_md5 == request_token):
return mw.returnJson(False, '密钥错误')
if not mw.inArray(data['limit_addr'], request_ip):
return mw.returnJson(False, '非法请求')
if reqClass == None:
return mw.returnJson(False, '请指定请求方法类')
if reqAction == None:
return mw.returnJson(False, '请指定请求方法')
classFile = ('config_api', 'crontab_api', 'files_api', 'firewall_api',
'plugins_api', 'system_api', 'site_api', 'task_api')
className = reqClass + '_api'
if not className in classFile:
return "external api request error"
eval_str = "__import__('" + className + "')." + className + '()'
newInstance = eval(eval_str)
try:
return publicObject(newInstance, reqAction)
except Exception as e:
return mw.getTracebackInfo()
@app.route('/<reqClass>/<reqAction>', methods=['POST', 'GET'])
@app.route('/<reqClass>/', methods=['POST', 'GET'])
@app.route('/<reqClass>', methods=['POST', 'GET'])
@@ -462,14 +506,14 @@ def index(reqClass=None, reqAction=None, reqData=None):
return render_template(reqClass + '.html', data=data)
if not isLogined():
return 'request error!'
return 'error request!'
# API请求
classFile = ('config_api', 'crontab_api', 'files_api', 'firewall_api',
'plugins_api', 'system_api', 'site_api', 'task_api')
className = reqClass + '_api'
if not className in classFile:
return "api request error"
return "api error request"
eval_str = "__import__('" + className + "')." + className + '()'
newInstance = eval(eval_str)
+72 -2
View File
@@ -57,8 +57,8 @@ $('input[name="sites_path"]').change(function(){
$('input[name="backup_path"]').change(function(){
var backup_path = $(this).val();
$('.backup_path').removeAttr('disabled');
$('.btn_sites_path').unbind().click(function(){
$('.btn_backup_path').removeAttr('disabled');
$('.btn_backup_path').unbind().click(function(){
$.post('/config/set_backup_dir','backup_path='+backup_path, function(rdata){
showMsg(rdata.msg,function(){window.location.reload();},{icon:rdata.status?1:2},2000);
},'json');
@@ -665,3 +665,73 @@ function setBasicAuth(){
}
}
function showPanelApi(){
$.post('/config/get_panel_token', '', function(rdata){
var tip = layer.open({
area: ['500px', '355px'],
title: '配置面板API',
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="token" type="text" style="width: 310px;" disabled>\
<button class="btn btn-success btn-xs reset_token" style="margin-left: -50px;">重置</button>\
</div>\
</div>\
<div class="line">\
<span class="tname" style="width: 90px; overflow: initial; height: 20px; line-height: 20px;">IP白名单<br/>(每行1个)</span>\
<div class="info-r"><textarea class="bt-input-text" name="api_limit_addr" style="width: 310px; height: 80px; line-height: 20px; padding: 5px 8px;"></textarea></div>\
</div>\
<div class="line">\
<span class="tname"></span>\
<div class="info-r"><button class="btn btn-success btn-sm save_api">保存配置</button></div>\
</div>\
<ul class="help-info-text c7">\
<li>开启API后,必需在IP白名单列表中的IP才能访问面板API接口</li>\
<li style="color: red;">请不要在生产环境开启,这可能增加服务器安全风险;</li>\
</ul>\
</div>',
success:function(layero,index){
$('input[name="token"]').val(rdata.data.token);
$('textarea[name="api_limit_addr"]').val(rdata.data.limit_addr);
$('.reset_token').click(function(){
layer.confirm('您确定要重置当前密钥吗?<br/><span style="color: red; ">重置密钥后,已关联密钥产品,将失效,请重新添加新密钥至产品。</span>',{title:'重置密钥',closeBtn:2,icon:13,cancel:function(){
}}, function() {
$.post('/config/set_panel_token', {'op_type':"1"},function(rdata){
showMsg("接口密钥已生成,重置密钥后,已关联密钥产品,将失效,请重新添加新密钥至产品。", function(){
$('input[name="token"]').val(rdata.data);
} ,{icon:1}, 2000);
},'json');
});
});
$('.save_api').click(function(){
var limit_addr = $('textarea[name="api_limit_addr"]').val();
$.post('/config/set_panel_token', {'op_type':"3",'limit_addr':limit_addr},function(rdata){
showMsg(rdata.msg, function(){
} ,{icon:rdata.status?1:2}, 2000);
},'json');
});
},
});
},'json');
}
function setPanelApi(){
var cfg_panel_api = $('#cfg_panel_api').prop("checked");
$.post('/config/set_panel_token', {'op_type':"2"},function(rdata){
showMsg(rdata.msg, function(){
if (rdata.status){
showPanelApi();
}
} ,{icon:rdata.status?1:2}, 1000);
},'json');
}
+1 -1
View File
@@ -6,7 +6,7 @@
</head>
<body>
<h1>开启命令</h1>
<p>{{data['cmd']}}</p>
<p>mw open</p>
<hr>
<!-- <address>Linux面板<a href="" target="_blank">请求帮助</a></address> -->
</body>
+8
View File
@@ -138,6 +138,14 @@
<span class="set-info c7">为面板增加一道基于BasicAuth的认证服务,有效防止面板被扫描</span>
</p>
<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']}}/>
<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>
</p>
<p class="mtb15">
<span class="set-tit text-right" title="临时访问授权">临时访问授权</span>
<button type="button" class="btn btn-success btn-sm ml5" onclick="setTempAccess()">临时访问授权管理</button>
+1 -1
View File
@@ -91,7 +91,7 @@ function showAd(){
<table class="table table-hover">\
<thead><tr><td style="text-align: center;">商家</td><td style="text-align: center;">优惠码</td><tr></thead>\
<tbody>\
<tr><td><a target="_blank" href="https://digitalvirt.com/aff.php?aff=154"><img src="https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg"/></a></td><td>9SYDY7UH0U</td></tr>\
<tr><td><a target="_blank" href="https://digitalvirt.com/aff.php?aff=154"><img src="https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg"/></a></td><td>mdserver-web</td></tr>\
</tbody>\
</table>\
</div>'
+6 -3
View File
@@ -36,7 +36,7 @@ class backupTools:
"----------------------------------------------------------------------------")
return
backup_path = mw.getRootDir() + '/backup/site'
backup_path = mw.getBackupDir() + '/site'
if not os.path.exists(backup_path):
mw.execShell("mkdir -p " + backup_path)
@@ -97,7 +97,7 @@ class backupTools:
"----------------------------------------------------------------------------")
return
backup_path = mw.getRootDir() + '/backup/database'
backup_path = mw.getBackupDir() + '/database'
if not os.path.exists(backup_path):
mw.execShell("mkdir -p " + backup_path)
@@ -122,7 +122,10 @@ class backupTools:
# mw.execShell(db_path + "/bin/mysqldump --skip-lock-tables --default-character-set=utf8 " +
# name + " | gzip > " + filename)
mw.execShell(db_path + "/bin/mysqldump --single-transaction --quick --default-character-set=utf8 " +
# mw.execShell(db_path + "/bin/mysqldump --single-transaction --quick --default-character-set=utf8 " +
# name + " | gzip > " + filename)
mw.execShell(db_path + "/bin/mysqldump --force --opt --default-character-set=utf8 " +
name + " | gzip > " + filename)
if not os.path.exists(filename):
+14 -1
View File
@@ -171,6 +171,17 @@ mw_reload()
fi
}
mw_close(){
echo 'True' > $mw_path/data/close.pl
}
mw_open()
{
if [ -f $mw_path/data/close.pl ];then
rm -rf $mw_path/data/close.pl
fi
}
error_logs()
{
tail -n 100 $mw_path/logs/error.log
@@ -254,6 +265,8 @@ case "$1" in
mw_start_task;;
'status') mw_status;;
'logs') error_logs;;
'close') mw_close;;
'open') mw_open;;
'update') mw_update;;
'update_dev') mw_update_dev;;
'install_app') mw_install_app;;
@@ -292,9 +305,9 @@ case "$1" in
if [ ! -f $mw_path/data/ipv6.pl ];then
# Need to restart ipv6 to take effect
echo 'True' > $mw_path/data/ipv6.pl
mw_stop
mw_start
echo 'True' > $mw_path/data/ipv6.pl
fi
address="MW-Panel-Url: http://[$v6]:$port$auth_path"
else
+15 -10
View File
@@ -15,7 +15,6 @@ sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
yum install -y wget lsof
yum install -y python3-devel
yum install -y python-devel
yum install -y crontabs
yum install -y expect
yum install -y curl curl-devel libcurl libcurl-devel
@@ -71,26 +70,32 @@ systemctl stop firewalld
yum groupinstall -y "Development Tools"
yum install -y epel-release
yum install -y libevent libevent-devel unzip libmcrypt libmcrypt-devel
yum install -y wget python-imaging libicu-devel zip bzip2-devel gcc libxml2 libxml2-dev libpng-devel libwebp libwebp-devel pcre pcre-devel
yum install -y lsof net-tools
yum install -y ncurses-devel mysql-devel cmake
yum install -y libevent libevent-devel zip unzip libmcrypt libmcrypt-devel
yum install -y wget libicu-devel readline-devel zip bzip2 bzip2-devel libxml2 libxml2-devel
yum install -y libpng libpng-devel libwebp libwebp-devel pcre pcre-devel gd gd-devel zlib zlib-devel gettext gettext-devel
yum install -y net-tools
yum install -y ncurses ncurses-devel mysql-devel make cmake
yum install -y sqlite-devel
# python-imaging
# yum install -y MySQL-python
for yumPack in make cmake gcc gcc-c++ flex bison file libtool libtool-libs autoconf kernel-devel patch wget libpng libpng-devel gd gd-devel libxml2 libxml2-devel zlib zlib-devel glib2 glib2-devel tar bzip2 bzip2-devel libevent libevent-devel ncurses ncurses-devel curl curl-devel libcurl libcurl-devel e2fsprogs e2fsprogs-devel libidn libidn-devel vim-minimal gettext gettext-devel ncurses-devel gmp-devel libcap diffutils ca-certificates net-tools libc-client-devel psmisc libXpm-devel git-core c-ares-devel libicu-devel libxslt libxslt-devel zip unzip glibc.i686 libstdc++.so.6 cairo-devel bison-devel ncurses-devel libaio-devel perl perl-devel perl-Data-Dumper lsof crontabs expat-devel readline-devel;
yum install -y perl perl-devel perl-Data-Dumper
for yumPack in gcc gcc-c++ flex file libtool libtool-libs autoconf kernel-devel patch glib2 glib2-devel tar e2fsprogs e2fsprogs-devel libidn libidn-devel vim-minimal gmp-devel libcap diffutils ca-certificates libc-client-devel psmisc libXpm-devel c-ares-devel libxslt libxslt-devel glibc.i686 libstdc++.so.6 cairo-devel libaio-devel expat-devel;
do dnf --enablerepo=powertools install -y $yumPack;done
yum install -y libtirpc libtirpc-devel
dnf install boost-locale
dnf --enablerepo=powertools install -y boost-locale
dnf --enablerepo=powertools install -y libmemcached libmemcached-devel
dnf --enablerepo=powertools install -y rpcgen
dnf --enablerepo=powertools install -y oniguruma oniguruma-devel
dnf --enablerepo=powertools install -y re2c bison
dnf --enablerepo=powertools install -y re2c bison bison-devel
dnf install -y libjpeg-turbo libjpeg-turbo-devel
cd /www/server/mdserver-web/scripts && bash lib.sh
chmod 755 /www/server/mdserver-web/data
echo "rocky ok"
-1
View File
@@ -73,7 +73,6 @@ fi
echo "use system version: ${OSNAME}"
cd /www/server/mdserver-web && bash scripts/install/${OSNAME}.sh
cd /www/server/mdserver-web && bash cli.sh start
isStart=`ps -ef|grep 'gunicorn -c setting.py app:app' |grep -v grep|awk '{print $2}'`
n=0
+5 -2
View File
@@ -33,6 +33,8 @@ elif [ "$OSNAME" == "freebsd" ];then
echo "freebsd lib"
elif [ "$OSNAME" == "centos" ];then
echo "centos lib"
elif [ "$OSNAME" == "rocky" ]; then
echo "rocky lib"
elif [ "$OSNAME" == "fedora" ];then
echo "fedora lib"
elif [ "$OSNAME" == "alma" ];then
@@ -52,7 +54,7 @@ if [ ! -f /usr/local/bin/pip3 ];then
python3 -m pip install --upgrade pip setuptools wheel -i https://pypi.python.org/pypi
fi
pip install --upgrade pip
which pip && pip install --upgrade pip
pip3 install --upgrade setuptools
cd /www/server/mdserver-web && pip3 install -r /www/server/mdserver-web/requirements.txt
@@ -69,8 +71,9 @@ fi
pip install --upgrade pip
pip3 install --upgrade setuptools
pip3 install -r /www/server/mdserver-web/requirements.txt
cd /www/server/mdserver-web && pip3 install -r /www/server/mdserver-web/requirements.txt
echo "lib ok!"
# pip3 install flask-caching==1.10.1
# pip3 install mysqlclient
+94
View File
@@ -0,0 +1,94 @@
<?php
/**
* MW API接口示例Demo
* 仅供参考,请根据实际项目需求开发,并做好安全处理
* date 2022-11-28
* author midoks
*/
class mwApi {
private $MW_KEY = "j7GQhzNcBV4KU9QKYPXvtjSzCcmfkc0e"; //接口密钥
private $MW_PANEL = "http://127.0.0.1:7200"; //面板地址
//如果希望多台面板,可以在实例化对象时,将面板地址与密钥传入
public function __construct($mw_panel = null, $mw_key = null) {
if ($mw_panel) {
$this->MW_PANEL = $mw_panel;
}
if ($mw_key) {
$this->MW_KEY = $mw_key;
}
}
/**
* 发起POST请求
* @param String $url 目标网填,带http://
* @param Array|String $data 欲提交的数据
* @return string
*/
private function httpPostCookie($url, $data, $timeout = 60) {
//定义cookie保存位置
$cookie_file = './' . md5($this->MW_PANEL) . '.cookie';
if (!file_exists($cookie_file)) {
$fp = fopen($cookie_file, 'w+');
fclose($fp);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
/**
* 构造带有签名的关联数组
*/
private function getKeyData() {
$now_time = time();
$ready_data = array(
'request_token' => md5($now_time . '' . md5($this->MW_KEY)),
'request_time' => $now_time,
);
return $ready_data;
}
//示例取面板日志
public function getLogsList() {
//拼接URL地址
$url = $this->MW_PANEL . '/api/firewall/get_log_list';
//准备POST数据
$post_data = $this->getKeyData(); //取签名
$post_data['p'] = '1';
$post_data['limit'] = 10;
//请求面板接口
$result = $this->httpPostCookie($url, $post_data);
//解析JSON数据
$data = json_decode($result, true);
return $data;
}
}
//实例化对象
$api = new mwApi();
//获取面板日志
$rdata = $api->getLogsList();
// var_dump($rdata);
//输出JSON数据到浏览器
echo json_encode($rdata);
?>
+122
View File
@@ -0,0 +1,122 @@
# coding: utf-8
# +-----------------------------------------------------------------------------------
# | MW Linux面板
# +-----------------------------------------------------------------------------------
# | Copyright (c) 2015-2099 MW(http://github.com/midoks/mdserver) All rights reserved.
# +-----------------------------------------------------------------------------------
# | Author: midoks
# +-----------------------------------------------------------------------------------
#------------------------------
# API-Demo of Python
#------------------------------
import time
import hashlib
import sys
import os
import json
class mwApi:
__MW_KEY = 'j7GQhzNcBV4KU9QKYPXvtjSzCcmfkc0e'
__MW_PANEL = 'http://127.0.0.1:7200'
# 如果希望多台面板,可以在实例化对象时,将面板地址与密钥传入
def __init__(self, mw_panel=None, mw_key=None):
if mw_panel:
self.__MW_PANEL = mw_panel
self.__MW_KEY = mw_key
# 计算MD5
def __get_md5(self, s):
m = hashlib.md5()
m.update(s.encode('utf-8'))
return m.hexdigest()
# 构造带有签名的关联数组
def __get_key_data(self):
now_time = int(time.time())
ready_data = {
'request_token': self.__get_md5(str(now_time) + '' + self.__get_md5(self.__MW_KEY)),
'request_time': now_time
}
return ready_data
# 发送POST请求并保存Cookie
#@url 被请求的URL地址(必需)
#@data POST参数,可以是字符串或字典(必需)
#@timeout 超时时间默认1800秒
# return string
def __http_post_cookie(self, url, p_data, timeout=1800):
cookie_file = './' + self.__get_md5(self.__MW_PANEL) + '.cookie'
if sys.version_info[0] == 2:
# Python2
import urllib
import urllib2
import ssl
import cookielib
# 创建cookie对象
cookie_obj = cookielib.MozillaCookieJar(cookie_file)
# 加载已保存的cookie
if os.path.exists(cookie_file):
cookie_obj.load(cookie_file, ignore_discard=True,
ignore_expires=True)
ssl._create_default_https_context = ssl._create_unverified_context
data = urllib.urlencode(p_data)
req = urllib2.Request(url, data)
opener = urllib2.build_opener(
urllib2.HTTPCookieProcessor(cookie_obj))
response = opener.open(req, timeout=timeout)
# 保存cookie
cookie_obj.save(ignore_discard=True, ignore_expires=True)
return response.read()
else:
# Python3
import urllib.request
import ssl
import http.cookiejar
cookie_obj = http.cookiejar.MozillaCookieJar(cookie_file)
cookie_obj.load(cookie_file, ignore_discard=True,
ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie_obj)
data = urllib.parse.urlencode(p_data).encode('utf-8')
req = urllib.request.Request(url, data)
opener = urllib.request.build_opener(handler)
response = opener.open(req, timeout=timeout)
cookie_obj.save(ignore_discard=True, ignore_expires=True)
result = response.read()
if type(result) == bytes:
result = result.decode('utf-8')
return result
# 取面板日志
def getLogs(self):
# 拼接URL地址
url = self.__MW_PANEL + '/api/firewall/get_log_list'
# 准备POST数据
post_data = self.__get_key_data() # 取签名
post_data['limit'] = 10
post_data['p'] = '1'
# 请求面板接口
result = self.__http_post_cookie(url, post_data)
# 解析JSON数据
return json.loads(result)
if __name__ == '__main__':
# 实例化宝塔API对象
api = mwApi()
# 调用get_logs方法
rdata = api.getLogs()
# 打印响应数据
print(rdata)