mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 09:49:25 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da2d0fd2ce | ||
|
|
6e0d580f6b | ||
|
|
34481c12e1 | ||
|
|
bc27feab00 | ||
|
|
1e48b32170 | ||
|
|
b9cbf63945 | ||
|
|
8437e236db | ||
|
|
838043a9dd | ||
|
|
8debe50f1b | ||
|
|
8a97577b61 | ||
|
|
cb9b6b2816 | ||
|
|
92d5126230 | ||
|
|
50c6f9fce5 | ||
|
|
cbb1403f80 | ||
|
|
21f995f8ac | ||
|
|
185e0dae22 | ||
|
|
e555829f1b | ||
|
|
2f50a2ffa0 | ||
|
|
069ececfe1 | ||
|
|
1ea1ad5ae0 | ||
|
|
3787913a12 | ||
|
|
45f51954f9 | ||
|
|
0c7773c6d4 | ||
|
|
81e1940b8f | ||
|
|
2e24a715ba | ||
|
|
a05be24ed1 | ||
|
|
f09017fe6e | ||
|
|
1aedb66132 | ||
|
|
2e3aef3776 | ||
|
|
0d3cf64e9a | ||
|
|
66220c1963 | ||
|
|
1ed52a1033 | ||
|
|
1a4ac13f8b | ||
|
|
e2e94015a0 | ||
|
|
dee7abc850 | ||
|
|
a1464006db | ||
|
|
b4c6bcec6e | ||
|
|
1d55ef3d0a | ||
|
|
24dab4775c | ||
|
|
7a7b77887c | ||
|
|
c39d21b300 | ||
|
|
3f7bce197f | ||
|
|
e706ff17c1 | ||
|
|
5a80422b77 | ||
|
|
d3fb392f28 | ||
|
|
6817043007 | ||
|
|
3106c101d8 | ||
|
|
e25c7f424d | ||
|
|
156459b6a4 | ||
|
|
c73fe892b7 | ||
|
|
491ad84103 | ||
|
|
cdb27c5d83 | ||
|
|
7d35f9d129 | ||
|
|
b34d1e7caa | ||
|
|
055a52da03 | ||
|
|
2c3746c596 | ||
|
|
96a0ca9b2f | ||
|
|
1cd436bc5d | ||
|
|
3834a9b0b8 | ||
|
|
30454e3b4a | ||
|
|
020354f5bc | ||
|
|
6e5dbeda72 | ||
|
|
804922a707 | ||
|
|
23081f4487 | ||
|
|
2f75f57365 | ||
|
|
f4f7ffe5dd | ||
|
|
0de23a3914 | ||
|
|
d1f47ca406 | ||
|
|
8d16fe1d46 | ||
|
|
d1bffd74ae | ||
|
|
23de77d951 | ||
|
|
172fe65df4 | ||
|
|
4cd96252f1 | ||
|
|
a88f4c35bd | ||
|
|
19ffeb7e8e | ||
|
|
004e1ce03c | ||
|
|
485efb0c88 | ||
|
|
227107719b | ||
|
|
d683f18bd0 | ||
|
|
78446b5a68 | ||
|
|
3fe638d16c | ||
|
|
f71973b10a | ||
|
|
0ab0a918c3 | ||
|
|
c694688220 | ||
|
|
f979fd32e3 | ||
|
|
7e11e8138e | ||
|
|
590575f5b1 | ||
|
|
b76c525106 | ||
|
|
56a276f019 | ||
|
|
62050fcff1 | ||
|
|
d4989bb762 | ||
|
|
dff54109a4 | ||
|
|
5850d69c10 | ||
|
|
908507f64e | ||
|
|
ecd455ab21 | ||
|
|
c4ebfff55e | ||
|
|
6adf5f472d | ||
|
|
ee6b5c304a | ||
|
|
03327a549f | ||
|
|
f6e245e77d | ||
|
|
4dcf9d9a40 | ||
|
|
a6ef4e12ad | ||
|
|
2e751bb3fb | ||
|
|
5ab15341e4 | ||
|
|
d6b027e969 | ||
|
|
76a4b3b3e6 | ||
|
|
3062aee5cb | ||
|
|
dbf0d95329 | ||
|
|
c42b0d5fda | ||
|
|
59f2688399 | ||
|
|
395bf3aa5a | ||
|
|
bd85e418bc | ||
|
|
091ac05920 | ||
|
|
127d175e5c | ||
|
|
744a7f83df | ||
|
|
5f61a7af17 | ||
|
|
c4ceaddcca | ||
|
|
12729092d8 | ||
|
|
94830659e9 | ||
|
|
aef307c312 | ||
|
|
2b15c77cdc | ||
|
|
78acddb043 | ||
|
|
9106f3d2f5 | ||
|
|
2df8355a33 | ||
|
|
c5610aae05 | ||
|
|
f1f3a42557 | ||
|
|
63072120fc | ||
|
|
0be966646b | ||
|
|
c3201118bd | ||
|
|
12896574c7 | ||
|
|
5bf877647f | ||
|
|
697e692c92 | ||
|
|
7b620a294b | ||
|
|
8c1e4d7c4d | ||
|
|
468c64df40 | ||
|
|
c560bc666f | ||
|
|
8c4ab4a60d | ||
|
|
1a0b7895d9 | ||
|
|
26a29fea96 | ||
|
|
5c9a12a7b2 | ||
|
|
7d103e8f4a | ||
|
|
4f4dfd0ee1 | ||
|
|
c02e95bc49 | ||
|
|
e77bfb055a | ||
|
|
712814515c | ||
|
|
512213df15 | ||
|
|
e07c5ab7f9 | ||
|
|
83471a37b0 | ||
|
|
f82944a043 | ||
|
|
6eb5dec1f6 | ||
|
|
f7ec845a7e | ||
|
|
0e7ed65e04 | ||
|
|
60910c9d87 | ||
|
|
f4b4b3c3a6 | ||
|
|
ce363b0319 | ||
|
|
42b0a4067b | ||
|
|
1e6f755045 | ||
|
|
c7570e84a0 | ||
|
|
34b7a5f7ba | ||
|
|
ff2146a49d | ||
|
|
5038d8b07f | ||
|
|
aacc87c190 | ||
|
|
e68a21ccb7 | ||
|
|
435f0a0c84 | ||
|
|
d4269dc886 | ||
|
|
079ae529ee | ||
|
|
f8d3e23025 | ||
|
|
efa168a4b1 | ||
|
|
ebfc32be74 | ||
|
|
79a2f6d7a4 | ||
|
|
edd218b139 | ||
|
|
d3645425f6 | ||
|
|
2f34c689d0 | ||
|
|
548e5fbde1 | ||
|
|
f0b3d7f151 | ||
|
|
c85a6fd462 | ||
|
|
ddbc7988b2 | ||
|
|
83b1e3b8af | ||
|
|
8fd4f83793 | ||
|
|
32321c822f | ||
|
|
bb8e8b7367 | ||
|
|
224417e2bd | ||
|
|
afb2a39f8c | ||
|
|
f240f167ff | ||
|
|
69273f9cf9 | ||
|
|
e30079bd2c | ||
|
|
d882de1582 | ||
|
|
2e14dc22ff | ||
|
|
6839e387c2 | ||
|
|
bde2bc0b2b | ||
|
|
e6fe0885a5 | ||
|
|
f95440da99 | ||
|
|
cbfff99f89 | ||
|
|
ee119ea3cc | ||
|
|
ebefee67bc | ||
|
|
60fc2e5803 | ||
|
|
b766a6eb6a | ||
|
|
f67342fd7a | ||
|
|
2f98228310 | ||
|
|
b07739a66a | ||
|
|
3b293e3163 | ||
|
|
cec5fc594f | ||
|
|
ed10a050bc | ||
|
|
cfc3dc73c4 | ||
|
|
7c23c16280 | ||
|
|
0f27552817 | ||
|
|
7464789c8c | ||
|
|
a1f9c023c7 | ||
|
|
9e8cdc2c49 | ||
|
|
dc9b44f5f9 | ||
|
|
b7ea4bd6f1 | ||
|
|
65dddb798c | ||
|
|
2451f0b593 | ||
|
|
418734eb31 | ||
|
|
fce7fe4fe3 | ||
|
|
e31407527f | ||
|
|
9250e81059 | ||
|
|
f54f9c6736 | ||
|
|
54135a88f9 | ||
|
|
5b219708db | ||
|
|
b62a5e457b | ||
|
|
3af325f0c4 | ||
|
|
514ced2cc6 | ||
|
|
55cdf6c0cf | ||
|
|
00cd6e4309 | ||
|
|
03012d8296 | ||
|
|
b4952dbb20 | ||
|
|
9123cedf4c | ||
|
|
1c9fbfc2eb | ||
|
|
d6e182b94f | ||
|
|
e48e56f36a | ||
|
|
adde6acf4d | ||
|
|
e929aa0875 | ||
|
|
f784376486 | ||
|
|
7c0d0f4a07 | ||
|
|
e25804998d | ||
|
|
6e69f843a0 | ||
|
|
978d2878a4 | ||
|
|
675ea86b83 | ||
|
|
c2be36b8b3 | ||
|
|
938e204691 | ||
|
|
70eb911e58 | ||
|
|
0440d0f286 | ||
|
|
9651a88d67 | ||
|
|
6b8d2622b4 | ||
|
|
e743499825 | ||
|
|
127535c7d4 | ||
|
|
0a322c9fed | ||
|
|
db36c34332 | ||
|
|
6c00e8c350 | ||
|
|
4e21b136d7 | ||
|
|
407b317f01 | ||
|
|
eb55ff7c30 | ||
|
|
3729146b80 | ||
|
|
48636eae43 | ||
|
|
ae62bee78d | ||
|
|
d0f33a0813 | ||
|
|
6627b67692 | ||
|
|
32f58e6323 | ||
|
|
4c82688f7d | ||
|
|
479ed7ac1e | ||
|
|
1320a8aad1 | ||
|
|
ed1b1322fa | ||
|
|
b9b61d1462 | ||
|
|
fc982674f8 |
+3
-1
@@ -180,4 +180,6 @@ plugins/frp
|
||||
plugins/file_search
|
||||
plugins/proxysql
|
||||
plugins/tidb
|
||||
plugins/gorse
|
||||
plugins/goedge-admin
|
||||
plugins/goedge-node
|
||||
plugins/goedge-happy
|
||||
|
||||
@@ -110,11 +110,11 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
|
||||
```
|
||||
|
||||
|
||||
### 版本更新 0.17.2
|
||||
### 版本更新 0.17.3
|
||||
|
||||
- MySQL9.0。
|
||||
- zabbix,zabbix-agent测试。
|
||||
- 正则匹配修复(兼容)。
|
||||
- 新增pgadmin插件。
|
||||
- 新增acme_pandominassl_apply插件。
|
||||
- 新增快捷指令:mw pgdb。
|
||||
- 常规更新。
|
||||
|
||||
### JSDelivr安装地址
|
||||
|
||||
+10
-6
@@ -225,8 +225,7 @@ fi
|
||||
86400 # 24小时后过期
|
||||
self.saveConfig()
|
||||
except Exception as e:
|
||||
raise Exception(
|
||||
'服务因维护而关闭或发生内部错误,查看 <a href="https://letsencrypt.status.io/" target="_blank" class="btlink">https://letsencrypt.status.io/</a> 了解更多详细信息。')
|
||||
raise Exception('服务因维护而关闭或发生内部错误,查看 <a href="https://letsencrypt.status.io/" target="_blank" class="btlink">https://letsencrypt.status.io/</a> 了解更多详细信息。')
|
||||
return self.__apis
|
||||
|
||||
# 系列化payload
|
||||
@@ -1297,9 +1296,9 @@ fullchain.pem 粘贴到证书输入框
|
||||
site_sql = mw.M('sites')
|
||||
siteName = None
|
||||
for domain in domains:
|
||||
pid = sql.where('name=?', domain).getField('pid')
|
||||
pid = sql.where('name=?', (domain,)).getField('pid')
|
||||
if pid:
|
||||
siteName = site_sql.where('id=?', pid).getField('name')
|
||||
siteName = site_sql.where('id=?', (pid,)).getField('name')
|
||||
break
|
||||
return siteName
|
||||
|
||||
@@ -1325,6 +1324,8 @@ fullchain.pem 粘贴到证书输入框
|
||||
else:
|
||||
site_name = self.getSiteNameByDomains(domains)
|
||||
is_rep = api.httpToHttps(site_name)
|
||||
api.operateProxyConf(site_name,'stop')
|
||||
mw.restartWeb()
|
||||
try:
|
||||
index = self.createOrder(
|
||||
domains,
|
||||
@@ -1376,6 +1377,9 @@ fullchain.pem 粘贴到证书输入框
|
||||
is_rep_decode = json.loads(is_rep)
|
||||
if is_rep_decode['status']:
|
||||
api.closeToHttps(site_name)
|
||||
|
||||
api.operateProxyConf(site_name,'start')
|
||||
mw.restartWeb()
|
||||
writeLog("-" * 70)
|
||||
return cert
|
||||
|
||||
@@ -1447,8 +1451,8 @@ fullchain.pem 粘贴到证书输入框
|
||||
|
||||
# 是否到了最大重试次数
|
||||
if 'retry_count' in self.__config['orders'][i]:
|
||||
if self.__config['orders'][i]['retry_count'] >= 5:
|
||||
msg = '|-本次跳过域名:{},因连续5次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
|
||||
if self.__config['orders'][i]['retry_count'] >= 100:
|
||||
msg = '|-本次跳过域名:{},因连续10次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
|
||||
self.__config['orders'][i]['domains'])
|
||||
writeLog(msg)
|
||||
continue
|
||||
|
||||
@@ -28,7 +28,7 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.17.2'
|
||||
__version = '0.17.3'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
# 统一默认配置文件
|
||||
|
||||
@@ -472,6 +472,9 @@ def getJson(data):
|
||||
import json
|
||||
return json.dumps(data)
|
||||
|
||||
def getObjectByJson(data):
|
||||
import json
|
||||
return json.loads(data)
|
||||
|
||||
def returnData(status, msg, data=None):
|
||||
return {'status': status, 'msg': msg, 'data': data}
|
||||
@@ -687,6 +690,15 @@ def restoreFile(file, act=None):
|
||||
file_type = "_def"
|
||||
execShell("cp -p {1} {0}".format(file, file + file_type))
|
||||
|
||||
def base64StrEncode(content):
|
||||
content = bytes(content,'utf-8')
|
||||
content = base64.b64encode(content)
|
||||
return content.decode('utf8')
|
||||
|
||||
def base64StrDecode(content):
|
||||
content = bytes(content,'utf-8')
|
||||
content = base64.urlsafe_b64decode(content)
|
||||
return content.decode('utf8')
|
||||
|
||||
def enPunycode(domain):
|
||||
if sys.version_info[0] == 2:
|
||||
|
||||
@@ -148,7 +148,7 @@ class plugins_api:
|
||||
def initApi(self):
|
||||
|
||||
plugin_names = {
|
||||
'openresty': '1.25.3.1',
|
||||
'openresty': '1.25.3',
|
||||
'php': '56',
|
||||
'swap': '1.1',
|
||||
'mysql': '5.7',
|
||||
|
||||
@@ -1786,8 +1786,7 @@ class site_api:
|
||||
data.append({"r_from": _from, "type": _typeCode, "r_type": _rTypeCode,
|
||||
"r_to": _to, 'keep_path': _keepPath, 'id': _id})
|
||||
mw.writeFile(data_path, json.dumps(data))
|
||||
mw.writeFile(
|
||||
"{}/{}.conf".format(self.getRedirectPath(_siteName), _id), file_content)
|
||||
mw.writeFile("{}/{}.conf".format(self.getRedirectPath(_siteName), _id), file_content)
|
||||
|
||||
self.operateRedirectConf(_siteName, 'start')
|
||||
mw.restartWeb()
|
||||
@@ -1977,6 +1976,7 @@ class site_api:
|
||||
location ^~ {from} {\n\
|
||||
proxy_pass {to};\n\
|
||||
proxy_set_header Host {host};\n\
|
||||
proxy_ssl_server_name on;\n\
|
||||
proxy_set_header X-Real-IP $remote_addr;\n\
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\
|
||||
proxy_set_header REMOTE-HOST $remote_addr;\n\
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
- 面板相关命令
|
||||
|
||||
```
|
||||
/etc/init.d/mw default | 显示登录信息
|
||||
/etc/init.d/mw db | 快捷连接MySQL
|
||||
/etc/init.d/mw redis | 快捷连接Redis
|
||||
mw default | 显示登录信息
|
||||
mw db | 快捷连接MySQL
|
||||
mw redis | 快捷连接Redis
|
||||
mw mongodb | 快捷连接MongoDB
|
||||
mw pgdb | 快捷连接PostgreSQL
|
||||
----------------------------------------
|
||||
mw open | 开启面板
|
||||
mw close | 关闭面板
|
||||
@@ -16,7 +18,7 @@ mw venv | 进入虚拟环境
|
||||
mw mirror | 切换镜像
|
||||
mw install_app | 快捷安装常用软件
|
||||
mw update | 更新到正式
|
||||
mw update_dev | 更新到开发
|
||||
mw dev/update_dev | 更新到开发
|
||||
|
||||
service mw [start|stop|reload|restart|status]
|
||||
```
|
||||
|
||||
@@ -71,9 +71,14 @@ CREATE TABLE IF NOT EXISTS `sites` (
|
||||
`type_id` INTEGER,
|
||||
`ps` TEXT,
|
||||
`edate` TEXT,
|
||||
`ssl_effective_date` TEXT,
|
||||
`ssl_expiration_date` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
ALTER TABLE `sites` ADD COLUMN `ssl_effective_date` TEXT DEFAULT '';
|
||||
ALTER TABLE `sites` ADD COLUMN `ssl_expiration_date` TEXT DEFAULT '';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `site_types` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
CREATE TABLE IF NOT EXISTS `dnsapi` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`name` TEXT,
|
||||
`type` TEXT,
|
||||
`val` TEXT,
|
||||
`remark` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `email` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`addr` TEXT,
|
||||
`remark` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `domain` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`domain` TEXT,
|
||||
`dnsapi_id` TEXT,
|
||||
`email` TEXT,
|
||||
`remark` TEXT,
|
||||
`effective_date` TEXT,
|
||||
`expiration_date` TEXT,
|
||||
`error` TEXT,
|
||||
`status` INTEGER default '0',
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
-- ALTER TABLE `domain` ADD COLUMN `effective_date` TEXT DEFAULT '';
|
||||
-- ALTER TABLE `domain` ADD COLUMN `expiration_date` TEXT DEFAULT '';
|
||||
-- ALTER TABLE `domain` ADD COLUMN `error` TEXT DEFAULT '';
|
||||
-- ALTER TABLE `domain` ADD COLUMN `status` INTEGER DEFAULT '0';
|
||||
@@ -0,0 +1,128 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import requests
|
||||
import base64
|
||||
|
||||
|
||||
# 8001 / 7788
|
||||
goedge_addr = 'http://127.0.0.2:8009'
|
||||
access_keyid = "xxx"
|
||||
access_key = "xxx"
|
||||
|
||||
# 指定用户
|
||||
userId = 1
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
domain = sys.argv[1]
|
||||
ssl_path = sys.argv[2]
|
||||
|
||||
|
||||
def getToken():
|
||||
api_url = goedge_addr+'/APIAccessTokenService/getAPIAccessToken'
|
||||
post_data = {
|
||||
"type": "admin",
|
||||
"accessKeyId": access_keyid,
|
||||
"accessKey": access_key
|
||||
}
|
||||
data = requests.post(api_url,json=post_data)
|
||||
data_obj = data.json()
|
||||
|
||||
return data_obj['data']['token']
|
||||
|
||||
token = getToken()
|
||||
|
||||
def commonReq(url, data):
|
||||
headers = {
|
||||
'X-Edge-Access-Token': token
|
||||
}
|
||||
api_url = goedge_addr+url
|
||||
resp_data = requests.post(api_url,json=data, headers=headers)
|
||||
return resp_data.json()
|
||||
|
||||
def listSSLCerts(domain):
|
||||
request_data = {
|
||||
"userId":userId,
|
||||
"isCA":False,
|
||||
"keyword": "ACME泛域名自动上传",
|
||||
"domains":[domain,"*."+domain],
|
||||
"size":1
|
||||
}
|
||||
response_data = commonReq('/SSLCertService/listSSLCerts', request_data)
|
||||
|
||||
data = response_data['data']['sslCertsJSON']
|
||||
data = mw.base64StrDecode(data)
|
||||
data = mw.getObjectByJson(data)
|
||||
# print(data)
|
||||
return data
|
||||
|
||||
|
||||
|
||||
# createSSLCert(domain)
|
||||
def createSSLCert(domain, did=0):
|
||||
|
||||
ssl_cer_file = ssl_path + '/'+domain+'.cer'
|
||||
|
||||
if not os.path.exists(ssl_cer_file):
|
||||
print("没有有效证书!")
|
||||
return ''
|
||||
# print(ssl_cer_file)
|
||||
ssl_info = mw.getCertName(ssl_cer_file)
|
||||
cer_data = mw.readFile(ssl_cer_file)
|
||||
cer_data = mw.base64StrEncode(cer_data)
|
||||
# print('cer',cer_data)
|
||||
|
||||
ssl_key_file = ssl_path + '/'+domain+'.key'
|
||||
key_data = mw.readFile(ssl_key_file)
|
||||
key_data = mw.base64StrEncode(key_data)
|
||||
# print('ssl_info',ssl_info)
|
||||
|
||||
timeBeginAt = int(time.mktime(time.strptime(ssl_info['notBefore'], "%Y-%m-%d")))
|
||||
timeEndAt = int(time.mktime(time.strptime(ssl_info['notAfter'], "%Y-%m-%d")))
|
||||
|
||||
request_data = {
|
||||
"isOn":True,
|
||||
"userId":userId,
|
||||
"name": "ACME泛域名自动上传",
|
||||
"isCA":False,
|
||||
"description":domain,
|
||||
"serverName":domain,
|
||||
"certData":cer_data,
|
||||
"keyData":key_data,
|
||||
"timeBeginAt":timeBeginAt,
|
||||
"timeEndAt": timeEndAt,
|
||||
"dnsNames":[domain,"*."+domain],
|
||||
"commonNames":[ssl_info['issuer']]
|
||||
}
|
||||
|
||||
if did>0:
|
||||
request_data['sslCertId'] = did
|
||||
# print(request_data)
|
||||
response_data = commonReq('/SSLCertService/updateSSLCert', request_data)
|
||||
print('更新成功',domain,response_data)
|
||||
return response_data
|
||||
else:
|
||||
# print(request_data)
|
||||
response_data = commonReq('/SSLCertService/createSSLCert', request_data)
|
||||
print('创建成功',domain,response_data)
|
||||
return response_data
|
||||
return response_data
|
||||
|
||||
def autoSyncDomain(domain):
|
||||
data = listSSLCerts(domain)
|
||||
if len(data) > 0 :
|
||||
did = data[0]['id']
|
||||
createSSLCert(domain,did)
|
||||
else:
|
||||
createSSLCert(domain)
|
||||
print(data)
|
||||
|
||||
|
||||
autoSyncDomain(domain)
|
||||
print(domain,ssl_path)
|
||||
@@ -0,0 +1,12 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
|
||||
domain = sys.argv[1]
|
||||
path = sys.argv[2]
|
||||
|
||||
print(domain,path)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
Executable
+34
@@ -0,0 +1,34 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('acme_pandominassl_apply');">服务</p>
|
||||
<p onclick="dnsapiList();">DNSAPI *</p>
|
||||
<p onclick="emailList();">邮件地址 </p>
|
||||
<p onclick="domainList()">域名SSL *</p>
|
||||
<p onclick="pluginConfigTpl('acme_pandominassl_apply',$('.plugin_version').attr('version'));">HOOK</p>
|
||||
<p onclick="pluginLogs('acme_pandominassl_apply','','run_log');">日志</p>
|
||||
<p onclick="apaReadme();">相关说明</p>
|
||||
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(1000);
|
||||
resetPluginWinHeight(550);
|
||||
$.getScript( "/plugins/file?name=acme_pandominassl_apply&f=js/common.js", function(){
|
||||
pluginService('acme_pandominassl_apply', $('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+857
@@ -0,0 +1,857 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import requests
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'acme_pandominassl_apply'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return '/tmp/' + getPluginName()
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
return '/etc/rc.d/' + getPluginName()
|
||||
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getConf():
|
||||
path = getServerDir() + "/hook.py"
|
||||
return path
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
return path
|
||||
|
||||
def runLog():
|
||||
return getServerDir() + '/hook.log'
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[3:]
|
||||
# print(args)
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def getHomeDir():
|
||||
if mw.isAppleSystem():
|
||||
user = mw.execShell(
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
return '/Users/' + user
|
||||
else:
|
||||
return '/root'
|
||||
|
||||
|
||||
def getRunUser():
|
||||
if mw.isAppleSystem():
|
||||
user = mw.execShell(
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
return user
|
||||
else:
|
||||
return 'root'
|
||||
|
||||
def configTpl():
|
||||
path = getPluginDir() + '/hooks'
|
||||
pathFile = os.listdir(path)
|
||||
tmp = []
|
||||
for one in pathFile:
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
return mw.getJson(tmp)
|
||||
|
||||
|
||||
def readConfigTpl():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
content = mw.readFile(args['file'])
|
||||
content = contentReplace(content)
|
||||
return mw.returnJson(True, 'ok', content)
|
||||
|
||||
def getPidFile():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = r'pidfile\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def status():
|
||||
return 'start'
|
||||
|
||||
def contentReplace(content):
|
||||
service_path = mw.getServerDir()
|
||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$SERVER_APP}', service_path + '/redis')
|
||||
content = content.replace('{$REDIS_PASS}', mw.getRandomString(10))
|
||||
return content
|
||||
|
||||
|
||||
def pSqliteDb(dbname='dnsapi'):
|
||||
file = getServerDir() + '/acme.db'
|
||||
name = 'acme'
|
||||
|
||||
import_sql = mw.readFile(getPluginDir() + '/conf/acme.sql')
|
||||
md5_sql = mw.md5(import_sql)
|
||||
|
||||
import_sign = False
|
||||
save_md5_file = getServerDir() + '/acme.md5'
|
||||
if os.path.exists(save_md5_file):
|
||||
save_md5_sql = mw.readFile(save_md5_file)
|
||||
if save_md5_sql != md5_sql:
|
||||
import_sign = True
|
||||
mw.writeFile(save_md5_file, md5_sql)
|
||||
else:
|
||||
mw.writeFile(save_md5_file, md5_sql)
|
||||
|
||||
if not os.path.exists(file) or import_sql:
|
||||
conn = mw.M(dbname).dbPos(getServerDir(), name)
|
||||
csql_list = import_sql.split(';')
|
||||
for index in range(len(csql_list)):
|
||||
conn.execute(csql_list[index], ())
|
||||
|
||||
conn = mw.M(dbname).dbPos(getServerDir(), name)
|
||||
return conn
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
|
||||
run_log_file = runLog()
|
||||
if not os.path.exists(run_log_file):
|
||||
mw.writeFile(run_log_file,'')
|
||||
|
||||
hook_file = getConf()
|
||||
if not os.path.exists(hook_file):
|
||||
mw.writeFile(hook_file,'')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def apaOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
if current_os.startswith("freebsd"):
|
||||
data = mw.execShell('service ' + getPluginName() + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def start():
|
||||
import tool_cron
|
||||
tool_cron.createBgTask()
|
||||
|
||||
return apaOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
import tool_cron
|
||||
tool_cron.removeBgTask()
|
||||
return apaOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = apaOp('restart')
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
return apaOp('reload')
|
||||
|
||||
|
||||
def dnsapiAdd():
|
||||
conn = pSqliteDb('dnsapi')
|
||||
args = getArgs()
|
||||
data = checkArgs(args,['id','name', 'type', 'remark'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
name = args['name'].strip()
|
||||
remark = args['remark'].strip()
|
||||
stype = args['type'].strip()
|
||||
val = args['val'].strip()
|
||||
sid = args['id'].strip()
|
||||
|
||||
if name == '':
|
||||
return mw.returnJson(False, '名称不能为空!')
|
||||
|
||||
if sid != '0' : #修改操作
|
||||
conn.where("id=?", (sid,)).update({
|
||||
'name':name,
|
||||
'type':stype,
|
||||
'val':val,
|
||||
'remark':remark,
|
||||
})
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
|
||||
if conn.where("name=?", (name,)).count():
|
||||
return mw.returnJson(False, name+'已存在!')
|
||||
|
||||
addTime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
err = conn.add('name,type,val,remark,addtime', (name, stype, val,remark, addTime))
|
||||
# print(err)
|
||||
return mw.returnJson(True, '添加成功!')
|
||||
|
||||
def dnsapiDel():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conn = pSqliteDb('dnsapi')
|
||||
try:
|
||||
sid = args['id']
|
||||
name = args['name']
|
||||
conn.where("id=?", (sid,)).delete()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '删除失败!' + str(ex))
|
||||
|
||||
def dnsapiList():
|
||||
args = getArgs()
|
||||
page = 1
|
||||
page_size = 10
|
||||
search = ''
|
||||
data = {}
|
||||
if 'page' in args:
|
||||
page = int(args['page'])
|
||||
|
||||
if 'page_size' in args:
|
||||
page_size = int(args['page_size'])
|
||||
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
|
||||
conn = pSqliteDb('dnsapi')
|
||||
limit = str((page - 1) * page_size) + ',' + str(page_size)
|
||||
condition = ''
|
||||
if not search == '':
|
||||
condition = "name like '%" + search + "%'"
|
||||
field = 'id,name,type,val,remark,addtime'
|
||||
clist = conn.where(condition, ()).field(
|
||||
field).limit(limit).order('id desc').select()
|
||||
|
||||
count = conn.where(condition, ()).count()
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['p'] = page
|
||||
_page['row'] = page_size
|
||||
_page['tojs'] = 'dbList'
|
||||
data['page'] = mw.getPage(_page)
|
||||
data['data'] = clist
|
||||
|
||||
return mw.getJson(data)
|
||||
|
||||
def dnsapiListAll():
|
||||
conn = pSqliteDb('dnsapi')
|
||||
field = 'id,name,type,val,remark,addtime'
|
||||
data = conn.field(field).limit('1000').select()
|
||||
return mw.getJson(data)
|
||||
|
||||
def emailList():
|
||||
args = getArgs()
|
||||
page = 1
|
||||
page_size = 10
|
||||
search = ''
|
||||
data = {}
|
||||
if 'page' in args:
|
||||
page = int(args['page'])
|
||||
|
||||
if 'page_size' in args:
|
||||
page_size = int(args['page_size'])
|
||||
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
|
||||
conn = pSqliteDb('email')
|
||||
limit = str((page - 1) * page_size) + ',' + str(page_size)
|
||||
condition = ''
|
||||
if not search == '':
|
||||
condition = "addr like '%" + search + "%'"
|
||||
field = 'id,addr,remark,addtime'
|
||||
clist = conn.where(condition, ()).field(
|
||||
field).limit(limit).order('id desc').select()
|
||||
|
||||
count = conn.where(condition, ()).count()
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['p'] = page
|
||||
_page['row'] = page_size
|
||||
_page['tojs'] = 'dbList'
|
||||
data['page'] = mw.getPage(_page)
|
||||
data['data'] = clist
|
||||
|
||||
return mw.getJson(data)
|
||||
|
||||
def emailAdd():
|
||||
args = getArgs()
|
||||
data = checkArgs(args,['addr', 'remark'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
addr = args['addr'].strip()
|
||||
remark = args['remark'].strip()
|
||||
|
||||
if addr == '':
|
||||
return mw.returnJson(False, '邮件地址不能为空!')
|
||||
|
||||
conn = pSqliteDb('email')
|
||||
|
||||
addTime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
conn.add('addr,remark,addtime', (addr, remark, addTime))
|
||||
return mw.returnJson(True, '添加成功!')
|
||||
|
||||
def emailDel():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conn = pSqliteDb('email')
|
||||
try:
|
||||
sid = args['id']
|
||||
name = args['name']
|
||||
conn.where("id=?", (sid,)).delete()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '删除失败!' + str(ex))
|
||||
|
||||
def domainAdd():
|
||||
args = getArgs()
|
||||
data = checkArgs(args,['id','domain', 'dnsapi_id','email','remark'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
sid = args['id'].strip()
|
||||
domain = args['domain'].strip()
|
||||
remark = args['remark'].strip()
|
||||
email = args['email'].strip()
|
||||
dnsapi_id = args['dnsapi_id'].strip()
|
||||
|
||||
if domain == '':
|
||||
return mw.returnJson(False, '域名不能为空!')
|
||||
if email == '':
|
||||
return mw.returnJson(False, '邮件不能为空!')
|
||||
|
||||
conn = pSqliteDb('domain')
|
||||
|
||||
if sid != '0' : #修改操作
|
||||
conn.where("id=?", (sid,)).update({
|
||||
'domain':domain,
|
||||
'dnsapi_id':dnsapi_id,
|
||||
'email':email,
|
||||
'remark':remark,
|
||||
})
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
|
||||
if conn.where("domain=?", (domain,)).count():
|
||||
return mw.returnJson(False, domain+'已存在!')
|
||||
|
||||
|
||||
|
||||
addTime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
conn.add('domain,dnsapi_id,email,remark,addtime', (domain, dnsapi_id,email,remark, addTime))
|
||||
return mw.returnJson(True, '添加成功!')
|
||||
|
||||
def domainDel():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conn = pSqliteDb('domain')
|
||||
try:
|
||||
sid = args['id']
|
||||
name = args['name']
|
||||
conn.where("id=?", (sid,)).delete()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '删除失败!' + str(ex))
|
||||
|
||||
def domainStatusToggle():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conn = pSqliteDb('domain')
|
||||
|
||||
field = 'id,status'
|
||||
fdata = conn.field(field).where('id=?',(args['id'],)).find()
|
||||
|
||||
fstatus = fdata['status']
|
||||
if fstatus == 0:
|
||||
fstatus = 1
|
||||
else:
|
||||
fstatus = 0
|
||||
# print(fdata['status'],fstatus)
|
||||
conn.where("id=?", (args['id'],)).update({
|
||||
'status':fstatus,
|
||||
})
|
||||
return mw.returnJson(True, '切换成功!')
|
||||
|
||||
def domainList():
|
||||
args = getArgs()
|
||||
page = 1
|
||||
page_size = 10
|
||||
search = ''
|
||||
data = {}
|
||||
if 'page' in args:
|
||||
page = int(args['page'])
|
||||
|
||||
if 'page_size' in args:
|
||||
page_size = int(args['page_size'])
|
||||
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
|
||||
conn = pSqliteDb('domain')
|
||||
conn_dnsapi = pSqliteDb('dnsapi')
|
||||
limit = str((page - 1) * page_size) + ',' + str(page_size)
|
||||
condition = ''
|
||||
if not search == '':
|
||||
condition = "domain like '%" + search + "%'"
|
||||
field = 'id,domain,dnsapi_id,email,status,effective_date,expiration_date,remark,addtime'
|
||||
clist = conn.where(condition, ()).field(
|
||||
field).limit(limit).order('id desc').select()
|
||||
|
||||
for i in range(len(clist)):
|
||||
tdata = conn_dnsapi.field('id,name').where('id=?',(clist[i]['dnsapi_id'],)).select()
|
||||
if len(tdata) > 0:
|
||||
# print(tdata[0]['name'])
|
||||
clist[i]['dnsapi_id_alias'] = clist[i]['dnsapi_id']+'('+ tdata[0]['name'] +')'
|
||||
else:
|
||||
clist[i]['dnsapi_id_alias'] = clist[i]['dnsapi_id']+' (无)'
|
||||
|
||||
count = conn.where(condition, ()).count()
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['p'] = page
|
||||
_page['row'] = page_size
|
||||
_page['tojs'] = 'dbList'
|
||||
data['page'] = mw.getPage(_page)
|
||||
data['data'] = clist
|
||||
|
||||
return mw.getJson(data)
|
||||
|
||||
def getDnsapiData(dnsapi_id):
|
||||
if dnsapi_id == '0':
|
||||
return {}
|
||||
conn_dnsapi = pSqliteDb('dnsapi')
|
||||
tdata = conn_dnsapi.field('id,name,type,val').where('id=?',(dnsapi_id,)).select()
|
||||
|
||||
if len(tdata)>0:
|
||||
return tdata[0]
|
||||
return {}
|
||||
|
||||
def getDnsapiExportVar(val):
|
||||
cmd_list = val.split('~')
|
||||
def_var = ''
|
||||
for x in range(len(cmd_list)):
|
||||
v = cmd_list[x]
|
||||
vlist = v.split('|')
|
||||
def_var += 'export '+vlist[0]+'="'+vlist[1]+'"\n'
|
||||
return def_var
|
||||
|
||||
def getDnsapiKv(val):
|
||||
cmd_list = val.split('~')
|
||||
def_var = {}
|
||||
for x in range(len(cmd_list)):
|
||||
v = cmd_list[x]
|
||||
vlist = v.split('|')
|
||||
kk = vlist[0]
|
||||
vv = vlist[1]
|
||||
def_var[kk] = vv
|
||||
return def_var
|
||||
|
||||
def domainApplyPathJudge(domain):
|
||||
acme_dir = "/root/.acme.sh"
|
||||
if mw.isAppleSystem():
|
||||
user = getRunUser()
|
||||
acme_dir = "/Users/"+user+"/.acme.sh"
|
||||
|
||||
abs_domain_path = acme_dir+'/'+domain+'_ecc'
|
||||
# print(abs_domain_path)
|
||||
if os.path.exists(abs_domain_path):
|
||||
return True, abs_domain_path
|
||||
|
||||
abs_domain_path = acme_dir+'/'+domain
|
||||
# print(abs_domain_path)
|
||||
if os.path.exists(abs_domain_path):
|
||||
return True, abs_domain_path
|
||||
|
||||
return False,''
|
||||
|
||||
|
||||
def hookWriteLog(line):
|
||||
hook_file = runLog()
|
||||
mdate = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
log = "["+mdate+"]:"+line
|
||||
print(log)
|
||||
return mw.writeFile(hook_file,log+"\n",'a+')
|
||||
|
||||
def runHookPy(domain,path):
|
||||
# print(domain,path)
|
||||
run_log = runLog()
|
||||
hook_file = getConf()
|
||||
cmd = 'cd '+mw.getRunDir()
|
||||
cmd += ' && python3 '+hook_file + ' ' + domain + ' ' + path
|
||||
cmd += ' >> '+ run_log
|
||||
print(cmd)
|
||||
return mw.execShell(cmd)
|
||||
|
||||
def autoUpdateSslData(domain, path):
|
||||
ssl_cer_file = path + '/'+domain+'.cer'
|
||||
ssl_info = mw.getCertName(ssl_cer_file)
|
||||
|
||||
time_begin = int(time.mktime(time.strptime(ssl_info['notBefore'], "%Y-%m-%d")))
|
||||
time_end = int(time.mktime(time.strptime(ssl_info['notAfter'], "%Y-%m-%d")))
|
||||
# print(ssl_info)
|
||||
# print(time_begin,time_end)
|
||||
conn = pSqliteDb('domain')
|
||||
conn.where('domain=?', (domain,)).update({
|
||||
'effective_date':str(time_begin),
|
||||
'expiration_date':str(time_end),
|
||||
})
|
||||
|
||||
return True
|
||||
|
||||
def runHookDstDomain(row):
|
||||
domain = row['domain']
|
||||
email = str(row['email'])
|
||||
|
||||
if row['effective_date'] != '':
|
||||
effective_date = int(row['effective_date'])
|
||||
now_int = int(time.time())
|
||||
day = (now_int - effective_date)/86400
|
||||
if int(day) < 8:
|
||||
common_log = '【'+domain+'】未过期'
|
||||
hookWriteLog(common_log)
|
||||
return
|
||||
|
||||
hookWriteLog('开始申请【'+domain+'】SSL证书')
|
||||
cmd = "#!/bin/bash\n"
|
||||
|
||||
if mw.isAppleSystem():
|
||||
user = getRunUser()
|
||||
cmd += "source /Users/"+user+"/.zshrc\n"
|
||||
|
||||
cmd_data = getDnsapiData(row['dnsapi_id'])
|
||||
# print(cmd_data)
|
||||
export_val = getDnsapiExportVar(cmd_data['val'])
|
||||
cmd += export_val
|
||||
|
||||
# acme.sh --register-account -m my@example.com
|
||||
cmd_register = 'acme.sh --register-account -m '+ email + '\n'
|
||||
cmd += cmd_register
|
||||
|
||||
|
||||
# acme.sh --issue -d "example.com" -d "*.example.com" --dns dns_cf
|
||||
cmd_apply = 'acme.sh --issue --dns '+str(cmd_data['type'])+' -d '+domain+' -d "*.'+domain+'"'
|
||||
if row['effective_date'] != '':
|
||||
effective_date = int(row['effective_date'])
|
||||
now_int = int(time.time())
|
||||
day = (now_int - effective_date)/86400
|
||||
if int(day) > 7:
|
||||
cmd_apply = 'acme.sh --issue --dns '+str(cmd_data['type'])+' -d '+domain+' -d "*.'+domain+'" --force'
|
||||
cmd += cmd_apply
|
||||
|
||||
run_log = runLog()
|
||||
cmd += ' >> '+ run_log
|
||||
print(cmd)
|
||||
os.system(cmd)
|
||||
hookWriteLog('结束申请【'+domain+'】SSL证书')
|
||||
isok, path = domainApplyPathJudge(domain)
|
||||
print(isok,path)
|
||||
if isok:
|
||||
autoUpdateSslData(domain, path)
|
||||
hookWriteLog('开始执行【'+domain+'】Hook脚本')
|
||||
runHookPy(domain,path)
|
||||
hookWriteLog('结束执行【'+domain+'】Hook脚本')
|
||||
|
||||
def getHookIdCmd():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
cmd = "cd "+mw.getRunDir()+" "
|
||||
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_hook_id 1.0 {"id":"'+args['id']+'"}'
|
||||
return mw.returnJson(True, 'ok',cmd)
|
||||
|
||||
def runHookId():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['id'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
conn = pSqliteDb('domain')
|
||||
field = 'id,domain,dnsapi_id,email,effective_date,expiration_date,remark'
|
||||
row = conn.field(field).where('id=?',(args['id'],)).find()
|
||||
runHookDstDomain(row)
|
||||
return 'run hook '+args['id']+' end'
|
||||
|
||||
def runHookCmd():
|
||||
cmd = "cd "+mw.getRunDir()+" "
|
||||
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_hook'
|
||||
return mw.returnJson(True, 'ok',cmd)
|
||||
|
||||
def runHook():
|
||||
conn = pSqliteDb('domain')
|
||||
|
||||
field = 'id,domain,dnsapi_id,email,effective_date,expiration_date,remark'
|
||||
clist = conn.field(field).where('status=?',(1,)).limit('1000').order('id desc').select()
|
||||
|
||||
for idx in range(len(clist)):
|
||||
row = clist[idx]
|
||||
# print(row)
|
||||
runHookDstDomain(row)
|
||||
time.sleep(1)
|
||||
return 'run hook end'
|
||||
|
||||
def autoSyncDomain(domain, dnsapi_id, email):
|
||||
conn = pSqliteDb('domain')
|
||||
|
||||
field = 'id,domain,dnsapi_id,email,effective_date,expiration_date,remark'
|
||||
fdata = conn.field(field).where('domain=?',(domain,)).select()
|
||||
# print(fdata)
|
||||
mdate = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
if len(fdata) == 0:
|
||||
conn.add('domain,dnsapi_id,email,remark,addtime', (domain, dnsapi_id, email,"备注", mdate))
|
||||
print(domain+" 同步成功!")
|
||||
return True
|
||||
|
||||
def runSyncCfDataRow(row, page = 1):
|
||||
# print(row, page)
|
||||
|
||||
cf_key = row['kv']['CF_Key']
|
||||
cf_mail = row['kv']['CF_Email']
|
||||
header = {
|
||||
'X-Auth-Email': cf_mail,
|
||||
'X-Auth-Key': cf_key,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
url = "https://api.cloudflare.com/client/v4/zones?status=active&page="+str(page)+"&per_page=20&order=status&direction=desc&match=all"
|
||||
try:
|
||||
r = requests.get(url, timeout=30, headers=header)
|
||||
r.raise_for_status()
|
||||
r.encoding = r.apparent_encoding
|
||||
# print(r.text)
|
||||
jdata = json.loads(r.text)
|
||||
result = jdata['result']
|
||||
result_info = jdata['result_info']
|
||||
|
||||
# print(len(result))
|
||||
for i in result:
|
||||
autoSyncDomain(i['name'], row['id'], cf_mail)
|
||||
|
||||
if result_info['total_pages'] > page:
|
||||
page += 1
|
||||
runSyncCfDataRow(row, page)
|
||||
# print(result)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# 同步CloudFlare数据
|
||||
def runSyncCfData():
|
||||
print("同步CloudFlare数据开始")
|
||||
conn_dnsapi = pSqliteDb('dnsapi')
|
||||
field = "id,name,type,val"
|
||||
fdata = conn_dnsapi.field(field).where('type=?', ('dns_cf',)).limit('10').select()
|
||||
|
||||
for x in range(len(fdata)):
|
||||
row = fdata[x]
|
||||
dnsapi_kv = getDnsapiKv(row['val'])
|
||||
row['kv'] = dnsapi_kv
|
||||
runSyncCfDataRow(row)
|
||||
|
||||
print("同步CloudFlare数据结束")
|
||||
return ''
|
||||
|
||||
def runSyncCfCmd():
|
||||
cmd = "cd "+mw.getRunDir()+" "
|
||||
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_sync_cf_data'
|
||||
return mw.returnJson(True, 'ok',cmd)
|
||||
|
||||
def runSyncDnspodDataRow(row, page = 1):
|
||||
# print(row, page)
|
||||
|
||||
DPI_Id = row['kv']['DPI_Id']
|
||||
DPI_Key = row['kv']['DPI_Key']
|
||||
data = {
|
||||
'login_token': DPI_Id+','+DPI_Key,
|
||||
'length':5,
|
||||
'format':'json',
|
||||
}
|
||||
url = "https://api.dnspod.com/Domain.List"
|
||||
try:
|
||||
r = requests.post(url, timeout=30, data=data)
|
||||
r.raise_for_status()
|
||||
r.encoding = r.apparent_encoding
|
||||
|
||||
# print(r.text)
|
||||
jdata = json.loads(r.text)
|
||||
info = jdata['info']
|
||||
domains = jdata['domains']
|
||||
|
||||
# print(jdata)
|
||||
for i in domains:
|
||||
autoSyncDomain(i['name'], row['id'], i['owner'])
|
||||
|
||||
page_total = int(info['domain_total']/data['length'])
|
||||
if page_total > page:
|
||||
page += 1
|
||||
runSyncDnspodDataRow(row, page)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# 同步DnsPod数据
|
||||
def runSyncDnsPodData():
|
||||
print("同步DnsPod数据开始")
|
||||
conn_dnsapi = pSqliteDb('dnsapi')
|
||||
field = "id,name,type,val"
|
||||
fdata = conn_dnsapi.field(field).where('type=?', ('dns_dpi',)).limit('10').select()
|
||||
for x in range(len(fdata)):
|
||||
row = fdata[x]
|
||||
dnsapi_kv = getDnsapiKv(row['val'])
|
||||
row['kv'] = dnsapi_kv
|
||||
runSyncDnspodDataRow(row)
|
||||
|
||||
print(fdata)
|
||||
print("同步DnsPod数据结束")
|
||||
return ''
|
||||
|
||||
def runSyncDnsPodCmd():
|
||||
cmd = "cd "+mw.getRunDir()+" "
|
||||
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_sync_dnspod_data'
|
||||
return mw.returnJson(True, 'ok',cmd)
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
# print(func)
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
elif func == 'run_info':
|
||||
print(runInfo())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'config_tpl':
|
||||
print(configTpl())
|
||||
elif func == 'read_config_tpl':
|
||||
print(readConfigTpl())
|
||||
elif func == 'dnsapi_list':
|
||||
print(dnsapiList())
|
||||
elif func == 'dnsapi_list_all':
|
||||
print(dnsapiListAll())
|
||||
elif func == 'dnsapi_add':
|
||||
print(dnsapiAdd())
|
||||
elif func == 'dnsapi_del':
|
||||
print(dnsapiDel())
|
||||
elif func == 'email_list':
|
||||
print(emailList())
|
||||
elif func == 'email_add':
|
||||
print(emailAdd())
|
||||
elif func == 'email_del':
|
||||
print(emailDel())
|
||||
elif func == 'domain_list':
|
||||
print(domainList())
|
||||
elif func == 'domain_add':
|
||||
print(domainAdd())
|
||||
elif func == 'domain_del':
|
||||
print(domainDel())
|
||||
elif func == 'domain_status_toggle':
|
||||
print(domainStatusToggle())
|
||||
elif func == 'run_hook':
|
||||
print(runHook())
|
||||
elif func == 'run_hook_cmd':
|
||||
print(runHookCmd())
|
||||
elif func == 'get_run_hook_id_cmd':
|
||||
print(getHookIdCmd())
|
||||
elif func == 'run_hook_id':
|
||||
print(runHookId())
|
||||
elif func == 'run_sync_cf_data':
|
||||
print(runSyncCfData())
|
||||
elif func == 'run_sync_cf_cmd':
|
||||
print(runSyncCfCmd())
|
||||
elif func == 'run_sync_dnspod_data':
|
||||
print(runSyncDnsPodData())
|
||||
elif func == 'run_sync_dnspod_cmd':
|
||||
print(runSyncDnsPodCmd())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "ACME泛域名SSL申请/管理",
|
||||
"name": "acme_pandominassl_apply",
|
||||
"title": "ACME泛域名SSL",
|
||||
"shell": "install.sh",
|
||||
"versions":["1.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/acme_pandominassl_apply",
|
||||
"path": "server/acme_pandominassl_apply",
|
||||
"display": 1,
|
||||
"author": "ACME",
|
||||
"date": "2024-09-12",
|
||||
"home": "https://github.com/acmesh-official/acme.sh",
|
||||
"type": 0,
|
||||
"pid": "5"
|
||||
}
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
# curl https://get.acme.sh | sh
|
||||
# acme.sh --uninstall
|
||||
|
||||
|
||||
# source /Users/xxx/.zshrc
|
||||
|
||||
# https://github.com/acmesh-official/acme.sh/wiki/dnsapi
|
||||
# https://docs.dnspod.com/api-legacy/domains.html#get-the-domain-list
|
||||
|
||||
# cd /www/server/mdserver-web && python3 plugins/acme_pandominassl_apply/index.py run_hook
|
||||
# cd /www/server/mdserver-web && python3 plugins/acme_pandominassl_apply/index.py run_sync_cf_data
|
||||
# cd /www/server/mdserver-web && python3 plugins/acme_pandominassl_apply/index.py run_sync_dnspod_data
|
||||
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
# pip install cloudflare
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
mkdir -p $serverPath/acme_pandominassl_apply
|
||||
echo "${VERSION}" > $serverPath/acme_pandominassl_apply/version.pl
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/acme_pandominassl_apply/index.py start
|
||||
echo '安装[ACME泛域名SSL]完成'
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/acme_pandominassl_apply/index.py stop
|
||||
rm -rf $serverPath/acme_pandominassl_apply
|
||||
echo "卸载[ACME泛域名SSL]成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+792
@@ -0,0 +1,792 @@
|
||||
function apaPost(method, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'acme_pandominassl_apply';
|
||||
req_data['func'] = method;
|
||||
req_data['version'] = $('.plugin_version').attr('version');
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
//错误展示10S
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
function apaPostN(method, args,callback){
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'acme_pandominassl_apply';
|
||||
req_data['func'] = method;
|
||||
req_data['version'] = $('.plugin_version').attr('version');
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
if (!data.status){
|
||||
//错误展示10S
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function apaPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'acme_pandominassl_apply';
|
||||
req_data['func'] = method;
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function apaReadme(){
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>ACME泛域名SSL申请/管理/HOOK</li>';
|
||||
readme += '<li>通过DNS验证获取SSL证书!</li>';
|
||||
readme += '<li>HOOK: ssl发生变动时调用!</li>';
|
||||
readme += '<li>暂时仅支持1000个域名管理!</li>';
|
||||
readme += '<li>DNSAPI文档: https://github.com/acmesh-official/acme.sh/wiki/dnsapi</li>';
|
||||
readme += '<li>默认7天强制更新!</li>';
|
||||
|
||||
|
||||
readme += '</ul>';
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
|
||||
|
||||
function emailDel(id, name){
|
||||
safeMessage('删除['+name+']','您真的要删除['+name+']吗?',function(){
|
||||
var data='id='+id+'&name='+name;
|
||||
apaPost('email_del', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
emailList();
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function emailAdd(type){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: '500px',
|
||||
title: '添加邮件地址',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: true,
|
||||
btn:["提交","关闭"],
|
||||
content: "<form class='bt-form pd20' id='email_add'>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>邮件地址</span>\
|
||||
<div class='info-r'><input name='addr' class='bt-input-text mr5' style='width:100%;' placeholder='邮件地址' type='text'></div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>备注</span>\
|
||||
<div class='info-r'><input name='remark' class='bt-input-text mr5' style='width:100%;' placeholder='备注' type='text'></div>\
|
||||
</div>\
|
||||
</form>",
|
||||
success:function(){
|
||||
$("input[name='addr']").keyup(function(){
|
||||
var v = $(this).val();
|
||||
$("input[name='remark']").val(v);
|
||||
});
|
||||
},
|
||||
yes:function(index) {
|
||||
var data = $("#email_add").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
// data = toArrayObject(data);
|
||||
apaPost('email_add', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(index);
|
||||
emailList();
|
||||
}
|
||||
},{icon: rdata.status ? 1 : 2}, 2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function emailList(page, search){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
if(typeof(search) != 'undefined'){
|
||||
_data['search'] = search;
|
||||
}
|
||||
|
||||
apaPost('email_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var list = '';
|
||||
for(i in rdata.data){
|
||||
list += '<tr>';
|
||||
list +='<td><input value="'+rdata.data[i]['id']+'" class="check" onclick="checkSelect();" type="checkbox"></td>';
|
||||
list += '<td>' + rdata.data[i]['addr'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['remark'] +'</td>';
|
||||
list += '<td style="text-align:right">';
|
||||
list += '<a href="javascript:;" class="btlink" onclick="emailDel(\''+rdata.data[i]['id']+'\',\''+rdata.data[i]['addr']+'\')" title="删除">删除</a>' +
|
||||
'</td>';
|
||||
list += '</tr>';
|
||||
}
|
||||
|
||||
var con = '<div class="safe bgw">\
|
||||
<button onclick="emailAdd()" title="添加邮件地址" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">添加邮件地址</button>\
|
||||
<span style="float:right"> \
|
||||
<button batch="true" style="float: right;display: none;margin-left:10px;" onclick="delDbBatch();" title="删除选中项" class="btn btn-default btn-sm">删除选中</button>\
|
||||
</span>\
|
||||
<div class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
<thead><tr><th width="30"><input class="check" onclick="checkSelect();" type="checkbox"></th>\
|
||||
<th>邮件地址</th>\
|
||||
<th>备注</th>\
|
||||
<th style="text-align:right;">操作</th></tr></thead>\
|
||||
<tbody>'+ list +'</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
<div class="dataTables_paginate paging_bootstrap page"></div>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
$('.dataTables_paginate').html(rdata.page);
|
||||
|
||||
readerTableChecked();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function dnsapiDel(id, name){
|
||||
safeMessage('删除['+name+']','您真的要删除['+name+']吗?',function(){
|
||||
var data='id='+id+'&name='+name;
|
||||
apaPost('dnsapi_del', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dnsapiList();
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var dnsapi_option = [
|
||||
{"name":"dns_cf", "title":'cloudflare', 'key':'CF_Key:CF_Email'},
|
||||
{"name":"dns_dp", "title":'dnspod/国内', 'key':'DP_Id:DP_Key'},
|
||||
{"name":"dns_dpi", "title":'dnspod/国际', 'key':'DPI_Id:DPI_Key'},
|
||||
{"name":"dns_gd", "title":'GoDaddy', 'key':'GD_Key:GD_Secret'},
|
||||
{"name":"dns_pdns", "title":'PowerDNS', 'key':'PDNS_Url:PDNS_ServerId:PDNS_Token:PDNS_Ttl'},
|
||||
{"name":"dns_lua", "title":'LuaDNS', 'key':'LUA_Key:LUA_Email'},
|
||||
{"name":"dns_me", "title":'DNSMadeEasy', 'key':'ME_Key:ME_Secret'},
|
||||
{"name":"dns_aws", "title":'Amazon Route53', 'key':'AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY'},
|
||||
{"name":"dns_ali", "title":'Aliyun', 'key':'Ali_Key:Ali_Secret'},
|
||||
{"name":"dns_ispconfig", "title":'ISPConfig', 'key':'ISPC_User:ISPC_Password:ISPC_Api:ISPC_Api_Insecure'},
|
||||
{"name":"dns_ad", "title":'Alwaysdata', 'key':'AD_API_KEY'},
|
||||
{"name":"dns_linode_v4", "title":'Linode', 'key':'LINODE_V4_API_KEY'},
|
||||
{"name":"dns_freedns", "title":'FreeDNS', 'key':'FREEDNS_User:FREEDNS_Password'},
|
||||
{"name":"dns_cyon", "title":'cyon.ch', 'key':'CY_Username:CY_Password:CY_OTP_Secret'},
|
||||
{"name":"dns_gandi_livedns", "title":'LiveDNS', 'key':'GANDI_LIVEDNS_TOKEN'},
|
||||
{"name":"dns_knot", "title":'Knot', 'key':'KNOT_SERVER:KNOT_KEY'},
|
||||
{"name":"dns_dgon", "title":'DigitalOcean', 'key':'DO_API_KEY'},
|
||||
{"name":"dns_cloudns", "title":'ClouDNS.net', 'key':'CLOUDNS_SUB_AUTH_ID:CLOUDNS_AUTH_PASSWORD'},
|
||||
{"name":"dns_namesilo", "title":'Namesilo', 'key':'Namesilo_Key'},
|
||||
{"name":"dns_azure", "title":'Azure', 'key':'AZUREDNS_SUBSCRIPTIONID:AZUREDNS_TENANTID:AZUREDNS_APPID:AZUREDNS_CLIENTSECRET'},
|
||||
{"name":"dns_selectel", "title":'selectel.com', 'key':'SL_Key'},
|
||||
{"name":"dns_zonomi", "title":'zonomi.com', 'key':'ZM_Key'},
|
||||
{"name":"dns_kinghost", "title":'KingHost', 'key':'KINGHOST_Username:KINGHOST_Password'},
|
||||
{"name":"dns_zilore", "title":'Zilore', 'key':'Zilore_Key'},
|
||||
{"name":"dns_gcloud", "title":'Google Cloud DNS', 'key':'CLOUDSDK_ACTIVE_CONFIG_NAME'},
|
||||
{"name":"dns_mydnsjp", "title":'MyDNS.JP', 'key':'MYDNSJP_MasterID:MYDNSJP_Password'},
|
||||
{"name":"dns_doapi", "title":'do.de', 'key':'DO_LETOKEN'},
|
||||
{"name":"dns_online", "title":'Online', 'key':'ONLINE_API_KEY'},
|
||||
{"name":"dns_cn", "title":'Core-Networks', 'key':'CN_User:CN_Password'},
|
||||
{"name":"dns_ultra", "title":'UltraDNS', 'key':'ULTRA_USR:ULTRA_PWD'},
|
||||
{"name":"dns_hetzner", "title":'Hetzner', 'key':'HETZNER_Token'},
|
||||
{"name":"dns_ddnss", "title":'DDNSS.de', 'key':'DDNSS_Token'},
|
||||
];
|
||||
|
||||
function getDnsapiKey(name){
|
||||
for (var i = 0; i < dnsapi_option.length; i++) {
|
||||
if (dnsapi_option[i]['name'] == name){
|
||||
return dnsapi_option[i]['key'];
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function getDnsapiTitle(name){
|
||||
for (var i = 0; i < dnsapi_option.length; i++) {
|
||||
if (dnsapi_option[i]['name'] == name){
|
||||
return dnsapi_option[i]['title'];
|
||||
}
|
||||
}
|
||||
return '其他';
|
||||
}
|
||||
|
||||
|
||||
|
||||
function dnsapiAdd(row){
|
||||
// console.log(row);
|
||||
var option_name = '';
|
||||
var option_remark = '';
|
||||
var option_type = 'cf';
|
||||
var option_val = '';
|
||||
var option_id = 0;
|
||||
if (typeof(row) != 'undefined'){
|
||||
option_name = row['name'];
|
||||
option_remark = row['remark'];
|
||||
option_type = row['type'];
|
||||
option_val = row['val'];
|
||||
option_id = row['id'];
|
||||
|
||||
}
|
||||
|
||||
// console.log(option_name);
|
||||
function renderDnsapiOption(name, val){
|
||||
var vlist = {};
|
||||
if (val != ''){
|
||||
var t = val.split('~');
|
||||
for (var i = 0; i < t.length; i++) {
|
||||
var kv = t[i].split('|');
|
||||
if (kv.length == 2){
|
||||
vlist[kv[0]] = kv[1];
|
||||
} else {
|
||||
vlist[kv[0]] = '';
|
||||
}
|
||||
}
|
||||
// console.log(vlist);
|
||||
}
|
||||
|
||||
|
||||
var key = getDnsapiKey(name);
|
||||
var klist = key.split(':');
|
||||
// console.log(klist);
|
||||
var option_html = '';
|
||||
for (var i = 0; i < klist.length; i++) {
|
||||
var klist_val = '';
|
||||
if (klist[i] in vlist){
|
||||
klist_val = vlist[klist[i]];
|
||||
}
|
||||
|
||||
option_html += "\
|
||||
<span class='tname'>"+klist[i]+"</span>\
|
||||
<div class='info-r'>\
|
||||
<input name='"+klist[i]+"' class='bt-input-text mr5' style='width:100%;' value='"+klist_val+"' placeholder='请输入对应值' type='text'>\
|
||||
</div>";
|
||||
}
|
||||
$('#dnsapi_option').html(option_html);
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: '500px',
|
||||
title: '添加DNSAPI',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: true,
|
||||
btn:["提交","关闭"],
|
||||
content: "<form class='bt-form pd20' id='dnsapi_add'>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>名称</span>\
|
||||
<div class='info-r'><input name='name' class='bt-input-text mr5' style='width:100%;' placeholder='名称' value='"+option_name+"' type='text'></div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>DNSAPI类型</span>\
|
||||
<div class='info-r'>\
|
||||
<select class='bt-input-text mr5' name='type'>\
|
||||
<option name='cf'>cloudflare</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class='line' id='dnsapi_option'>\
|
||||
<span class='tname'>CF_Key</span>\
|
||||
<div class='info-r'>\
|
||||
<input name='v1' class='bt-input-text mr5' style='width:100%;' placeholder='请输入对应值' type='text'>\
|
||||
</div>\
|
||||
<span class='tname'>CF_Email</span>\
|
||||
<div class='info-r'>\
|
||||
<input name='v2' class='bt-input-text mr5' style='width:100%;' placeholder='请输入对应值' type='text'>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>备注</span>\
|
||||
<div class='info-r'><input name='remark' class='bt-input-text mr5' style='width:100%;' placeholder='备注' value='"+option_remark+"' type='text'></div>\
|
||||
</div>\
|
||||
<input name='id' value='"+option_id+"' type='hidden'>\
|
||||
</form>",
|
||||
success:function(){
|
||||
$("input[name='name']").keyup(function(){
|
||||
var v = $(this).val();
|
||||
$("input[name='remark']").val(v);
|
||||
});
|
||||
|
||||
var option = '';
|
||||
for (var i = 0; i<dnsapi_option.length; i++) {
|
||||
|
||||
if (dnsapi_option[i]['name'] == option_type){
|
||||
option += "<option value='"+dnsapi_option[i]['name']+"' key='"+dnsapi_option[i]['key']+"' selected>"+dnsapi_option[i]['title']+"</option>";
|
||||
} else {
|
||||
option += "<option value='"+dnsapi_option[i]['name']+"' key='"+dnsapi_option[i]['key']+"'>"+dnsapi_option[i]['title']+"</option>";
|
||||
}
|
||||
}
|
||||
|
||||
renderDnsapiOption(option_type, option_val);
|
||||
$('select[name="type"]').html(option);
|
||||
$('select[name="type"]').change(function(){
|
||||
var name = $(this).val();
|
||||
|
||||
if (option_type == name){
|
||||
renderDnsapiOption(name, option_val);
|
||||
} else {
|
||||
renderDnsapiOption(name,'');
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
yes:function(index) {
|
||||
var data = $("#dnsapi_add").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
data = toArrayObject(data);
|
||||
|
||||
var key = getDnsapiKey(data['type']);
|
||||
var klist = key.split(':');
|
||||
var val = '';
|
||||
for (var i = 0; i < klist.length; i++) {
|
||||
var k = klist[i];
|
||||
if (k in data){
|
||||
if (klist.length - 1 == i){
|
||||
val += k + '|' + data[k];
|
||||
} else {
|
||||
val += k + '|' + data[k]+'~';
|
||||
}
|
||||
}
|
||||
}
|
||||
data['val'] = val;
|
||||
apaPost('dnsapi_add', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(index);
|
||||
dnsapiList();
|
||||
}
|
||||
},{icon: rdata.status ? 1 : 2}, 2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function dnsapiList(page, search){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
if(typeof(search) != 'undefined'){
|
||||
_data['search'] = search;
|
||||
}
|
||||
|
||||
apaPost('dnsapi_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var list = '';
|
||||
for(i in rdata.data){
|
||||
list += '<tr>';
|
||||
list +='<td><input value="'+rdata.data[i]['id']+'" class="check" onclick="checkSelect();" type="checkbox"></td>';
|
||||
list += '<td>' + rdata.data[i]['name'] +'</td>';
|
||||
list += '<td>' + getDnsapiTitle(rdata.data[i]['type']) +'</td>';
|
||||
list += '<td>' + rdata.data[i]['val'].split('~').join("<br/>") +'</td>';
|
||||
list += '<td>' + rdata.data[i]['remark'] +'</td>';
|
||||
|
||||
list += '<td style="text-align:right">';
|
||||
list += '<a href="javascript:;" index="'+i+'" class="btlink edit" title="编辑">编辑</a> | ';
|
||||
list += '<a href="javascript:;" class="btlink" onclick="dnsapiDel(\''+rdata.data[i]['id']+'\',\''+rdata.data[i]['name']+'\')" title="删除">删除</a>';
|
||||
list += '</td></tr>';
|
||||
}
|
||||
|
||||
var con = '<div class="safe bgw">\
|
||||
<button onclick="dnsapiAdd()" title="DNSAPI" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">添加DNSAPI</button>\
|
||||
<span style="float:right"> \
|
||||
<button batch="true" style="float: right;display: none;margin-left:10px;" onclick="delDbBatch();" title="删除选中项" class="btn btn-default btn-sm">删除选中</button>\
|
||||
</span>\
|
||||
<div class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
<thead><tr><th width="30"><input class="check" onclick="checkSelect();" type="checkbox"></th>\
|
||||
<th>名称</th>\
|
||||
<th>类型</th>\
|
||||
<th>值</th>\
|
||||
<th>备注</th>\
|
||||
<th style="text-align:right;">操作</th></tr></thead>\
|
||||
<tbody>'+ list +'</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
<div class="dataTables_paginate paging_bootstrap page"></div>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
$('.dataTables_paginate').html(rdata.page);
|
||||
|
||||
$('.edit').click(function(){
|
||||
var idx = $(this).attr('index');
|
||||
var row = rdata.data[idx];
|
||||
// console.log(row);
|
||||
dnsapiAdd(row);
|
||||
})
|
||||
|
||||
readerTableChecked();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function domainDel(id, name){
|
||||
safeMessage('删除['+name+']','您真的要删除['+name+']吗?',function(){
|
||||
var data='id='+id+'&name='+name;
|
||||
apaPost('domain_del', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
domainList();
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function domainStatusToggle(id){
|
||||
var data='id='+id;
|
||||
apaPost('domain_status_toggle', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
domainList();
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
}
|
||||
|
||||
function domainIdCmd(id){
|
||||
var data='id='+id;
|
||||
apaPost('get_run_hook_id_cmd', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
layer.open({
|
||||
title: "手动同步命令",
|
||||
area: ['600px', '180px'],
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
btn:["复制","取消"],
|
||||
content: '<div class="pd15">\
|
||||
<div class="divtable">\
|
||||
<pre class="layui-code">'+rdata.data+'</pre>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
copyText(rdata.data);
|
||||
},
|
||||
yes:function(){
|
||||
copyText(rdata.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function domainHookCmd(){
|
||||
apaPost('run_hook_cmd', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.open({
|
||||
title: "手动同步全部命令",
|
||||
area: ['600px', '180px'],
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
btn:["复制","取消"],
|
||||
content: '<div class="pd15">\
|
||||
<div class="divtable">\
|
||||
<pre class="layui-code">'+rdata.data+'</pre>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
copyText(rdata.data);
|
||||
},
|
||||
yes:function(){
|
||||
copyText(rdata.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function syncCfCmd(){
|
||||
apaPost('run_sync_cf_cmd', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.open({
|
||||
title: "手动同步CloudFlare全部域名命令",
|
||||
area: ['600px', '180px'],
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
btn:["复制","取消"],
|
||||
content: '<div class="pd15">\
|
||||
<div class="divtable">\
|
||||
<pre class="layui-code">'+rdata.data+'</pre>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
copyText(rdata.data);
|
||||
},
|
||||
yes:function(){
|
||||
copyText(rdata.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function syncDnsPodCmd(){
|
||||
apaPost('run_sync_dnspod_cmd', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.open({
|
||||
title: "手动同步DnsPod全部域名命令",
|
||||
area: ['600px', '180px'],
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
btn:["复制","取消"],
|
||||
content: '<div class="pd15">\
|
||||
<div class="divtable">\
|
||||
<pre class="layui-code">'+rdata.data+'</pre>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
copyText(rdata.data);
|
||||
},
|
||||
yes:function(){
|
||||
copyText(rdata.data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function domainAdd(row){
|
||||
|
||||
var option_domian = '';
|
||||
var option_remark = '备注';
|
||||
var option_email = '';
|
||||
var option_id = 0;
|
||||
var option_dnsapi_id = 0;
|
||||
if (typeof(row) != 'undefined'){
|
||||
option_domian = row['domain'];
|
||||
option_remark = row['remark'];
|
||||
option_email = row['email'];
|
||||
option_id = row['id'];
|
||||
option_dnsapi_id = row['dnsapi_id'];
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: '500px',
|
||||
title: '添加顶级域名',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: true,
|
||||
btn:["提交","关闭"],
|
||||
content: "<form class='bt-form pd20' id='domain_add'>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>域名</span>\
|
||||
<div class='info-r'><input name='domain' class='bt-input-text mr5' style='width:100%;' value='"+option_domian+"' placeholder='域名' type='text'></div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>DNSAPI</span>\
|
||||
<div class='info-r'>\
|
||||
<select class='bt-input-text mr5' name='dnsapi_id'>\
|
||||
<option name='0'>无设置</option>\
|
||||
</select>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>邮件</span>\
|
||||
<div class='info-r'><input name='email' class='bt-input-text mr5' style='width:100%;' value='"+option_email+"' placeholder='邮件' type='text'></div>\
|
||||
</div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>备注</span>\
|
||||
<div class='info-r'><input name='remark' class='bt-input-text mr5' style='width:100%;' value='"+option_remark+"' placeholder='备注' type='text'></div>\
|
||||
</div>\
|
||||
<input name='id' value='"+option_id+"' type='hidden'>\
|
||||
</form>",
|
||||
success:function(){
|
||||
// $("input[name='domain']").keyup(function(){
|
||||
// var v = $(this).val();
|
||||
// $("input[name='remark']").val(v);
|
||||
// });
|
||||
|
||||
var dnsapi_id_html = "<option value='0'>无设置</option>";
|
||||
apaPostN('dnsapi_list_all', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
for (var i = 0; i < rdata.length; i++) {
|
||||
if (option_dnsapi_id == rdata[i]['id']){
|
||||
dnsapi_id_html += "<option value='"+rdata[i]['id']+"' selected>"+rdata[i]['name']+"</option>";
|
||||
} else {
|
||||
dnsapi_id_html += "<option value='"+rdata[i]['id']+"'>"+rdata[i]['name']+"</option>";
|
||||
}
|
||||
}
|
||||
$('select[name="dnsapi_id"]').html(dnsapi_id_html);
|
||||
});
|
||||
},
|
||||
yes:function(index) {
|
||||
var data = $("#domain_add").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
apaPost('domain_add', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(index);
|
||||
domainList();
|
||||
}
|
||||
},{icon: rdata.status ? 1 : 2}, 2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function domainList(page, search){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
if(typeof(search) != 'undefined'){
|
||||
_data['search'] = search;
|
||||
}
|
||||
|
||||
apaPost('domain_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
var list = '';
|
||||
for(i in rdata.data){
|
||||
list += '<tr>';
|
||||
list +='<td><input value="'+rdata.data[i]['id']+'" class="check" onclick="checkSelect();" type="checkbox"></td>';
|
||||
list += '<td>' + rdata.data[i]['domain'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['dnsapi_id_alias'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['email'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['remark'] +'</td>';
|
||||
|
||||
|
||||
|
||||
if (rdata.data[i]['effective_date'] == ''){
|
||||
list += '<td>空/未申请</td>';
|
||||
} else {
|
||||
list += '<td>'+getFormatTime(rdata.data[i]['effective_date'],'yyyy/MM/dd')+'</td>';
|
||||
}
|
||||
|
||||
if (rdata.data[i]['expiration_date'] == ''){
|
||||
list += '<td>空/未申请</td>';
|
||||
} else {
|
||||
list += '<td>'+getFormatTime(rdata.data[i]['expiration_date'],'yyyy/MM/dd')+'</td>';
|
||||
}
|
||||
|
||||
if (rdata.data[i]['status'] == '0'){
|
||||
list += '<td><a href="javascript:;" index="'+i+'" class="btlink status">否</a></td>';
|
||||
} else {
|
||||
list += '<td><a href="javascript:;" index="'+i+'" class="btlink status">是</a></td>';
|
||||
}
|
||||
|
||||
list += '<td style="text-align:right">';
|
||||
list += '<a href="javascript:;" index="'+i+'" class="btlink cmd" title="命令">命令</a> | ';
|
||||
list += '<a href="javascript:;" index="'+i+'" class="btlink edit" title="编辑">编辑</a> | ';
|
||||
list += '<a href="javascript:;" class="btlink" onclick="domainDel(\''+rdata.data[i]['id']+'\',\''+rdata.data[i]['domain']+'\')" title="删除">删除</a>';
|
||||
list += '</td></tr>';
|
||||
}
|
||||
|
||||
var con = '<div class="safe bgw">\
|
||||
<button onclick="domainAdd()" title="添加顶级域名" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">添加域名</button>\
|
||||
<button onclick="domainHookCmd()" title="全部同步命令" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">全部同步命令</button>\
|
||||
<button onclick="syncCfCmd()" title="cloudflare同步命令" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">cloudflare同步命令</button>\
|
||||
<button onclick="syncDnsPodCmd()" title="DnsPod国际同步命令" class="btn btn-success btn-sm" type="button" style="margin-right: 5px;">DnsPod国际同步命令</button>\
|
||||
<div class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
<thead><tr><th width="30"><input class="check" onclick="checkSelect();" type="checkbox"></th>\
|
||||
<th>域名</th>\
|
||||
<th>DNSAPI</th>\
|
||||
<th>邮件</th>\
|
||||
<th>备注</th>\
|
||||
<th>开始</th>\
|
||||
<th>结束</th>\
|
||||
<th>同步</th>\
|
||||
<th style="text-align:right;">操作</th></tr></thead>\
|
||||
<tbody>'+ list +'</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
<div class="dataTables_paginate paging_bootstrap page"></div>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
$('.dataTables_paginate').html(rdata.page);
|
||||
|
||||
$('.edit').click(function(){
|
||||
var idx = $(this).attr('index');
|
||||
var row = rdata.data[idx];
|
||||
domainAdd(row);
|
||||
});
|
||||
|
||||
$('.status').click(function(){
|
||||
var idx = $(this).attr('index');
|
||||
var row = rdata.data[idx];
|
||||
domainStatusToggle(row['id']);
|
||||
});
|
||||
|
||||
$('.cmd').click(function(){
|
||||
var idx = $(this).attr('index');
|
||||
var row = rdata.data[idx];
|
||||
domainIdCmd(row['id']);
|
||||
});
|
||||
|
||||
readerTableChecked();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'acme_pandominassl_apply'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getTaskConf():
|
||||
conf = getServerDir() + "/cron_config.json"
|
||||
return conf
|
||||
|
||||
def getTaskDeltaConf():
|
||||
conf = getServerDir() + "/cron_delta_config.json"
|
||||
return conf
|
||||
|
||||
|
||||
def getConfigData():
|
||||
try:
|
||||
return json.loads(mw.readFile(getTaskConf()))
|
||||
except:
|
||||
pass
|
||||
return {
|
||||
"task_id": -1,
|
||||
"period": "day-n",
|
||||
"where1": "1",
|
||||
"hour": "0",
|
||||
"minute": "15",
|
||||
}
|
||||
|
||||
|
||||
def createBgTask():
|
||||
removeBgTask()
|
||||
createBgTaskByName(getPluginName())
|
||||
return True
|
||||
|
||||
|
||||
def createBgTaskByName(name):
|
||||
args = getConfigData()
|
||||
_name = "[勿删]ACME泛域名SSL[APA]"
|
||||
res = mw.M("crontab").field("id, name").where("name=?", (_name,)).find()
|
||||
if res:
|
||||
return True
|
||||
|
||||
if "task_id" in args and args["task_id"] > 0:
|
||||
res = mw.M("crontab").field("id, name").where(
|
||||
"id=?", (args["task_id"],)).find()
|
||||
if res and res["id"] == args["task_id"]:
|
||||
print("计划任务已经存在!")
|
||||
return True
|
||||
import crontab_api
|
||||
api = crontab_api.crontab_api()
|
||||
|
||||
mw_dir = mw.getRunDir()
|
||||
cmd = '''
|
||||
mw_dir=%s
|
||||
rname=%s
|
||||
plugin_path=%s
|
||||
script_path=%s
|
||||
logs_file=$plugin_path/${rname}.log
|
||||
''' % (mw_dir, name, getServerDir(), getPluginDir())
|
||||
cmd += 'echo "★【`date +"%Y-%m-%d %H:%M:%S"`】 STSRT★" >> $logs_file' + "\n"
|
||||
cmd += 'echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $logs_file' + "\n"
|
||||
cmd += 'echo "python3 $script_path/index.py run_hook"' + "\n"
|
||||
cmd += 'cd $mw_dir && python3 $script_path/index.py run_hook' + "\n"
|
||||
cmd += 'echo "【`date +"%Y-%m-%d %H:%M:%S"`】 END★" >> $logs_file' + "\n"
|
||||
cmd += 'echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" >> $logs_file' + "\n"
|
||||
|
||||
params = {
|
||||
'name': _name,
|
||||
'type': args['period'],
|
||||
'week': "",
|
||||
'where1': args['where1'],
|
||||
'hour': args['hour'],
|
||||
'minute': args['minute'],
|
||||
'save': "",
|
||||
'backup_to': "",
|
||||
'stype': "toShell",
|
||||
'sname': '',
|
||||
'sbody': cmd,
|
||||
'urladdress': '',
|
||||
}
|
||||
|
||||
task_id = api.add(params)
|
||||
if task_id > 0:
|
||||
args["task_id"] = task_id
|
||||
args["name"] = name
|
||||
mw.writeFile(getTaskConf(), json.dumps(args))
|
||||
|
||||
|
||||
def removeBgTask():
|
||||
cfg = getConfigData()
|
||||
if "task_id" in cfg and cfg["task_id"] > 0:
|
||||
res = mw.M("crontab").field("id, name").where(
|
||||
"id=?", (cfg["task_id"],)).find()
|
||||
if res and res["id"] == cfg["task_id"]:
|
||||
import crontab_api
|
||||
api = crontab_api.crontab_api()
|
||||
data = api.delete(cfg["task_id"])
|
||||
if data[0]:
|
||||
cfg["task_id"] = -1
|
||||
mw.writeFile(getTaskConf(), json.dumps(cfg))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 1:
|
||||
action = sys.argv[1]
|
||||
if action == "remove":
|
||||
removeBgTask()
|
||||
elif action == "add":
|
||||
createBgTask()
|
||||
@@ -127,6 +127,7 @@ def initConf():
|
||||
"/var/log/cron",
|
||||
"/www/wwwlogs",
|
||||
"/www/server/rsyncd",
|
||||
"/www/server/acme_pandominassl_apply",
|
||||
"/www/server/sphinx/index",
|
||||
"/www/server/mongodb/logs",
|
||||
"/www/server/php/53/var/log",
|
||||
|
||||
@@ -262,7 +262,12 @@ class nosqlMongodbCtr():
|
||||
|
||||
# print(where)
|
||||
result = collection_instance.find(where).skip(start_index).limit(size).sort('_id',-1)
|
||||
count = collection_instance.count_documents(where)
|
||||
if where:
|
||||
count = collection_instance.count_documents(where)
|
||||
else:
|
||||
collection_stats = db_instance.command("collStats", collection)
|
||||
count = collection_stats.get("count")
|
||||
|
||||
d = []
|
||||
for document in result:
|
||||
d.append(document)
|
||||
|
||||
@@ -167,6 +167,19 @@ class nosqlMySQLCtr():
|
||||
sid = args['sid']
|
||||
db = args['db']
|
||||
table = args['table']
|
||||
if table == '':
|
||||
page_args = {}
|
||||
page_args['count'] = 0
|
||||
page_args['tojs'] = 'mysqlGetDataList'
|
||||
page_args['p'] = 1
|
||||
page_args['row'] = 10
|
||||
|
||||
rdata = {}
|
||||
rdata['page'] = mw.getPage(page_args)
|
||||
rdata['list'] = []
|
||||
rdata['count'] = 0
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
p = 1
|
||||
size = 10
|
||||
if 'p' in args:
|
||||
@@ -223,6 +236,7 @@ class nosqlMySQLCtr():
|
||||
rdata['soso_field'] = ''
|
||||
if 'field' in args_where:
|
||||
rdata['soso_field'] = args_where['field']
|
||||
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
def showProcessList(self,args):
|
||||
|
||||
@@ -135,7 +135,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pull-right" style="padding-top: 5px;">
|
||||
<div id="mongodb_select" class="pull-right" style="padding-top: 5px;">
|
||||
<div class="server_list" style="float:left;">
|
||||
<select name="sid" class="bt-input-text c5 mr5">
|
||||
<option value="0">本地服务器</option>
|
||||
|
||||
@@ -227,7 +227,6 @@ function initTabMongodb(){
|
||||
}
|
||||
|
||||
|
||||
|
||||
function initTabMemcached(){
|
||||
memcachedGetList();
|
||||
|
||||
@@ -288,7 +287,11 @@ function mysqlGetDbName(){
|
||||
}
|
||||
|
||||
function mysqlGetTableName(){
|
||||
return $('#mysql .mysql_table_list select[name=mysql_table]').val();
|
||||
var table = $('#mysql .mysql_table_list select[name=mysql_table]').val();
|
||||
if (!table){
|
||||
return '';
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
function mysqlInitField(f, data){
|
||||
@@ -397,7 +400,7 @@ function mysqlGetDataList(p){
|
||||
} else {
|
||||
request_data['where'] = {};
|
||||
}
|
||||
// console.log(request_data);
|
||||
|
||||
myPostCB('get_data_list',request_data ,function(rdata){
|
||||
|
||||
if (rdata.data.status){
|
||||
@@ -758,6 +761,7 @@ function mongodbCollectionName(){
|
||||
function mongodbGetList(){
|
||||
var sid = mongodbGetSid();
|
||||
mgdbPostCB('get_db_list',{'sid':sid} ,function(rdata){
|
||||
// console.log(rdata);
|
||||
if (rdata.data.status){
|
||||
var list = rdata.data.data['list'];
|
||||
var content = '';
|
||||
@@ -775,6 +779,11 @@ function mongodbGetList(){
|
||||
mongodbGetCollections(list[0]);
|
||||
}
|
||||
|
||||
$('#mongodb_select .db_list select[name="db"]').change(function(){
|
||||
var collection_name = $(this).val();
|
||||
mongodbGetCollections(collection_name);
|
||||
});
|
||||
|
||||
closeInstallLayer();
|
||||
} else {
|
||||
showInstallLayer();
|
||||
@@ -787,6 +796,7 @@ function mongodbGetCollections(name){
|
||||
var sid = mongodbGetSid();
|
||||
|
||||
mgdbPostCB('get_collections_list',{'sid':sid,'name':name} ,function(rdata){
|
||||
// console.log(rdata);
|
||||
if (rdata.data.status){
|
||||
var list = rdata.data.data['collections'];
|
||||
|
||||
@@ -817,13 +827,19 @@ function mongodbGetCollections(name){
|
||||
var isAdd = data.isAdd;
|
||||
if (isAdd){
|
||||
$('#mongodb').data('collection',change[0].value);
|
||||
mongodbDataList(1);
|
||||
|
||||
setTimeout(function(){
|
||||
mongodbDataList(1);
|
||||
},200);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (select_list.length > 0){
|
||||
mongodbDataList(1);
|
||||
|
||||
setTimeout(function(){
|
||||
mongodbDataList(1);
|
||||
},200);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,594 @@
|
||||
[INCLUDES]
|
||||
before = paths-debian.conf
|
||||
|
||||
[DEFAULT]
|
||||
backend = systemd
|
||||
ignorecommand =
|
||||
bantime = 10m
|
||||
findtime = 10m
|
||||
maxretry = 5
|
||||
|
||||
maxmatches = %(maxretry)s
|
||||
usedns = warn
|
||||
logencoding = auto
|
||||
enabled = false
|
||||
mode = normal
|
||||
filter = %(__name__)s[mode=%(mode)s]
|
||||
|
||||
destemail = root@localhost
|
||||
|
||||
sender = root@<fq-hostname>
|
||||
|
||||
mta = sendmail
|
||||
|
||||
protocol = tcp
|
||||
|
||||
chain = <known/chain>
|
||||
|
||||
port = 0:65535
|
||||
|
||||
fail2ban_agent = Fail2Ban/%(fail2ban_version)s
|
||||
|
||||
|
||||
banaction = iptables-multiport
|
||||
banaction_allports = iptables-allports
|
||||
|
||||
action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
action_mw = %(action_)s
|
||||
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
action_mwl = %(action_)s
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
action_xarf = %(action_)s
|
||||
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
|
||||
|
||||
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
action_blocklist_de = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]
|
||||
action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
action_abuseipdb = abuseipdb
|
||||
|
||||
action = %(action_)s
|
||||
|
||||
[sshd]
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
|
||||
[dropbear]
|
||||
port = ssh
|
||||
logpath = %(dropbear_log)s
|
||||
backend = %(dropbear_backend)s
|
||||
|
||||
|
||||
[selinux-ssh]
|
||||
port = ssh
|
||||
logpath = %(auditd_log)s
|
||||
|
||||
|
||||
[apache-auth]
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
[apache-badbots]
|
||||
port = http,https
|
||||
logpath = %(apache_access_log)s
|
||||
bantime = 48h
|
||||
maxretry = 1
|
||||
|
||||
[apache-noscript]
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
|
||||
[apache-overflows]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-nohome]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-botsearch]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-fakegooglebot]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_access_log)s
|
||||
maxretry = 1
|
||||
ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot <ip>
|
||||
|
||||
|
||||
[apache-modsecurity]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-shellshock]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[openhab-auth]
|
||||
|
||||
filter = openhab
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = /opt/openhab/logs/request.log
|
||||
|
||||
|
||||
[nginx-http-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
|
||||
[nginx-limit-req]
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
|
||||
[nginx-botsearch]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
|
||||
[php-url-fopen]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_access_log)s
|
||||
%(apache_access_log)s
|
||||
|
||||
|
||||
[suhosin]
|
||||
|
||||
port = http,https
|
||||
logpath = %(suhosin_log)s
|
||||
|
||||
|
||||
[lighttpd-auth]
|
||||
port = http,https
|
||||
logpath = %(lighttpd_error_log)s
|
||||
|
||||
|
||||
|
||||
[roundcube-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(roundcube_errors_log)s
|
||||
|
||||
|
||||
[openwebmail]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/openwebmail.log
|
||||
|
||||
|
||||
[horde]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/horde/horde.log
|
||||
|
||||
|
||||
[groupoffice]
|
||||
|
||||
port = http,https
|
||||
logpath = /home/groupoffice/log/info.log
|
||||
|
||||
|
||||
[sogo-auth]
|
||||
port = http,https
|
||||
logpath = /var/log/sogo/sogo.log
|
||||
|
||||
|
||||
[tine20]
|
||||
|
||||
logpath = /var/log/tine20/tine20.log
|
||||
port = http,https
|
||||
|
||||
|
||||
|
||||
[drupal-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
[guacamole]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/tomcat*/catalina.out
|
||||
|
||||
[monit]
|
||||
port = 2812
|
||||
logpath = /var/log/monit
|
||||
/var/log/monit.log
|
||||
|
||||
|
||||
[webmin-auth]
|
||||
|
||||
port = 10000
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[froxlor-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
|
||||
[squid]
|
||||
|
||||
port = 80,443,3128,8080
|
||||
logpath = /var/log/squid/access.log
|
||||
|
||||
|
||||
[3proxy]
|
||||
|
||||
port = 3128
|
||||
logpath = /var/log/3proxy.log
|
||||
|
||||
|
||||
|
||||
|
||||
[proftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(proftpd_log)s
|
||||
backend = %(proftpd_backend)s
|
||||
|
||||
|
||||
[pure-ftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(pureftpd_log)s
|
||||
backend = %(pureftpd_backend)s
|
||||
|
||||
|
||||
[gssftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[wuftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(wuftpd_log)s
|
||||
backend = %(wuftpd_backend)s
|
||||
|
||||
|
||||
[vsftpd]
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(vsftpd_log)s
|
||||
|
||||
|
||||
|
||||
[assp]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = /root/path/to/assp/logs/maillog.txt
|
||||
|
||||
|
||||
[courier-smtp]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[postfix]
|
||||
mode = more
|
||||
port = smtp,465,submission
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
|
||||
|
||||
[postfix-rbl]
|
||||
|
||||
filter = postfix[mode=rbl]
|
||||
port = smtp,465,submission
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[sendmail-auth]
|
||||
|
||||
port = submission,465,smtp
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[sendmail-reject]
|
||||
port = smtp,465,submission
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[qmail-rbl]
|
||||
|
||||
filter = qmail
|
||||
port = smtp,465,submission
|
||||
logpath = /service/qmail/log/main/current
|
||||
|
||||
|
||||
[dovecot]
|
||||
|
||||
port = pop3,pop3s,imap,imaps,submission,465,sieve
|
||||
logpath = %(dovecot_log)s
|
||||
backend = %(dovecot_backend)s
|
||||
|
||||
|
||||
[sieve]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(dovecot_log)s
|
||||
backend = %(dovecot_backend)s
|
||||
|
||||
|
||||
[solid-pop3d]
|
||||
|
||||
port = pop3,pop3s
|
||||
logpath = %(solidpop3d_log)s
|
||||
|
||||
|
||||
[exim]
|
||||
port = smtp,465,submission
|
||||
logpath = %(exim_main_log)s
|
||||
|
||||
|
||||
[exim-spam]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(exim_main_log)s
|
||||
|
||||
|
||||
[kerio]
|
||||
|
||||
port = imap,smtp,imaps,465
|
||||
logpath = /opt/kerio/mailserver/store/logs/security.log
|
||||
|
||||
|
||||
|
||||
[courier-auth]
|
||||
port = smtp,465,submission,imap,imaps,pop3,pop3s
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[postfix-sasl]
|
||||
filter = postfix[mode=auth]
|
||||
port = smtp,465,submission,imap,imaps,pop3,pop3s
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
|
||||
|
||||
[perdition]
|
||||
port = imap,imaps,pop3,pop3s
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[squirrelmail]
|
||||
port = smtp,465,submission,imap,imap2,imaps,pop3,pop3s,http,https,socks
|
||||
logpath = /var/lib/squirrelmail/prefs/squirrelmail_access_log
|
||||
|
||||
|
||||
[cyrus-imap]
|
||||
port = imap,imaps
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[uwimap-auth]
|
||||
port = imap,imaps
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[named-refused]
|
||||
port = domain,953
|
||||
logpath = /var/log/named/security.log
|
||||
|
||||
|
||||
[nsd]
|
||||
|
||||
port = 53
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/nsd.log
|
||||
|
||||
|
||||
|
||||
[asterisk]
|
||||
port = 5060,5061
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/asterisk/messages
|
||||
maxretry = 10
|
||||
|
||||
|
||||
[freeswitch]
|
||||
port = 5060,5061
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/freeswitch.log
|
||||
maxretry = 10
|
||||
|
||||
|
||||
[znc-adminlog]
|
||||
port = 6667
|
||||
logpath = /var/lib/znc/moddata/adminlog/znc.log
|
||||
|
||||
|
||||
[mysqld-auth]
|
||||
|
||||
port = 3306
|
||||
logpath = %(mysql_log)s
|
||||
backend = %(mysql_backend)s
|
||||
|
||||
|
||||
[mongodb-auth]
|
||||
port = 27017
|
||||
logpath = /var/log/mongodb/mongodb.log
|
||||
|
||||
|
||||
[recidive]
|
||||
|
||||
logpath = /var/log/fail2ban.log
|
||||
banaction = %(banaction_allports)s
|
||||
bantime = 1w
|
||||
findtime = 1d
|
||||
|
||||
[pam-generic]
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[xinetd-fail]
|
||||
|
||||
banaction = iptables-multiport-log
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[stunnel]
|
||||
|
||||
logpath = /var/log/stunnel4/stunnel.log
|
||||
|
||||
|
||||
[ejabberd-auth]
|
||||
|
||||
port = 5222
|
||||
logpath = /var/log/ejabberd/ejabberd.log
|
||||
|
||||
|
||||
[counter-strike]
|
||||
|
||||
logpath = /opt/cstrike/logs/L[0-9]*.log
|
||||
tcpport = 27030,27031,27032,27033,27034,27035,27036,27037,27038,27039
|
||||
udpport = 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, port="%(tcpport)s", protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, port="%(udpport)s", protocol="udp"]
|
||||
|
||||
[softethervpn]
|
||||
port = 500,4500
|
||||
protocol = udp
|
||||
logpath = /usr/local/vpnserver/security_log/*/sec.log
|
||||
|
||||
[gitlab]
|
||||
port = http,https
|
||||
logpath = /var/log/gitlab/gitlab-rails/application.log
|
||||
|
||||
[grafana]
|
||||
port = http,https
|
||||
logpath = /var/log/grafana/grafana.log
|
||||
|
||||
[bitwarden]
|
||||
port = http,https
|
||||
logpath = /home/*/bwdata/logs/identity/Identity/log.txt
|
||||
|
||||
[centreon]
|
||||
port = http,https
|
||||
logpath = /var/log/centreon/login.log
|
||||
|
||||
[nagios]
|
||||
|
||||
logpath = %(syslog_daemon)s ; nrpe.cfg may define a different log_facility
|
||||
backend = %(syslog_backend)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[oracleims]
|
||||
logpath = /opt/sun/comms/messaging64/log/mail.log_current
|
||||
banaction = %(banaction_allports)s
|
||||
|
||||
[directadmin]
|
||||
logpath = /var/log/directadmin/login.log
|
||||
port = 2222
|
||||
|
||||
[portsentry]
|
||||
logpath = /var/lib/portsentry/portsentry.history
|
||||
maxretry = 1
|
||||
|
||||
[pass2allow-ftp]
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
knocking_url = /knocking/
|
||||
filter = apache-pass[knocking_url="%(knocking_url)s"]
|
||||
logpath = %(apache_access_log)s
|
||||
blocktype = RETURN
|
||||
returntype = DROP
|
||||
action = %(action_)s[blocktype=%(blocktype)s, returntype=%(returntype)s,
|
||||
actionstart_on_demand=false, actionrepair_on_unban=true]
|
||||
bantime = 1h
|
||||
maxretry = 1
|
||||
findtime = 1
|
||||
|
||||
|
||||
[murmur]
|
||||
port = 64738
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/mumble-server/mumble-server.log
|
||||
|
||||
|
||||
[screensharingd]
|
||||
logpath = /var/log/system.log
|
||||
logencoding = utf-8
|
||||
|
||||
[haproxy-http-auth]
|
||||
logpath = /var/log/haproxy.log
|
||||
|
||||
[slapd]
|
||||
port = ldap,ldaps
|
||||
logpath = /var/log/slapd.log
|
||||
|
||||
[domino-smtp]
|
||||
port = smtp,ssmtp
|
||||
logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log
|
||||
|
||||
[phpmyadmin-syslog]
|
||||
port = http,https
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[zoneminder]
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
[traefik-auth]
|
||||
port = http,https
|
||||
logpath = /var/log/traefik/access.log
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
Executable
+30
@@ -0,0 +1,30 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('fail2ban');">服务</p>
|
||||
<p onclick="pluginInitD('fail2ban');">自启动</p>
|
||||
<p onclick="pluginConfigTpl('fail2ban',$('.plugin_version').attr('version'));">配置修改</p>
|
||||
<!-- <p onclick="getRedisConfig($('.plugin_version').attr('version'));">性能调整</p> -->
|
||||
<!-- <p onclick="redisStatus($('.plugin_version').attr('version'));">负载状态</p> -->
|
||||
<p onclick="pluginLogs('fail2ban','','run_log');">运行日志</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con" style="height: 520px; overflow: auto;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=fail2ban&f=js/fail2ban.js", function(){
|
||||
pluginService('fail2ban', $('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+284
@@ -0,0 +1,284 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'fail2ban'
|
||||
|
||||
def f2bDir():
|
||||
return '/run/fail2ban'
|
||||
|
||||
def f2bEtcDir():
|
||||
return '/etc/fail2ban'
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return '/tmp/' + getPluginName()
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
return '/etc/rc.d/' + getPluginName()
|
||||
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getConf():
|
||||
path = f2bEtcDir() + "/fail2ban.conf"
|
||||
return path
|
||||
|
||||
|
||||
def getConfTpl():
|
||||
path = getPluginDir() + "/config/redis.conf"
|
||||
return path
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
return path
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[3:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
def configTpl():
|
||||
path = f2bEtcDir()
|
||||
pathFile = os.listdir(path)
|
||||
tmp = []
|
||||
for one in pathFile:
|
||||
if one.endswith("conf"):
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
return mw.getJson(tmp)
|
||||
|
||||
|
||||
def readConfigTpl():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
content = mw.readFile(args['file'])
|
||||
content = contentReplace(content)
|
||||
return mw.returnJson(True, 'ok', content)
|
||||
|
||||
def runLog():
|
||||
return '/var/log/fail2ban.log'
|
||||
|
||||
def getPidFile():
|
||||
f2dir = f2bDir()
|
||||
return f2dir+'/fail2ban.pid'
|
||||
|
||||
def status():
|
||||
pid_file = getPidFile()
|
||||
if not os.path.exists(pid_file):
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
def contentReplace(content):
|
||||
service_path = mw.getServerDir()
|
||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
return content
|
||||
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
|
||||
# initd replace
|
||||
# if not os.path.exists(file_bin):
|
||||
# content = mw.readFile(file_tpl)
|
||||
# content = content.replace('{$SERVER_PATH}', service_path)
|
||||
# mw.writeFile(file_bin, content)
|
||||
# mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
systemService = systemDir + '/' + getPluginName() + '.service'
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
|
||||
service_path = mw.getServerDir()
|
||||
se_content = mw.readFile(systemServiceTpl)
|
||||
se_content = se_content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(systemService, se_content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def f2bOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
if current_os.startswith("freebsd"):
|
||||
data = mw.execShell('service ' + getPluginName() + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def start():
|
||||
return f2bOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return f2bOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = f2bOp('restart')
|
||||
|
||||
log_file = runLog()
|
||||
mw.execShell("echo '' > " + log_file)
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
return f2bOp('reload')
|
||||
|
||||
|
||||
def initdStatus():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
|
||||
shell_cmd = 'systemctl status ' + \
|
||||
getPluginName() + ' | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
if data[0] == '':
|
||||
return 'fail'
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
# freebsd initd install
|
||||
if current_os.startswith('freebsd'):
|
||||
import shutil
|
||||
source_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(source_bin, initd_bin)
|
||||
mw.execShell('chmod +x ' + initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="YES"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl enable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="NO"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl disable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
elif func == 'initd_status':
|
||||
print(initdStatus())
|
||||
elif func == 'initd_install':
|
||||
print(initdInstall())
|
||||
elif func == 'initd_uninstall':
|
||||
print(initdUinstall())
|
||||
elif func == 'run_info':
|
||||
print(runInfo())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'config_tpl':
|
||||
print(configTpl())
|
||||
elif func == 'read_config_tpl':
|
||||
print(readConfigTpl())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "防止恶意IP地址暴力破解服务、站点,禁止导致多个身份验证错误的主机",
|
||||
"name": "fail2ban",
|
||||
"title": "fail2ban",
|
||||
"shell": "install.sh",
|
||||
"versions":["1.1.0"],
|
||||
"updates":["1.1.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/fail2ban",
|
||||
"path": "server/fail2ban",
|
||||
"display": 1,
|
||||
"author": "fail2ban",
|
||||
"date": "2025-07-28",
|
||||
"home": "https://www.fail2ban.org",
|
||||
"type": 0,
|
||||
"pid": "4"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
[Unit]
|
||||
Description=Fail2Ban Service
|
||||
Documentation=man:fail2ban(1)
|
||||
After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service
|
||||
PartOf=firewalld.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment="PYTHONNOUSERSITE=1"
|
||||
ExecStartPre=/bin/mkdir -p /run/fail2ban
|
||||
ExecStart=/usr/bin/fail2ban-server -xf start
|
||||
# if should be logged in systemd journal, use following line or set logtarget to sysout in fail2ban.local
|
||||
# ExecStart=/usr/bin/fail2ban-server -xf --logtarget=sysout start
|
||||
ExecStop=/usr/bin/fail2ban-client stop
|
||||
ExecReload=/usr/bin/fail2ban-client reload
|
||||
PIDFile=/run/fail2ban/fail2ban.pid
|
||||
Restart=on-failure
|
||||
RestartPreventExitStatus=0 255
|
||||
Environment="PYTHONNOUSERSITE=yes"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/fail2ban && bash install.sh install 1.1.0
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
|
||||
apt install -y fail2ban
|
||||
|
||||
mkdir -p $serverPath/fail2ban
|
||||
echo "${VERSION}" > $serverPath/fail2ban/version.pl
|
||||
echo '安装fail2ban完成'
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/fail2ban/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/fail2ban/index.py initd_install
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
apt remove -y fail2ban
|
||||
|
||||
|
||||
if [ -f /usr/lib/systemd/system/fail2ban.service ];then
|
||||
systemctl stop fail2ban
|
||||
systemctl disable fail2ban
|
||||
rm -rf /usr/lib/systemd/system/fail2ban.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/fail2ban.service ];then
|
||||
systemctl stop fail2ban
|
||||
systemctl disable fail2ban
|
||||
rm -rf /lib/systemd/system/fail2ban.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/fail2ban/initd/fail2ban ];then
|
||||
$serverPath/fail2ban/initd/fail2ban stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/fail2ban ];then
|
||||
rm -rf $serverPath/fail2ban
|
||||
fi
|
||||
|
||||
echo "卸载fail2ban成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
function f2bPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'fail2ban';
|
||||
req_data['func'] = method;
|
||||
req_data['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
//错误展示10S
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function f2bPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'fail2ban';
|
||||
req_data['func'] = method;
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
@@ -0,0 +1,594 @@
|
||||
[INCLUDES]
|
||||
before = paths-debian.conf
|
||||
|
||||
[DEFAULT]
|
||||
backend = systemd
|
||||
ignorecommand =
|
||||
bantime = 10m
|
||||
findtime = 10m
|
||||
maxretry = 5
|
||||
|
||||
maxmatches = %(maxretry)s
|
||||
usedns = warn
|
||||
logencoding = auto
|
||||
enabled = false
|
||||
mode = normal
|
||||
filter = %(__name__)s[mode=%(mode)s]
|
||||
|
||||
destemail = root@localhost
|
||||
|
||||
sender = root@<fq-hostname>
|
||||
|
||||
mta = sendmail
|
||||
|
||||
protocol = tcp
|
||||
|
||||
chain = <known/chain>
|
||||
|
||||
port = 0:65535
|
||||
|
||||
fail2ban_agent = Fail2Ban/%(fail2ban_version)s
|
||||
|
||||
|
||||
banaction = iptables-multiport
|
||||
banaction_allports = iptables-allports
|
||||
|
||||
action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
action_mw = %(action_)s
|
||||
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
action_mwl = %(action_)s
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
action_xarf = %(action_)s
|
||||
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
|
||||
|
||||
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
action_blocklist_de = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]
|
||||
action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
action_abuseipdb = abuseipdb
|
||||
|
||||
action = %(action_)s
|
||||
|
||||
[sshd]
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
|
||||
[dropbear]
|
||||
port = ssh
|
||||
logpath = %(dropbear_log)s
|
||||
backend = %(dropbear_backend)s
|
||||
|
||||
|
||||
[selinux-ssh]
|
||||
port = ssh
|
||||
logpath = %(auditd_log)s
|
||||
|
||||
|
||||
[apache-auth]
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
[apache-badbots]
|
||||
port = http,https
|
||||
logpath = %(apache_access_log)s
|
||||
bantime = 48h
|
||||
maxretry = 1
|
||||
|
||||
[apache-noscript]
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
|
||||
[apache-overflows]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-nohome]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-botsearch]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-fakegooglebot]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_access_log)s
|
||||
maxretry = 1
|
||||
ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot <ip>
|
||||
|
||||
|
||||
[apache-modsecurity]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-shellshock]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[openhab-auth]
|
||||
|
||||
filter = openhab
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = /opt/openhab/logs/request.log
|
||||
|
||||
|
||||
[nginx-http-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
|
||||
[nginx-limit-req]
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
|
||||
[nginx-botsearch]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
|
||||
[php-url-fopen]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_access_log)s
|
||||
%(apache_access_log)s
|
||||
|
||||
|
||||
[suhosin]
|
||||
|
||||
port = http,https
|
||||
logpath = %(suhosin_log)s
|
||||
|
||||
|
||||
[lighttpd-auth]
|
||||
port = http,https
|
||||
logpath = %(lighttpd_error_log)s
|
||||
|
||||
|
||||
|
||||
[roundcube-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(roundcube_errors_log)s
|
||||
|
||||
|
||||
[openwebmail]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/openwebmail.log
|
||||
|
||||
|
||||
[horde]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/horde/horde.log
|
||||
|
||||
|
||||
[groupoffice]
|
||||
|
||||
port = http,https
|
||||
logpath = /home/groupoffice/log/info.log
|
||||
|
||||
|
||||
[sogo-auth]
|
||||
port = http,https
|
||||
logpath = /var/log/sogo/sogo.log
|
||||
|
||||
|
||||
[tine20]
|
||||
|
||||
logpath = /var/log/tine20/tine20.log
|
||||
port = http,https
|
||||
|
||||
|
||||
|
||||
[drupal-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
[guacamole]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/tomcat*/catalina.out
|
||||
|
||||
[monit]
|
||||
port = 2812
|
||||
logpath = /var/log/monit
|
||||
/var/log/monit.log
|
||||
|
||||
|
||||
[webmin-auth]
|
||||
|
||||
port = 10000
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[froxlor-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
|
||||
[squid]
|
||||
|
||||
port = 80,443,3128,8080
|
||||
logpath = /var/log/squid/access.log
|
||||
|
||||
|
||||
[3proxy]
|
||||
|
||||
port = 3128
|
||||
logpath = /var/log/3proxy.log
|
||||
|
||||
|
||||
|
||||
|
||||
[proftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(proftpd_log)s
|
||||
backend = %(proftpd_backend)s
|
||||
|
||||
|
||||
[pure-ftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(pureftpd_log)s
|
||||
backend = %(pureftpd_backend)s
|
||||
|
||||
|
||||
[gssftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[wuftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(wuftpd_log)s
|
||||
backend = %(wuftpd_backend)s
|
||||
|
||||
|
||||
[vsftpd]
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(vsftpd_log)s
|
||||
|
||||
|
||||
|
||||
[assp]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = /root/path/to/assp/logs/maillog.txt
|
||||
|
||||
|
||||
[courier-smtp]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[postfix]
|
||||
mode = more
|
||||
port = smtp,465,submission
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
|
||||
|
||||
[postfix-rbl]
|
||||
|
||||
filter = postfix[mode=rbl]
|
||||
port = smtp,465,submission
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[sendmail-auth]
|
||||
|
||||
port = submission,465,smtp
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[sendmail-reject]
|
||||
port = smtp,465,submission
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[qmail-rbl]
|
||||
|
||||
filter = qmail
|
||||
port = smtp,465,submission
|
||||
logpath = /service/qmail/log/main/current
|
||||
|
||||
|
||||
[dovecot]
|
||||
|
||||
port = pop3,pop3s,imap,imaps,submission,465,sieve
|
||||
logpath = %(dovecot_log)s
|
||||
backend = %(dovecot_backend)s
|
||||
|
||||
|
||||
[sieve]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(dovecot_log)s
|
||||
backend = %(dovecot_backend)s
|
||||
|
||||
|
||||
[solid-pop3d]
|
||||
|
||||
port = pop3,pop3s
|
||||
logpath = %(solidpop3d_log)s
|
||||
|
||||
|
||||
[exim]
|
||||
port = smtp,465,submission
|
||||
logpath = %(exim_main_log)s
|
||||
|
||||
|
||||
[exim-spam]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(exim_main_log)s
|
||||
|
||||
|
||||
[kerio]
|
||||
|
||||
port = imap,smtp,imaps,465
|
||||
logpath = /opt/kerio/mailserver/store/logs/security.log
|
||||
|
||||
|
||||
|
||||
[courier-auth]
|
||||
port = smtp,465,submission,imap,imaps,pop3,pop3s
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[postfix-sasl]
|
||||
filter = postfix[mode=auth]
|
||||
port = smtp,465,submission,imap,imaps,pop3,pop3s
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
|
||||
|
||||
[perdition]
|
||||
port = imap,imaps,pop3,pop3s
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[squirrelmail]
|
||||
port = smtp,465,submission,imap,imap2,imaps,pop3,pop3s,http,https,socks
|
||||
logpath = /var/lib/squirrelmail/prefs/squirrelmail_access_log
|
||||
|
||||
|
||||
[cyrus-imap]
|
||||
port = imap,imaps
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[uwimap-auth]
|
||||
port = imap,imaps
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[named-refused]
|
||||
port = domain,953
|
||||
logpath = /var/log/named/security.log
|
||||
|
||||
|
||||
[nsd]
|
||||
|
||||
port = 53
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/nsd.log
|
||||
|
||||
|
||||
|
||||
[asterisk]
|
||||
port = 5060,5061
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/asterisk/messages
|
||||
maxretry = 10
|
||||
|
||||
|
||||
[freeswitch]
|
||||
port = 5060,5061
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/freeswitch.log
|
||||
maxretry = 10
|
||||
|
||||
|
||||
[znc-adminlog]
|
||||
port = 6667
|
||||
logpath = /var/lib/znc/moddata/adminlog/znc.log
|
||||
|
||||
|
||||
[mysqld-auth]
|
||||
|
||||
port = 3306
|
||||
logpath = %(mysql_log)s
|
||||
backend = %(mysql_backend)s
|
||||
|
||||
|
||||
[mongodb-auth]
|
||||
port = 27017
|
||||
logpath = /var/log/mongodb/mongodb.log
|
||||
|
||||
|
||||
[recidive]
|
||||
|
||||
logpath = /var/log/fail2ban.log
|
||||
banaction = %(banaction_allports)s
|
||||
bantime = 1w
|
||||
findtime = 1d
|
||||
|
||||
[pam-generic]
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[xinetd-fail]
|
||||
|
||||
banaction = iptables-multiport-log
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[stunnel]
|
||||
|
||||
logpath = /var/log/stunnel4/stunnel.log
|
||||
|
||||
|
||||
[ejabberd-auth]
|
||||
|
||||
port = 5222
|
||||
logpath = /var/log/ejabberd/ejabberd.log
|
||||
|
||||
|
||||
[counter-strike]
|
||||
|
||||
logpath = /opt/cstrike/logs/L[0-9]*.log
|
||||
tcpport = 27030,27031,27032,27033,27034,27035,27036,27037,27038,27039
|
||||
udpport = 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, port="%(tcpport)s", protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, port="%(udpport)s", protocol="udp"]
|
||||
|
||||
[softethervpn]
|
||||
port = 500,4500
|
||||
protocol = udp
|
||||
logpath = /usr/local/vpnserver/security_log/*/sec.log
|
||||
|
||||
[gitlab]
|
||||
port = http,https
|
||||
logpath = /var/log/gitlab/gitlab-rails/application.log
|
||||
|
||||
[grafana]
|
||||
port = http,https
|
||||
logpath = /var/log/grafana/grafana.log
|
||||
|
||||
[bitwarden]
|
||||
port = http,https
|
||||
logpath = /home/*/bwdata/logs/identity/Identity/log.txt
|
||||
|
||||
[centreon]
|
||||
port = http,https
|
||||
logpath = /var/log/centreon/login.log
|
||||
|
||||
[nagios]
|
||||
|
||||
logpath = %(syslog_daemon)s ; nrpe.cfg may define a different log_facility
|
||||
backend = %(syslog_backend)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[oracleims]
|
||||
logpath = /opt/sun/comms/messaging64/log/mail.log_current
|
||||
banaction = %(banaction_allports)s
|
||||
|
||||
[directadmin]
|
||||
logpath = /var/log/directadmin/login.log
|
||||
port = 2222
|
||||
|
||||
[portsentry]
|
||||
logpath = /var/lib/portsentry/portsentry.history
|
||||
maxretry = 1
|
||||
|
||||
[pass2allow-ftp]
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
knocking_url = /knocking/
|
||||
filter = apache-pass[knocking_url="%(knocking_url)s"]
|
||||
logpath = %(apache_access_log)s
|
||||
blocktype = RETURN
|
||||
returntype = DROP
|
||||
action = %(action_)s[blocktype=%(blocktype)s, returntype=%(returntype)s,
|
||||
actionstart_on_demand=false, actionrepair_on_unban=true]
|
||||
bantime = 1h
|
||||
maxretry = 1
|
||||
findtime = 1
|
||||
|
||||
|
||||
[murmur]
|
||||
port = 64738
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/mumble-server/mumble-server.log
|
||||
|
||||
|
||||
[screensharingd]
|
||||
logpath = /var/log/system.log
|
||||
logencoding = utf-8
|
||||
|
||||
[haproxy-http-auth]
|
||||
logpath = /var/log/haproxy.log
|
||||
|
||||
[slapd]
|
||||
port = ldap,ldaps
|
||||
logpath = /var/log/slapd.log
|
||||
|
||||
[domino-smtp]
|
||||
port = smtp,ssmtp
|
||||
logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log
|
||||
|
||||
[phpmyadmin-syslog]
|
||||
port = http,https
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[zoneminder]
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
[traefik-auth]
|
||||
port = http,https
|
||||
logpath = /var/log/traefik/access.log
|
||||
@@ -0,0 +1,964 @@
|
||||
#
|
||||
# WARNING: heavily refactored in 0.9.0 release. Please review and
|
||||
# customize settings for your setup.
|
||||
#
|
||||
# Changes: in most of the cases you should not modify this
|
||||
# file, but provide customizations in jail.local file,
|
||||
# or separate .conf files under jail.d/ directory, e.g.:
|
||||
#
|
||||
# HOW TO ACTIVATE JAILS:
|
||||
#
|
||||
# YOU SHOULD NOT MODIFY THIS FILE.
|
||||
#
|
||||
# It will probably be overwritten or improved in a distribution update.
|
||||
#
|
||||
# Provide customizations in a jail.local file or a jail.d/customisation.local.
|
||||
# For example to change the default bantime for all jails and to enable the
|
||||
# ssh-iptables jail the following (uncommented) would appear in the .local file.
|
||||
# See man 5 jail.conf for details.
|
||||
#
|
||||
# [DEFAULT]
|
||||
# bantime = 1h
|
||||
#
|
||||
# [sshd]
|
||||
# enabled = true
|
||||
#
|
||||
# See jail.conf(5) man page for more information
|
||||
|
||||
|
||||
|
||||
# Comments: use '#' for comment lines and ';' (following a space) for inline comments
|
||||
|
||||
|
||||
[INCLUDES]
|
||||
|
||||
#before = paths-distro.conf
|
||||
before = paths-debian.conf
|
||||
|
||||
# The DEFAULT allows a global definition of the options. They can be overridden
|
||||
# in each jail afterwards.
|
||||
|
||||
[DEFAULT]
|
||||
|
||||
#
|
||||
# MISCELLANEOUS OPTIONS
|
||||
#
|
||||
|
||||
# "bantime.increment" allows to use database for searching of previously banned ip's to increase a
|
||||
# default ban time using special formula, default it is banTime * 1, 2, 4, 8, 16, 32...
|
||||
#bantime.increment = true
|
||||
|
||||
# "bantime.rndtime" is the max number of seconds using for mixing with random time
|
||||
# to prevent "clever" botnets calculate exact time IP can be unbanned again:
|
||||
#bantime.rndtime =
|
||||
|
||||
# "bantime.maxtime" is the max number of seconds using the ban time can reach (doesn't grow further)
|
||||
#bantime.maxtime =
|
||||
|
||||
# "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier,
|
||||
# default value of factor is 1 and with default value of formula, the ban time
|
||||
# grows by 1, 2, 4, 8, 16 ...
|
||||
#bantime.factor = 1
|
||||
|
||||
# "bantime.formula" used by default to calculate next value of ban time, default value below,
|
||||
# the same ban time growing will be reached by multipliers 1, 2, 4, 8, 16, 32...
|
||||
#bantime.formula = ban.Time * (1<<(ban.Count if ban.Count<20 else 20)) * banFactor
|
||||
#
|
||||
# more aggressive example of formula has the same values only for factor "2.0 / 2.885385" :
|
||||
#bantime.formula = ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)
|
||||
|
||||
# "bantime.multipliers" used to calculate next value of ban time instead of formula, coresponding
|
||||
# previously ban count and given "bantime.factor" (for multipliers default is 1);
|
||||
# following example grows ban time by 1, 2, 4, 8, 16 ... and if last ban count greater as multipliers count,
|
||||
# always used last multiplier (64 in example), for factor '1' and original ban time 600 - 10.6 hours
|
||||
#bantime.multipliers = 1 2 4 8 16 32 64
|
||||
# following example can be used for small initial ban time (bantime=60) - it grows more aggressive at begin,
|
||||
# for bantime=60 the multipliers are minutes and equal: 1 min, 5 min, 30 min, 1 hour, 5 hour, 12 hour, 1 day, 2 day
|
||||
#bantime.multipliers = 1 5 30 60 300 720 1440 2880
|
||||
|
||||
# "bantime.overalljails" (if true) specifies the search of IP in the database will be executed
|
||||
# cross over all jails, if false (dafault), only current jail of the ban IP will be searched
|
||||
#bantime.overalljails = false
|
||||
|
||||
# --------------------
|
||||
|
||||
# "ignoreself" specifies whether the local resp. own IP addresses should be ignored
|
||||
# (default is true). Fail2ban will not ban a host which matches such addresses.
|
||||
#ignoreself = true
|
||||
|
||||
# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
|
||||
# will not ban a host which matches an address in this list. Several addresses
|
||||
# can be defined using space (and/or comma) separator.
|
||||
#ignoreip = 127.0.0.1/8 ::1
|
||||
|
||||
# External command that will take an tagged arguments to ignore, e.g. <ip>,
|
||||
# and return true if the IP is to be ignored. False otherwise.
|
||||
#
|
||||
# ignorecommand = /path/to/command <ip>
|
||||
ignorecommand =
|
||||
|
||||
# "bantime" is the number of seconds that a host is banned.
|
||||
bantime = 10m
|
||||
|
||||
# A host is banned if it has generated "maxretry" during the last "findtime"
|
||||
# seconds.
|
||||
findtime = 10m
|
||||
|
||||
# "maxretry" is the number of failures before a host get banned.
|
||||
maxretry = 5
|
||||
|
||||
# "maxmatches" is the number of matches stored in ticket (resolvable via tag <matches> in actions).
|
||||
maxmatches = %(maxretry)s
|
||||
|
||||
# "backend" specifies the backend used to get files modification.
|
||||
# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
|
||||
# This option can be overridden in each jail as well.
|
||||
#
|
||||
# pyinotify: requires pyinotify (a file alteration monitor) to be installed.
|
||||
# If pyinotify is not installed, Fail2ban will use auto.
|
||||
# gamin: requires Gamin (a file alteration monitor) to be installed.
|
||||
# If Gamin is not installed, Fail2ban will use auto.
|
||||
# polling: uses a polling algorithm which does not require external libraries.
|
||||
# systemd: uses systemd python library to access the systemd journal.
|
||||
# Specifying "logpath" is not valid for this backend.
|
||||
# See "journalmatch" in the jails associated filter config
|
||||
# auto: will try to use the following backends, in order:
|
||||
# pyinotify, gamin, polling.
|
||||
#
|
||||
# Note: if systemd backend is chosen as the default but you enable a jail
|
||||
# for which logs are present only in its own log files, specify some other
|
||||
# backend for that jail (e.g. polling) and provide empty value for
|
||||
# journalmatch. See https://github.com/fail2ban/fail2ban/issues/959#issuecomment-74901200
|
||||
backend = systemd
|
||||
|
||||
# "usedns" specifies if jails should trust hostnames in logs,
|
||||
# warn when DNS lookups are performed, or ignore all hostnames in logs
|
||||
#
|
||||
# yes: if a hostname is encountered, a DNS lookup will be performed.
|
||||
# warn: if a hostname is encountered, a DNS lookup will be performed,
|
||||
# but it will be logged as a warning.
|
||||
# no: if a hostname is encountered, will not be used for banning,
|
||||
# but it will be logged as info.
|
||||
# raw: use raw value (no hostname), allow use it for no-host filters/actions (example user)
|
||||
usedns = warn
|
||||
|
||||
# "logencoding" specifies the encoding of the log files handled by the jail
|
||||
# This is used to decode the lines from the log file.
|
||||
# Typical examples: "ascii", "utf-8"
|
||||
#
|
||||
# auto: will use the system locale setting
|
||||
logencoding = auto
|
||||
|
||||
# "enabled" enables the jails.
|
||||
# By default all jails are disabled, and it should stay this way.
|
||||
# Enable only relevant to your setup jails in your .local or jail.d/*.conf
|
||||
#
|
||||
# true: jail will be enabled and log files will get monitored for changes
|
||||
# false: jail is not enabled
|
||||
enabled = false
|
||||
|
||||
|
||||
# "mode" defines the mode of the filter (see corresponding filter implementation for more info).
|
||||
mode = normal
|
||||
|
||||
# "filter" defines the filter to use by the jail.
|
||||
# By default jails have names matching their filter name
|
||||
#
|
||||
filter = %(__name__)s[mode=%(mode)s]
|
||||
|
||||
|
||||
#
|
||||
# ACTIONS
|
||||
#
|
||||
|
||||
# Some options used for actions
|
||||
|
||||
# Destination email address used solely for the interpolations in
|
||||
# jail.{conf,local,d/*} configuration files.
|
||||
destemail = root@localhost
|
||||
|
||||
# Sender email address used solely for some actions
|
||||
sender = root@<fq-hostname>
|
||||
|
||||
# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
|
||||
# mailing. Change mta configuration parameter to mail if you want to
|
||||
# revert to conventional 'mail'.
|
||||
mta = sendmail
|
||||
|
||||
# Default protocol
|
||||
protocol = tcp
|
||||
|
||||
# Specify chain where jumps would need to be added in ban-actions expecting parameter chain
|
||||
chain = <known/chain>
|
||||
|
||||
# Ports to be banned
|
||||
# Usually should be overridden in a particular jail
|
||||
port = 0:65535
|
||||
|
||||
# Format of user-agent https://tools.ietf.org/html/rfc7231#section-5.5.3
|
||||
fail2ban_agent = Fail2Ban/%(fail2ban_version)s
|
||||
|
||||
#
|
||||
# Action shortcuts. To be used to define action parameter
|
||||
|
||||
# Default banning action (e.g. iptables, iptables-new,
|
||||
# iptables-multiport, shorewall, etc) It is used to define
|
||||
# action_* variables. Can be overridden globally or per
|
||||
# section within jail.local file
|
||||
banaction = iptables-multiport
|
||||
banaction_allports = iptables-allports
|
||||
|
||||
# The simplest action to take: ban only
|
||||
action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
# ban & send an e-mail with whois report to the destemail.
|
||||
action_mw = %(action_)s
|
||||
%(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
|
||||
|
||||
# ban & send an e-mail with whois report and relevant log lines
|
||||
# to the destemail.
|
||||
action_mwl = %(action_)s
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
# See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
|
||||
#
|
||||
# ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines
|
||||
# to the destemail.
|
||||
action_xarf = %(action_)s
|
||||
xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]
|
||||
|
||||
# ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
|
||||
# to the destemail.
|
||||
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
|
||||
%(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
|
||||
|
||||
# Report block via blocklist.de fail2ban reporting service API
|
||||
#
|
||||
# See the IMPORTANT note in action.d/blocklist_de.conf for when to use this action.
|
||||
# Specify expected parameters in file action.d/blocklist_de.local or if the interpolation
|
||||
# `action_blocklist_de` used for the action, set value of `blocklist_de_apikey`
|
||||
# in your `jail.local` globally (section [DEFAULT]) or per specific jail section (resp. in
|
||||
# corresponding jail.d/my-jail.local file).
|
||||
#
|
||||
action_blocklist_de = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
# Report ban via badips.com, and use as blacklist
|
||||
#
|
||||
# See BadIPsAction docstring in config/action.d/badips.py for
|
||||
# documentation for this action.
|
||||
#
|
||||
# NOTE: This action relies on banaction being present on start and therefore
|
||||
# should be last action defined for a jail.
|
||||
#
|
||||
action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]
|
||||
#
|
||||
# Report ban via badips.com (uses action.d/badips.conf for reporting only)
|
||||
#
|
||||
action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]
|
||||
|
||||
# Report ban via abuseipdb.com.
|
||||
#
|
||||
# See action.d/abuseipdb.conf for usage example and details.
|
||||
#
|
||||
action_abuseipdb = abuseipdb
|
||||
|
||||
# Choose default action. To change, just override value of 'action' with the
|
||||
# interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
|
||||
# globally (section [DEFAULT]) or per specific section
|
||||
action = %(action_)s
|
||||
|
||||
|
||||
#
|
||||
# JAILS
|
||||
#
|
||||
|
||||
#
|
||||
# SSH servers
|
||||
#
|
||||
|
||||
[sshd]
|
||||
|
||||
# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
|
||||
# normal (default), ddos, extra or aggressive (combines all).
|
||||
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
|
||||
#mode = normal
|
||||
port = ssh
|
||||
logpath = %(sshd_log)s
|
||||
backend = %(sshd_backend)s
|
||||
|
||||
|
||||
[dropbear]
|
||||
|
||||
port = ssh
|
||||
logpath = %(dropbear_log)s
|
||||
backend = %(dropbear_backend)s
|
||||
|
||||
|
||||
[selinux-ssh]
|
||||
|
||||
port = ssh
|
||||
logpath = %(auditd_log)s
|
||||
|
||||
|
||||
#
|
||||
# HTTP servers
|
||||
#
|
||||
|
||||
[apache-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
|
||||
[apache-badbots]
|
||||
# Ban hosts which agent identifies spammer robots crawling the web
|
||||
# for email addresses. The mail outputs are buffered.
|
||||
port = http,https
|
||||
logpath = %(apache_access_log)s
|
||||
bantime = 48h
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[apache-noscript]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
|
||||
[apache-overflows]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-nohome]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-botsearch]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-fakegooglebot]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_access_log)s
|
||||
maxretry = 1
|
||||
ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot <ip>
|
||||
|
||||
|
||||
[apache-modsecurity]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
[apache-shellshock]
|
||||
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[openhab-auth]
|
||||
|
||||
filter = openhab
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = /opt/openhab/logs/request.log
|
||||
|
||||
|
||||
[nginx-http-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
|
||||
# To use 'nginx-limit-req' jail you should have `ngx_http_limit_req_module`
|
||||
# and define `limit_req` and `limit_req_zone` as described in nginx documentation
|
||||
# http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
|
||||
# or for example see in 'config/filter.d/nginx-limit-req.conf'
|
||||
[nginx-limit-req]
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
|
||||
[nginx-botsearch]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_error_log)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
# Ban attackers that try to use PHP's URL-fopen() functionality
|
||||
# through GET/POST variables. - Experimental, with more than a year
|
||||
# of usage in production environments.
|
||||
|
||||
[php-url-fopen]
|
||||
|
||||
port = http,https
|
||||
logpath = %(nginx_access_log)s
|
||||
%(apache_access_log)s
|
||||
|
||||
|
||||
[suhosin]
|
||||
|
||||
port = http,https
|
||||
logpath = %(suhosin_log)s
|
||||
|
||||
|
||||
[lighttpd-auth]
|
||||
# Same as above for Apache's mod_auth
|
||||
# It catches wrong authentifications
|
||||
port = http,https
|
||||
logpath = %(lighttpd_error_log)s
|
||||
|
||||
|
||||
#
|
||||
# Webmail and groupware servers
|
||||
#
|
||||
|
||||
[roundcube-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(roundcube_errors_log)s
|
||||
# Use following line in your jail.local if roundcube logs to journal.
|
||||
#backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[openwebmail]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/openwebmail.log
|
||||
|
||||
|
||||
[horde]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/horde/horde.log
|
||||
|
||||
|
||||
[groupoffice]
|
||||
|
||||
port = http,https
|
||||
logpath = /home/groupoffice/log/info.log
|
||||
|
||||
|
||||
[sogo-auth]
|
||||
# Monitor SOGo groupware server
|
||||
# without proxy this would be:
|
||||
# port = 20000
|
||||
port = http,https
|
||||
logpath = /var/log/sogo/sogo.log
|
||||
|
||||
|
||||
[tine20]
|
||||
|
||||
logpath = /var/log/tine20/tine20.log
|
||||
port = http,https
|
||||
|
||||
|
||||
#
|
||||
# Web Applications
|
||||
#
|
||||
#
|
||||
|
||||
[drupal-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
[guacamole]
|
||||
|
||||
port = http,https
|
||||
logpath = /var/log/tomcat*/catalina.out
|
||||
#logpath = /var/log/guacamole.log
|
||||
|
||||
[monit]
|
||||
#Ban clients brute-forcing the monit gui login
|
||||
port = 2812
|
||||
logpath = /var/log/monit
|
||||
/var/log/monit.log
|
||||
|
||||
|
||||
[webmin-auth]
|
||||
|
||||
port = 10000
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[froxlor-auth]
|
||||
|
||||
port = http,https
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
#
|
||||
# HTTP Proxy servers
|
||||
#
|
||||
#
|
||||
|
||||
[squid]
|
||||
|
||||
port = 80,443,3128,8080
|
||||
logpath = /var/log/squid/access.log
|
||||
|
||||
|
||||
[3proxy]
|
||||
|
||||
port = 3128
|
||||
logpath = /var/log/3proxy.log
|
||||
|
||||
|
||||
#
|
||||
# FTP servers
|
||||
#
|
||||
|
||||
|
||||
[proftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(proftpd_log)s
|
||||
backend = %(proftpd_backend)s
|
||||
|
||||
|
||||
[pure-ftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(pureftpd_log)s
|
||||
backend = %(pureftpd_backend)s
|
||||
|
||||
|
||||
[gssftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[wuftpd]
|
||||
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(wuftpd_log)s
|
||||
backend = %(wuftpd_backend)s
|
||||
|
||||
|
||||
[vsftpd]
|
||||
# or overwrite it in jails.local to be
|
||||
# logpath = %(syslog_authpriv)s
|
||||
# if you want to rely on PAM failed login attempts
|
||||
# vsftpd's failregex should match both of those formats
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
logpath = %(vsftpd_log)s
|
||||
|
||||
|
||||
#
|
||||
# Mail servers
|
||||
#
|
||||
|
||||
# ASSP SMTP Proxy Jail
|
||||
[assp]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = /root/path/to/assp/logs/maillog.txt
|
||||
|
||||
|
||||
[courier-smtp]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[postfix]
|
||||
# To use another modes set filter parameter "mode" in jail.local:
|
||||
mode = more
|
||||
port = smtp,465,submission
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
|
||||
|
||||
[postfix-rbl]
|
||||
|
||||
filter = postfix[mode=rbl]
|
||||
port = smtp,465,submission
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[sendmail-auth]
|
||||
|
||||
port = submission,465,smtp
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[sendmail-reject]
|
||||
# To use more aggressive modes set filter parameter "mode" in jail.local:
|
||||
# normal (default), extra or aggressive
|
||||
# See "tests/files/logs/sendmail-reject" or "filter.d/sendmail-reject.conf" for usage example and details.
|
||||
#mode = normal
|
||||
port = smtp,465,submission
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[qmail-rbl]
|
||||
|
||||
filter = qmail
|
||||
port = smtp,465,submission
|
||||
logpath = /service/qmail/log/main/current
|
||||
|
||||
|
||||
# dovecot defaults to logging to the mail syslog facility
|
||||
# but can be set by syslog_facility in the dovecot configuration.
|
||||
[dovecot]
|
||||
|
||||
port = pop3,pop3s,imap,imaps,submission,465,sieve
|
||||
logpath = %(dovecot_log)s
|
||||
backend = %(dovecot_backend)s
|
||||
|
||||
|
||||
[sieve]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(dovecot_log)s
|
||||
backend = %(dovecot_backend)s
|
||||
|
||||
|
||||
[solid-pop3d]
|
||||
|
||||
port = pop3,pop3s
|
||||
logpath = %(solidpop3d_log)s
|
||||
|
||||
|
||||
[exim]
|
||||
# see filter.d/exim.conf for further modes supported from filter:
|
||||
#mode = normal
|
||||
port = smtp,465,submission
|
||||
logpath = %(exim_main_log)s
|
||||
|
||||
|
||||
[exim-spam]
|
||||
|
||||
port = smtp,465,submission
|
||||
logpath = %(exim_main_log)s
|
||||
|
||||
|
||||
[kerio]
|
||||
|
||||
port = imap,smtp,imaps,465
|
||||
logpath = /opt/kerio/mailserver/store/logs/security.log
|
||||
|
||||
|
||||
#
|
||||
# Mail servers authenticators: might be used for smtp,ftp,imap servers, so
|
||||
# all relevant ports get banned
|
||||
#
|
||||
|
||||
[courier-auth]
|
||||
|
||||
port = smtp,465,submission,imap,imaps,pop3,pop3s
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[postfix-sasl]
|
||||
|
||||
filter = postfix[mode=auth]
|
||||
port = smtp,465,submission,imap,imaps,pop3,pop3s
|
||||
# You might consider monitoring /var/log/mail.warn instead if you are
|
||||
# running postfix since it would provide the same log lines at the
|
||||
# "warn" level but overall at the smaller filesize.
|
||||
logpath = %(postfix_log)s
|
||||
backend = %(postfix_backend)s
|
||||
|
||||
|
||||
[perdition]
|
||||
|
||||
port = imap,imaps,pop3,pop3s
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[squirrelmail]
|
||||
|
||||
port = smtp,465,submission,imap,imap2,imaps,pop3,pop3s,http,https,socks
|
||||
logpath = /var/lib/squirrelmail/prefs/squirrelmail_access_log
|
||||
|
||||
|
||||
[cyrus-imap]
|
||||
|
||||
port = imap,imaps
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[uwimap-auth]
|
||||
|
||||
port = imap,imaps
|
||||
logpath = %(syslog_mail)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# DNS servers
|
||||
#
|
||||
|
||||
|
||||
# !!! WARNING !!!
|
||||
# Since UDP is connection-less protocol, spoofing of IP and imitation
|
||||
# of illegal actions is way too simple. Thus enabling of this filter
|
||||
# might provide an easy way for implementing a DoS against a chosen
|
||||
# victim. See
|
||||
# http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
|
||||
# Please DO NOT USE this jail unless you know what you are doing.
|
||||
#
|
||||
# IMPORTANT: see filter.d/named-refused for instructions to enable logging
|
||||
# This jail blocks UDP traffic for DNS requests.
|
||||
# [named-refused-udp]
|
||||
#
|
||||
# filter = named-refused
|
||||
# port = domain,953
|
||||
# protocol = udp
|
||||
# logpath = /var/log/named/security.log
|
||||
|
||||
# IMPORTANT: see filter.d/named-refused for instructions to enable logging
|
||||
# This jail blocks TCP traffic for DNS requests.
|
||||
|
||||
[named-refused]
|
||||
|
||||
port = domain,953
|
||||
logpath = /var/log/named/security.log
|
||||
|
||||
|
||||
[nsd]
|
||||
|
||||
port = 53
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/nsd.log
|
||||
|
||||
|
||||
#
|
||||
# Miscellaneous
|
||||
#
|
||||
|
||||
[asterisk]
|
||||
|
||||
port = 5060,5061
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/asterisk/messages
|
||||
maxretry = 10
|
||||
|
||||
|
||||
[freeswitch]
|
||||
|
||||
port = 5060,5061
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/freeswitch.log
|
||||
maxretry = 10
|
||||
|
||||
|
||||
# enable adminlog; it will log to a file inside znc's directory by default.
|
||||
[znc-adminlog]
|
||||
|
||||
port = 6667
|
||||
logpath = /var/lib/znc/moddata/adminlog/znc.log
|
||||
|
||||
|
||||
# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld] or
|
||||
# equivalent section:
|
||||
# log-warnings = 2
|
||||
#
|
||||
# for syslog (daemon facility)
|
||||
# [mysqld_safe]
|
||||
# syslog
|
||||
#
|
||||
# for own logfile
|
||||
# [mysqld]
|
||||
# log-error=/var/log/mysqld.log
|
||||
[mysqld-auth]
|
||||
|
||||
port = 3306
|
||||
logpath = %(mysql_log)s
|
||||
backend = %(mysql_backend)s
|
||||
|
||||
|
||||
# Log wrong MongoDB auth (for details see filter 'filter.d/mongodb-auth.conf')
|
||||
[mongodb-auth]
|
||||
# change port when running with "--shardsvr" or "--configsvr" runtime operation
|
||||
port = 27017
|
||||
logpath = /var/log/mongodb/mongodb.log
|
||||
|
||||
|
||||
# Jail for more extended banning of persistent abusers
|
||||
# !!! WARNINGS !!!
|
||||
# 1. Make sure that your loglevel specified in fail2ban.conf/.local
|
||||
# is not at DEBUG level -- which might then cause fail2ban to fall into
|
||||
# an infinite loop constantly feeding itself with non-informative lines
|
||||
# 2. Increase dbpurgeage defined in fail2ban.conf to e.g. 648000 (7.5 days)
|
||||
# to maintain entries for failed logins for sufficient amount of time
|
||||
[recidive]
|
||||
|
||||
logpath = /var/log/fail2ban.log
|
||||
banaction = %(banaction_allports)s
|
||||
bantime = 1w
|
||||
findtime = 1d
|
||||
|
||||
|
||||
# Generic filter for PAM. Has to be used with action which bans all
|
||||
# ports such as iptables-allports, shorewall
|
||||
|
||||
[pam-generic]
|
||||
# pam-generic filter can be customized to monitor specific subset of 'tty's
|
||||
banaction = %(banaction_allports)s
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[xinetd-fail]
|
||||
|
||||
banaction = iptables-multiport-log
|
||||
logpath = %(syslog_daemon)s
|
||||
backend = %(syslog_backend)s
|
||||
maxretry = 2
|
||||
|
||||
|
||||
# stunnel - need to set port for this
|
||||
[stunnel]
|
||||
|
||||
logpath = /var/log/stunnel4/stunnel.log
|
||||
|
||||
|
||||
[ejabberd-auth]
|
||||
|
||||
port = 5222
|
||||
logpath = /var/log/ejabberd/ejabberd.log
|
||||
|
||||
|
||||
[counter-strike]
|
||||
|
||||
logpath = /opt/cstrike/logs/L[0-9]*.log
|
||||
tcpport = 27030,27031,27032,27033,27034,27035,27036,27037,27038,27039
|
||||
udpport = 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, port="%(tcpport)s", protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, port="%(udpport)s", protocol="udp"]
|
||||
|
||||
[softethervpn]
|
||||
port = 500,4500
|
||||
protocol = udp
|
||||
logpath = /usr/local/vpnserver/security_log/*/sec.log
|
||||
|
||||
[gitlab]
|
||||
port = http,https
|
||||
logpath = /var/log/gitlab/gitlab-rails/application.log
|
||||
|
||||
[grafana]
|
||||
port = http,https
|
||||
logpath = /var/log/grafana/grafana.log
|
||||
|
||||
[bitwarden]
|
||||
port = http,https
|
||||
logpath = /home/*/bwdata/logs/identity/Identity/log.txt
|
||||
|
||||
[centreon]
|
||||
port = http,https
|
||||
logpath = /var/log/centreon/login.log
|
||||
|
||||
# consider low maxretry and a long bantime
|
||||
# nobody except your own Nagios server should ever probe nrpe
|
||||
[nagios]
|
||||
|
||||
logpath = %(syslog_daemon)s ; nrpe.cfg may define a different log_facility
|
||||
backend = %(syslog_backend)s
|
||||
maxretry = 1
|
||||
|
||||
|
||||
[oracleims]
|
||||
# see "oracleims" filter file for configuration requirement for Oracle IMS v6 and above
|
||||
logpath = /opt/sun/comms/messaging64/log/mail.log_current
|
||||
banaction = %(banaction_allports)s
|
||||
|
||||
[directadmin]
|
||||
logpath = /var/log/directadmin/login.log
|
||||
port = 2222
|
||||
|
||||
[portsentry]
|
||||
logpath = /var/lib/portsentry/portsentry.history
|
||||
maxretry = 1
|
||||
|
||||
[pass2allow-ftp]
|
||||
# this pass2allow example allows FTP traffic after successful HTTP authentication
|
||||
port = ftp,ftp-data,ftps,ftps-data
|
||||
# knocking_url variable must be overridden to some secret value in jail.local
|
||||
knocking_url = /knocking/
|
||||
filter = apache-pass[knocking_url="%(knocking_url)s"]
|
||||
# access log of the website with HTTP auth
|
||||
logpath = %(apache_access_log)s
|
||||
blocktype = RETURN
|
||||
returntype = DROP
|
||||
action = %(action_)s[blocktype=%(blocktype)s, returntype=%(returntype)s,
|
||||
actionstart_on_demand=false, actionrepair_on_unban=true]
|
||||
bantime = 1h
|
||||
maxretry = 1
|
||||
findtime = 1
|
||||
|
||||
|
||||
[murmur]
|
||||
# AKA mumble-server
|
||||
port = 64738
|
||||
action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
|
||||
%(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
|
||||
logpath = /var/log/mumble-server/mumble-server.log
|
||||
|
||||
|
||||
[screensharingd]
|
||||
# For Mac OS Screen Sharing Service (VNC)
|
||||
logpath = /var/log/system.log
|
||||
logencoding = utf-8
|
||||
|
||||
[haproxy-http-auth]
|
||||
# HAProxy by default doesn't log to file you'll need to set it up to forward
|
||||
# logs to a syslog server which would then write them to disk.
|
||||
# See "haproxy-http-auth" filter for a brief cautionary note when setting
|
||||
# maxretry and findtime.
|
||||
logpath = /var/log/haproxy.log
|
||||
|
||||
[slapd]
|
||||
port = ldap,ldaps
|
||||
logpath = /var/log/slapd.log
|
||||
|
||||
[domino-smtp]
|
||||
port = smtp,ssmtp
|
||||
logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log
|
||||
|
||||
[phpmyadmin-syslog]
|
||||
port = http,https
|
||||
logpath = %(syslog_authpriv)s
|
||||
backend = %(syslog_backend)s
|
||||
|
||||
|
||||
[zoneminder]
|
||||
# Zoneminder HTTP/HTTPS web interface auth
|
||||
# Logs auth failures to apache2 error log
|
||||
port = http,https
|
||||
logpath = %(apache_error_log)s
|
||||
|
||||
[traefik-auth]
|
||||
# to use 'traefik-auth' filter you have to configure your Traefik instance,
|
||||
# see `filter.d/traefik-auth.conf` for details and service example.
|
||||
port = http,https
|
||||
logpath = /var/log/traefik/access.log
|
||||
@@ -16,6 +16,10 @@ fi
|
||||
git config --global credential.helper store
|
||||
git config --global pull.rebase false
|
||||
|
||||
if [ ! -d $GIT_PROJECT_DIR ];then
|
||||
git config --global --add safe.directory $GIT_PROJECT_DIR
|
||||
fi
|
||||
|
||||
# echo $GIT_PROJECT_DIR
|
||||
if [ ! -d $GIT_PROJECT_DIR ];then
|
||||
mkdir -p $GIT_USER_DIR && cd $GIT_USER_DIR
|
||||
@@ -24,6 +28,8 @@ fi
|
||||
|
||||
unset GIT_DIR
|
||||
|
||||
|
||||
|
||||
cd $GIT_PROJECT_DIR && git pull
|
||||
|
||||
# func 2
|
||||
|
||||
+10
-3
@@ -5,7 +5,7 @@ import time
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
|
||||
import subprocess
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
@@ -138,6 +138,8 @@ def initDreplace():
|
||||
git_dir = mw.getServerDir() + '/git'
|
||||
if not os.path.exists(git_dir):
|
||||
mw.execShell('mkdir -p ' + git_dir)
|
||||
mw.execShell('chown -R www:www ' + git_dir)
|
||||
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
@@ -762,8 +764,13 @@ def projectScriptRun():
|
||||
if not os.path.exists(commit_sh):
|
||||
return mw.returnJson(False, '脚本文件不存在!')
|
||||
|
||||
mw.execShell(script_run)
|
||||
mw.execShell('chown -R www:www ' + commit_log)
|
||||
repo_dir = mw.getServerDir()+'/git/'+ args['name']
|
||||
|
||||
# mw.execShell(script_run)
|
||||
subprocess.Popen(script_run, stdout=subprocess.PIPE, shell=True,
|
||||
bufsize=4096, stderr=subprocess.PIPE)
|
||||
subprocess.Popen('chown -R www:www ' + repo_dir, stdout=subprocess.PIPE, shell=True,
|
||||
bufsize=4096, stderr=subprocess.PIPE)
|
||||
return mw.returnJson(True, '脚本文件执行成功,观察日志!')
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"ps": "Gitea是一个开源社区驱动的轻量级代码托管解决方案。",
|
||||
"name": "gitea",
|
||||
"title": "Gitea",
|
||||
"versions": ["1.17.2","1.18.5"],
|
||||
"versions": ["1.17.2","1.18.5","1.22.1"],
|
||||
"tip": "soft",
|
||||
"install_pre_inspection":false,
|
||||
"uninstall_pre_inspection":true,
|
||||
|
||||
@@ -62,7 +62,7 @@ Install_App()
|
||||
fi
|
||||
fi
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
echo '正在安装脚本文件...'
|
||||
version=$1
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ Install_App()
|
||||
cd ${rootPath} && python3 plugins/gitea/index.py initd_install
|
||||
fi
|
||||
|
||||
echo 'install success' > $install_tmp
|
||||
echo 'install success'
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,6 @@
|
||||
# gorse
|
||||
推荐系统
|
||||
|
||||
|
||||
# 脚本安装
|
||||
cd /www/server/mdserver-web/plugins && rm -rf gorse && git clone https://github.com/mw-plugin/gorse && cd gorse && rm -rf .git && cd /www/server/mdserver-web/plugins/gorse && bash install.sh install 0.4.15
|
||||
@@ -0,0 +1,92 @@
|
||||
[database]
|
||||
cache_store = "{$CONFIG_REDIS}"
|
||||
data_store = "mongodb://127.0.0.1:27017/gorse"
|
||||
#data_store = "mysql://gorse:gorse@tcp(127.0.0.1:33206)/gorse"
|
||||
|
||||
|
||||
table_prefix = "gorse_"
|
||||
cache_table_prefix = "gorse_"
|
||||
data_table_prefix = "gorse_"
|
||||
|
||||
[master]
|
||||
port = 8086
|
||||
host = "0.0.0.0"
|
||||
http_port = 8088
|
||||
http_host = "0.0.0.0"
|
||||
http_cors_domains = []
|
||||
http_cors_methods = []
|
||||
n_jobs = 1
|
||||
meta_timeout = "10s"
|
||||
dashboard_user_name = "{$CONFIG_ADMIN}"
|
||||
dashboard_password = "{$CONFIG_PASS}"
|
||||
admin_api_key = ""
|
||||
|
||||
[server]
|
||||
default_n = 10
|
||||
api_key = ""
|
||||
clock_error = "5s"
|
||||
auto_insert_user = true
|
||||
auto_insert_item = true
|
||||
cache_expire = "10s"
|
||||
|
||||
[recommend]
|
||||
cache_size = 100
|
||||
cache_expire = "72h"
|
||||
|
||||
[recommend.data_source]
|
||||
positive_feedback_types = ["star","like"]
|
||||
read_feedback_types = ["read"]
|
||||
positive_feedback_ttl = 0
|
||||
item_ttl = 0
|
||||
|
||||
[recommend.popular]
|
||||
popular_window = "720h"
|
||||
|
||||
[recommend.user_neighbors]
|
||||
neighbor_type = "similar"
|
||||
enable_index = true
|
||||
index_recall = 0.8
|
||||
index_fit_epoch = 3
|
||||
|
||||
[recommend.item_neighbors]
|
||||
neighbor_type = "similar"
|
||||
enable_index = true
|
||||
index_recall = 0.8
|
||||
index_fit_epoch = 3
|
||||
|
||||
[recommend.collaborative]
|
||||
enable_index = true
|
||||
index_recall = 0.9
|
||||
index_fit_epoch = 3
|
||||
model_fit_period = "60m"
|
||||
model_search_period = "360m"
|
||||
model_search_epoch = 100
|
||||
model_search_trials = 10
|
||||
enable_model_size_search = false
|
||||
|
||||
[recommend.replacement]
|
||||
enable_replacement = false
|
||||
positive_replacement_decay = 0.8
|
||||
read_replacement_decay = 0.6
|
||||
|
||||
[recommend.offline]
|
||||
check_recommend_period = "1m"
|
||||
refresh_recommend_period = "24h"
|
||||
enable_latest_recommend = true
|
||||
enable_popular_recommend = false
|
||||
enable_user_based_recommend = true
|
||||
enable_item_based_recommend = false
|
||||
enable_collaborative_recommend = true
|
||||
enable_click_through_prediction = true
|
||||
explore_recommend = { popular = 0.1, latest = 0.2 }
|
||||
|
||||
[recommend.online]
|
||||
fallback_recommend = ["item_based", "latest"]
|
||||
num_feedback_fallback_item_based = 10
|
||||
|
||||
[tracing]
|
||||
enable_tracing = false
|
||||
exporter = "jaeger"
|
||||
collector_endpoint = "http://localhost:14268/api/traces"
|
||||
sampler = "always"
|
||||
ratio = 1
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
Executable
+30
@@ -0,0 +1,30 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('gorse');">服务</p>
|
||||
<p onclick="pluginInitD('gorse');">自启动</p>
|
||||
<p onclick="pluginConfigTpl('gorse',$('.plugin_version').attr('version'));">配置修改</p>
|
||||
<p onclick="pluginLogs('gorse','','run_log');">运行日志</p>
|
||||
<p onclick="gorseReadme();">相关说明</p>
|
||||
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con" style="height: 520px; overflow: auto;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=gorse&f=js/gorse.js", function(){
|
||||
pluginService('gorse', $('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+342
@@ -0,0 +1,342 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'gorse'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return '/tmp/' + getPluginName()
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
return '/etc/rc.d/' + getPluginName()
|
||||
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getConf():
|
||||
path = getServerDir() + "/gorse.toml"
|
||||
return path
|
||||
|
||||
|
||||
def getConfTpl():
|
||||
path = getPluginDir() + "/config/gorse.toml"
|
||||
return path
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
return path
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[3:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':',1)
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':',1)
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
def configTpl():
|
||||
path = getPluginDir() + '/tpl'
|
||||
pathFile = os.listdir(path)
|
||||
tmp = []
|
||||
for one in pathFile:
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
return mw.getJson(tmp)
|
||||
|
||||
|
||||
def readConfigTpl():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
content = mw.readFile(args['file'])
|
||||
content = contentReplace(content)
|
||||
return mw.returnJson(True, 'ok', content)
|
||||
|
||||
def getPidFile():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = r'pidfile\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def status():
|
||||
# pid_file = getPidFile()
|
||||
# if not os.path.exists(pid_file):
|
||||
# return 'stop'
|
||||
|
||||
cmd = "ps aux|grep gorse |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'"
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def initRedisConf():
|
||||
requirepass = ""
|
||||
conf = mw.getServerDir() + '/redis/redis.conf'
|
||||
content = mw.readFile(conf)
|
||||
rep = r"^(requirepass" + r')\s*([.0-9A-Za-z_& ~]+)'
|
||||
tmp = re.search(rep, content, re.M)
|
||||
if tmp:
|
||||
requirepass = tmp.groups()[1]
|
||||
|
||||
port = "6379"
|
||||
rep = r"^(port)\s*([.0-9A-Za-z_& ~]+)"
|
||||
tmp = re.search(rep, content, re.M)
|
||||
if tmp:
|
||||
port = tmp.groups()[1]
|
||||
|
||||
return 'redis://:'+requirepass+'@127.0.0.1:'+port+'/3'
|
||||
|
||||
def contentReplace(content):
|
||||
service_path = mw.getServerDir()
|
||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$CONFIG_ADMIN}', mw.getRandomString(6))
|
||||
content = content.replace('{$CONFIG_PASS}', mw.getRandomString(10))
|
||||
content = content.replace('{$CONFIG_REDIS}', initRedisConf())
|
||||
return content
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
mw.execShell("mkdir -p " + initD_path)
|
||||
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
|
||||
# initd replace
|
||||
if not os.path.exists(file_bin):
|
||||
content = mw.readFile(file_tpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(file_bin, content)
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
# log
|
||||
dataLog = getServerDir() + '/data'
|
||||
if not os.path.exists(dataLog):
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
# config replace
|
||||
dst_conf = getServerDir() + '/gorse.toml'
|
||||
dst_conf_init = getServerDir() + '/init.pl'
|
||||
if not os.path.exists(dst_conf_init):
|
||||
content = mw.readFile(getConfTpl())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(dst_conf, content)
|
||||
mw.writeFile(dst_conf_init, 'ok')
|
||||
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
systemService = systemDir + '/' + getPluginName() + '.service'
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
|
||||
service_path = mw.getServerDir()
|
||||
content = mw.readFile(systemServiceTpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(systemService, content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def gorseOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
# print(file)
|
||||
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
if current_os.startswith("freebsd"):
|
||||
data = mw.execShell('service ' + getPluginName() + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def start():
|
||||
return gorseOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return gorseOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = gorseOp('restart')
|
||||
log_file = runLog()
|
||||
mw.execShell("echo '' > " + log_file)
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
return gorseOp('reload')
|
||||
|
||||
|
||||
def getPort():
|
||||
conf = getServerDir() + '/gorse.conf'
|
||||
content = mw.readFile(conf)
|
||||
|
||||
rep = "^(" + 'port' + ')\s*([.0-9A-Za-z_& ~]+)'
|
||||
tmp = re.search(rep, content, re.M)
|
||||
if tmp:
|
||||
return tmp.groups()[1]
|
||||
|
||||
return '6379'
|
||||
|
||||
|
||||
def initdStatus():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
|
||||
shell_cmd = 'systemctl status ' + getPluginName() + ' | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
if data[0] == '':
|
||||
return 'fail'
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
# freebsd initd install
|
||||
if current_os.startswith('freebsd'):
|
||||
import shutil
|
||||
source_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(source_bin, initd_bin)
|
||||
mw.execShell('chmod +x ' + initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="YES"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl enable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="NO"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl disable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def runLog():
|
||||
return getServerDir() + '/logs.pl'
|
||||
|
||||
def installPreInspection():
|
||||
redis_path = mw.getServerDir() + "/redis"
|
||||
if not os.path.exists(redis_path):
|
||||
return "默认需要安装Redis"
|
||||
|
||||
mongodb_path = mw.getServerDir() + "/mongodb"
|
||||
if not os.path.exists(mongodb_path):
|
||||
return "默认需要安装MongoDB"
|
||||
return 'ok'
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
elif func == 'initd_status':
|
||||
print(initdStatus())
|
||||
elif func == 'initd_install':
|
||||
print(initdInstall())
|
||||
elif func == 'initd_uninstall':
|
||||
print(initdUinstall())
|
||||
elif func == 'install_pre_inspection':
|
||||
print(installPreInspection())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'config_tpl':
|
||||
print(configTpl())
|
||||
elif func == 'read_config_tpl':
|
||||
print(readConfigTpl())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "一款高效简单的推荐系统【单机】",
|
||||
"name": "gorse",
|
||||
"title": "Gorse",
|
||||
"shell": "install.sh",
|
||||
"versions":["0.4.15"],
|
||||
"tip": "soft",
|
||||
"install_pre_inspection":true,
|
||||
"checks": "server/gorse",
|
||||
"path": "server/gorse",
|
||||
"display": 1,
|
||||
"author": "midoks",
|
||||
"date": "2024-06-12",
|
||||
"home": "https://gorse.io/zh/docs/master/deploy/binary.html",
|
||||
"type": 0,
|
||||
"pid": "5"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Gorse, an open source recommender system service written in Go.
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
ExecStart={$SERVER_PATH}/gorse/bin/gorse-in-one -c {$SERVER_PATH}/gorse/gorse.toml \
|
||||
--log-path {$SERVER_PATH}/gorse/gorse.log \
|
||||
--cache-path {$SERVER_PATH}/gorse/data/cache.data
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
# chkconfig: 2345 55 25
|
||||
# description: Gorse Service
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: Gorse
|
||||
# Required-Start: $all
|
||||
# Required-Stop: $all
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: starts Gorse
|
||||
# Description: starts the MDW-Web
|
||||
### END INIT INFO
|
||||
|
||||
# Simple Gorse init.d script conceived to work on Linux systems
|
||||
# as it does use of the /proc filesystem.
|
||||
|
||||
CONF="{$SERVER_PATH}/gorse/gorse.toml"
|
||||
|
||||
APP_DIR={$SERVER_PATH}/gorse
|
||||
|
||||
app_start(){
|
||||
echo "Starting Gorse server..."
|
||||
echo "$APP_DIR/bin/gorse-in-one -c $CONF"
|
||||
nohup $APP_DIR/bin/gorse-in-one -c $CONF >> {$SERVER_PATH}/gorse/logs.pl 2>&1 &
|
||||
}
|
||||
|
||||
app_stop(){
|
||||
echo "Stopping ..."
|
||||
|
||||
find_gorse=`ps -ef | grep gorse | grep -v grep | awk "{print $2}"`
|
||||
for p in ${find_gorse[@]}
|
||||
do
|
||||
kill -9 $p > /dev/null 2>&1
|
||||
done
|
||||
|
||||
echo "Gorse stopped"
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
app_start
|
||||
;;
|
||||
stop)
|
||||
app_stop
|
||||
;;
|
||||
restart|reload)
|
||||
app_stop
|
||||
sleep 0.3
|
||||
app_start
|
||||
;;
|
||||
*)
|
||||
echo "Please use start or stop as first argument"
|
||||
;;
|
||||
esac
|
||||
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
sysArch=`arch`
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/gorse && bash install.sh install 0.4.15
|
||||
# cd /www/server/mdserver-web/plugins/gorse && bash install.sh install 0.4.15
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
mkdir -p $serverPath/source/gorse
|
||||
|
||||
SYSNAME=linux
|
||||
if [ "$sysName" == "Darwin" ];then
|
||||
SYSNAME=darwin
|
||||
fi
|
||||
|
||||
ARCH="amd64"
|
||||
if [ "$sysArch" == "x86_64" ];then
|
||||
ARCH="amd64"
|
||||
elif [ "$sysArch" == "aarch64" ];then
|
||||
ARCH="arm64"
|
||||
elif [ "$sysArch" == "arm64" ];then
|
||||
ARCH="arm64"
|
||||
else
|
||||
ARCH="amd64"
|
||||
fi
|
||||
|
||||
FILE_TGZ=gorse_${SYSNAME}_${ARCH}.zip
|
||||
GORSE_DIR=$serverPath/source/gorse
|
||||
|
||||
# https://github.com/gorse-io/gorse/releases/download/v0.4.15/gorse_linux_amd64.zip
|
||||
echo "https://github.com/gorse-io/gorse/releases/download/v${VERSION}/${FILE_TGZ}"
|
||||
|
||||
if [ ! -f $GORSE_DIR/${FILE_TGZ} ];then
|
||||
wget -O $GORSE_DIR/${FILE_TGZ} https://github.com/gorse-io/gorse/releases/download/v${VERSION}/${FILE_TGZ}
|
||||
fi
|
||||
|
||||
mkdir -p $serverPath/gorse/bin
|
||||
mkdir -p $serverPath/gorse/logs
|
||||
cd $GORSE_DIR && unzip -d $serverPath/gorse/bin ${FILE_TGZ}
|
||||
|
||||
mkdir -p $serverPath/gorse/data
|
||||
echo "${VERSION}" > $serverPath/gorse/version.pl
|
||||
echo '安装Gorse完成'
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/gorse/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/gorse/index.py initd_install
|
||||
|
||||
if [ -d ${GORSE_DIR}/gorse-${VERSION} ];then
|
||||
rm -rf ${GORSE_DIR}/gorse-${VERSION}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
app_name=gorse
|
||||
systemctl_dir=/lib/systemd/system
|
||||
if [ -d /usr/lib/systemd/system ];then
|
||||
systemctl_dir=/usr/lib/systemd/system
|
||||
fi
|
||||
|
||||
if [ -f ${systemctl_dir}/${app_name}.service ];then
|
||||
systemctl stop ${app_name}
|
||||
systemctl disable ${app_name}
|
||||
rm -rf ${systemctl_dir}/${app_name}.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/${app_name}/initd/${app_name} ];then
|
||||
$serverPath/${app_name}/initd/${app_name} stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/${app_name} ];then
|
||||
rm -rf $serverPath/${app_name}
|
||||
fi
|
||||
|
||||
echo "卸载Gorse成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
function gorsePost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'gorse';
|
||||
req_data['func'] = method;
|
||||
req_data['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
//错误展示10S
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function gorsePostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'gorse';
|
||||
req_data['func'] = method;
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
function gorseReadme(){
|
||||
|
||||
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>参考官方</li>';
|
||||
readme += '<li><a target="_blank" href="https://gorse.io">https://gorse.io</a></li>';
|
||||
readme += '<li>mongodb初始化,是无认证的</li>';
|
||||
readme += '</ul>';
|
||||
|
||||
$('.soft-man-con').html(readme);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
[database]
|
||||
|
||||
# The database for caching, support Redis, MySQL, Postgres and MongoDB:
|
||||
# redis://<user>:<password>@<host>:<port>/<db_number>
|
||||
# rediss://<user>:<password>@<host>:<port>/<db_number>
|
||||
# redis+cluster://<user>:<password>@<host1>:<port1>,<host2>:<port2>,...,<hostN>:<portN>
|
||||
# postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full
|
||||
# postgresql://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full
|
||||
# mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
|
||||
# mongodb+srv://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
|
||||
cache_store = "redis://localhost:6379/0"
|
||||
|
||||
# The database for persist data, support MySQL, Postgres, ClickHouse and MongoDB:
|
||||
# mysql://[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
|
||||
# postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full
|
||||
# postgresql://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full
|
||||
# clickhouse://user:password@host[:port]/database?param1=value1&...¶mN=valueN
|
||||
# chhttp://user:password@host[:port]/database?param1=value1&...¶mN=valueN
|
||||
# chhttps://user:password@host[:port]/database?param1=value1&...¶mN=valueN
|
||||
# mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
|
||||
# mongodb+srv://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
|
||||
data_store = "mysql://gorse:gorse_pass@tcp(localhost:3306)/gorse"
|
||||
|
||||
# The naming prefix for tables (collections, keys) in databases. The default value is empty.
|
||||
table_prefix = ""
|
||||
|
||||
# The naming prefix for tables (collections, keys) in cache storage databases. The default value is `table_prefix`.
|
||||
cache_table_prefix = ""
|
||||
|
||||
# The naming prefix for tables (collections, keys) in data storage databases. The default value is `table_prefix`.
|
||||
data_table_prefix = ""
|
||||
|
||||
[master]
|
||||
|
||||
# GRPC port of the master node. The default value is 8086.
|
||||
port = 8086
|
||||
|
||||
# gRPC host of the master node. The default values is "0.0.0.0".
|
||||
host = "0.0.0.0"
|
||||
|
||||
# HTTP port of the master node. The default values is 8088.
|
||||
http_port = 8088
|
||||
|
||||
# HTTP host of the master node. The default values is "0.0.0.0".
|
||||
http_host = "0.0.0.0"
|
||||
|
||||
# AllowedDomains is a list of allowed values for Http Origin.
|
||||
# The list may contain the special wildcard string ".*" ; all is allowed
|
||||
# If empty all are allowed.
|
||||
http_cors_domains = []
|
||||
|
||||
# AllowedMethods is either empty or has a list of http methods names. Checking is case-insensitive.
|
||||
http_cors_methods = []
|
||||
|
||||
# Number of working jobs in the master node. The default value is 1.
|
||||
n_jobs = 1
|
||||
|
||||
# Meta information timeout. The default value is 10s.
|
||||
meta_timeout = "10s"
|
||||
|
||||
# Username for the master node dashboard.
|
||||
dashboard_user_name = ""
|
||||
|
||||
# Password for the master node dashboard.
|
||||
dashboard_password = ""
|
||||
|
||||
# Secret key for admin APIs (SSL required).
|
||||
admin_api_key = ""
|
||||
|
||||
[server]
|
||||
|
||||
# Default number of returned items. The default value is 10.
|
||||
default_n = 10
|
||||
|
||||
# Secret key for RESTful APIs (SSL required).
|
||||
api_key = ""
|
||||
|
||||
# Clock error in the cluster. The default value is 5s.
|
||||
clock_error = "5s"
|
||||
|
||||
# Insert new users while inserting feedback. The default value is true.
|
||||
auto_insert_user = true
|
||||
|
||||
# Insert new items while inserting feedback. The default value is true.
|
||||
auto_insert_item = true
|
||||
|
||||
# Server-side cache expire time. The default value is 10s.
|
||||
cache_expire = "10s"
|
||||
|
||||
[recommend]
|
||||
|
||||
# The cache size for recommended/popular/latest items. The default value is 10.
|
||||
cache_size = 100
|
||||
|
||||
# Recommended cache expire time. The default value is 72h.
|
||||
cache_expire = "72h"
|
||||
|
||||
[recommend.data_source]
|
||||
|
||||
# The feedback types for positive events.
|
||||
positive_feedback_types = ["star","like"]
|
||||
|
||||
# The feedback types for read events.
|
||||
read_feedback_types = ["read"]
|
||||
|
||||
# The time-to-live (days) of positive feedback, 0 means disabled. The default value is 0.
|
||||
positive_feedback_ttl = 0
|
||||
|
||||
# The time-to-live (days) of items, 0 means disabled. The default value is 0.
|
||||
item_ttl = 0
|
||||
|
||||
[recommend.popular]
|
||||
|
||||
# The time window of popular items. The default values is 4320h.
|
||||
popular_window = "720h"
|
||||
|
||||
[recommend.user_neighbors]
|
||||
|
||||
# The type of neighbors for users. There are three types:
|
||||
# similar: Neighbors are found by number of common labels.
|
||||
# related: Neighbors are found by number of common liked items.
|
||||
# auto: If a user have labels, neighbors are found by number of common labels.
|
||||
# If this user have no labels, neighbors are found by number of common liked items.
|
||||
# The default value is "auto".
|
||||
neighbor_type = "similar"
|
||||
|
||||
# Enable approximate user neighbor searching using vector index. The default value is true.
|
||||
enable_index = true
|
||||
|
||||
# Minimal recall for approximate user neighbor searching. The default value is 0.8.
|
||||
index_recall = 0.8
|
||||
|
||||
# Maximal number of fit epochs for approximate user neighbor searching vector index. The default value is 3.
|
||||
index_fit_epoch = 3
|
||||
|
||||
[recommend.item_neighbors]
|
||||
|
||||
# The type of neighbors for items. There are three types:
|
||||
# similar: Neighbors are found by number of common labels.
|
||||
# related: Neighbors are found by number of common users.
|
||||
# auto: If a item have labels, neighbors are found by number of common labels.
|
||||
# If this item have no labels, neighbors are found by number of common users.
|
||||
# The default value is "auto".
|
||||
neighbor_type = "similar"
|
||||
|
||||
# Enable approximate item neighbor searching using vector index. The default value is true.
|
||||
enable_index = true
|
||||
|
||||
# Minimal recall for approximate item neighbor searching. The default value is 0.8.
|
||||
index_recall = 0.8
|
||||
|
||||
# Maximal number of fit epochs for approximate item neighbor searching vector index. The default value is 3.
|
||||
index_fit_epoch = 3
|
||||
|
||||
[recommend.collaborative]
|
||||
|
||||
# Enable approximate collaborative filtering recommend using vector index. The default value is true.
|
||||
enable_index = true
|
||||
|
||||
# Minimal recall for approximate collaborative filtering recommend. The default value is 0.9.
|
||||
index_recall = 0.9
|
||||
|
||||
# Maximal number of fit epochs for approximate collaborative filtering recommend vector index. The default value is 3.
|
||||
index_fit_epoch = 3
|
||||
|
||||
# The time period for model fitting. The default value is "60m".
|
||||
model_fit_period = "60m"
|
||||
|
||||
# The time period for model searching. The default value is "360m".
|
||||
model_search_period = "360m"
|
||||
|
||||
# The number of epochs for model searching. The default value is 100.
|
||||
model_search_epoch = 100
|
||||
|
||||
# The number of trials for model searching. The default value is 10.
|
||||
model_search_trials = 10
|
||||
|
||||
# Enable searching models of different sizes, which consume more memory. The default value is false.
|
||||
enable_model_size_search = false
|
||||
|
||||
[recommend.replacement]
|
||||
|
||||
# Replace historical items back to recommendations. The default value is false.
|
||||
enable_replacement = false
|
||||
|
||||
# Decay the weights of replaced items from positive feedbacks. The default value is 0.8.
|
||||
positive_replacement_decay = 0.8
|
||||
|
||||
# Decay the weights of replaced items from read feedbacks. The default value is 0.6.
|
||||
read_replacement_decay = 0.6
|
||||
|
||||
[recommend.offline]
|
||||
|
||||
# The time period to check recommendation for users. The default values is 1m.
|
||||
check_recommend_period = "1m"
|
||||
|
||||
# The time period to refresh recommendation for inactive users. The default values is 120h.
|
||||
refresh_recommend_period = "24h"
|
||||
|
||||
# Enable latest recommendation during offline recommendation. The default value is false.
|
||||
enable_latest_recommend = true
|
||||
|
||||
# Enable popular recommendation during offline recommendation. The default value is false.
|
||||
enable_popular_recommend = false
|
||||
|
||||
# Enable user-based similarity recommendation during offline recommendation. The default value is false.
|
||||
enable_user_based_recommend = true
|
||||
|
||||
# Enable item-based similarity recommendation during offline recommendation. The default value is false.
|
||||
enable_item_based_recommend = false
|
||||
|
||||
# Enable collaborative filtering recommendation during offline recommendation. The default value is true.
|
||||
enable_collaborative_recommend = true
|
||||
|
||||
# Enable click-though rate prediction during offline recommendation. Otherwise, results from multi-way recommendation
|
||||
# would be merged randomly. The default value is false.
|
||||
enable_click_through_prediction = true
|
||||
|
||||
# The explore recommendation method is used to inject popular items or latest items into recommended result:
|
||||
# popular: Recommend popular items to cold-start users.
|
||||
# latest: Recommend latest items to cold-start users.
|
||||
# The default values is { popular = 0.0, latest = 0.0 }.
|
||||
explore_recommend = { popular = 0.1, latest = 0.2 }
|
||||
|
||||
[recommend.online]
|
||||
|
||||
# The fallback recommendation method is used when cached recommendation drained out:
|
||||
# item_based: Recommend similar items to cold-start users.
|
||||
# popular: Recommend popular items to cold-start users.
|
||||
# latest: Recommend latest items to cold-start users.
|
||||
# Recommenders are used in order. The default values is ["latest"].
|
||||
fallback_recommend = ["item_based", "latest"]
|
||||
|
||||
# The number of feedback used in fallback item-based similar recommendation. The default values is 10.
|
||||
num_feedback_fallback_item_based = 10
|
||||
|
||||
[tracing]
|
||||
|
||||
# Enable tracing for REST APIs. The default value is false.
|
||||
enable_tracing = false
|
||||
|
||||
# The type of tracing exporters should be one of "jaeger", "zipkin", "otlp" and "otlphttp". The default value is "jaeger".
|
||||
exporter = "jaeger"
|
||||
|
||||
# The endpoint of tracing collector.
|
||||
collector_endpoint = "http://localhost:14268/api/traces"
|
||||
|
||||
# The type of tracing sampler should be one of "always", "never" and "ratio". The default value is "always".
|
||||
sampler = "always"
|
||||
|
||||
# The ratio of ratio based sampler. The default value is 1.
|
||||
ratio = 1
|
||||
@@ -38,7 +38,7 @@ max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 65535
|
||||
|
||||
skip-name-resolve = 1
|
||||
skip-name-resolve
|
||||
#skip-networking
|
||||
#skip-external-locking
|
||||
#loose-skip-innodb
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"uninstall_pre_inspection":true,
|
||||
"checks": "server/mariadb",
|
||||
"path": "server/mariadb",
|
||||
"versions":["10.6","10.7","10.8","10.9","10.11","11.0","11.1","11.2","11.3","11.4"],
|
||||
"versions":["10.6","10.7","10.8","10.9","10.11","11.0","11.1","11.2","11.3","11.4","11.5"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/mariadb",
|
||||
"path":"server/mariadb",
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.4.2
|
||||
MY_VER=11.4.3
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
Executable
+121
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
#https://dev.mysql.com/downloads/file/?id=480541
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.5.2
|
||||
|
||||
Install_app()
|
||||
{
|
||||
mkdir -p ${mariadbDir}
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if [ "$sysName" != "Darwin" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ -f /proc/cpuinfo ];then
|
||||
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
|
||||
fi
|
||||
|
||||
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
|
||||
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
|
||||
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
|
||||
cpuCore="${MEM_INFO}"
|
||||
fi
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# fi
|
||||
|
||||
# https://downloads.mariadb.org/interstitial/mariadb-10.9.1/source/mariadb-10.9.1.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
INSTALL_CMD=cmake
|
||||
# check cmake version
|
||||
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
|
||||
if [ "$CMAKE_VERSION" -eq "2" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
INSTALL_CMD=cmake3
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
||||
-DMYSQL_USER=mysql \
|
||||
-DMYSQL_UNIX_ADDR=$serverPath/mariadb/mysql.sock \
|
||||
-DWITH_MYISAM_STORAGE_ENGINE=1 \
|
||||
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
|
||||
-DWITH_MEMORY_STORAGE_ENGINE=1 \
|
||||
-DENABLED_LOCAL_INFILE=1 \
|
||||
-DWITH_PARTITION_STORAGE_ENGINE=1 \
|
||||
-DEXTRA_CHARSETS=all \
|
||||
-DDEFAULT_CHARSET=utf8mb4 \
|
||||
-DDEFAULT_COLLATION=utf8mb4_general_ci \
|
||||
-DCMAKE_C_COMPILER=/usr/bin/gcc \
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/g++
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '11.4' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
rm -rf $serverPath/mariadb
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
@@ -15,14 +15,14 @@ echo $sys_os
|
||||
|
||||
Install_mem(){
|
||||
mkdir -p $serverPath/source
|
||||
# mkdir -p $serverPath/memcached
|
||||
mkdir -p $serverPath/source/memcached
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if [ ! -f $serverPath/source/memcached.tar.gz ];then
|
||||
wget --no-check-certificate -O $serverPath/source/memcached.tar.gz http://www.memcached.org/files/memcached-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O $serverPath/source/memcached/memcached.tar.gz https://www.memcached.org/files/memcached-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
cd $serverPath/source && tar -zxvf memcached.tar.gz
|
||||
cd $serverPath/source/memcached && tar -zxvf memcached.tar.gz
|
||||
|
||||
OPTIONS=''
|
||||
if [ ${sys_os} == "Darwin" ]; then
|
||||
@@ -31,7 +31,7 @@ Install_mem(){
|
||||
fi
|
||||
|
||||
echo "./configure --prefix=${serverPath}/memcached && make && make install"
|
||||
cd $serverPath/source/memcached-${VERSION}
|
||||
cd $serverPath/source/memcached/memcached-${VERSION}
|
||||
./configure --prefix=$serverPath/memcached \
|
||||
$OPTIONS
|
||||
|
||||
@@ -39,12 +39,12 @@ Install_mem(){
|
||||
|
||||
if [ -d $serverPath/memcached ];then
|
||||
echo '1.6' > $serverPath/memcached/version.pl
|
||||
echo 'install ok' > $install_tmp
|
||||
echo '安装memcached成功'
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/memcached/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/memcached/index.py initd_install
|
||||
|
||||
rm -rf $serverPath/source/memcached-${VERSION}
|
||||
rm -rf $serverPath/source/memcached/memcached-${VERSION}
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ Uninstall_mem()
|
||||
$serverPath/memcached/initd/memcached stop
|
||||
fi
|
||||
rm -rf $serverPath/memcached
|
||||
echo '卸载memcached成功'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -662,6 +662,27 @@ def delDb():
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '删除失败!' + str(ex))
|
||||
|
||||
|
||||
def delDbTable():
|
||||
client = mongdbClient()
|
||||
db = client.admin
|
||||
sqlite_db = pSqliteDb('databases')
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['table_name', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
name = args['name']
|
||||
table_name = args['table_name']
|
||||
|
||||
try:
|
||||
cur_db = client[name]
|
||||
cur_db[table_name].drop()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '删除失败!' + str(ex))
|
||||
|
||||
def setRootPwd(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['password'])
|
||||
@@ -1289,6 +1310,10 @@ def getListBson(dbname=''):
|
||||
r.append(x)
|
||||
return r
|
||||
|
||||
def rootPwd():
|
||||
return pSqliteDb('config').where(
|
||||
'id=?', (1,)).getField('mg_root')
|
||||
|
||||
def importDbExternal():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
@@ -1568,12 +1593,16 @@ if __name__ == "__main__":
|
||||
print(saveConfig())
|
||||
elif func == 'set_config_auth':
|
||||
print(setConfigAuth())
|
||||
elif func == 'root_pwd':
|
||||
print(rootPwd())
|
||||
elif func == 'get_db_list':
|
||||
print(getDbList())
|
||||
elif func == 'add_db':
|
||||
print(addDb())
|
||||
elif func == 'del_db':
|
||||
print(delDb())
|
||||
elif func == 'del_db_table':
|
||||
print(delDbTable())
|
||||
elif func == 'set_root_pwd':
|
||||
print(setRootPwd())
|
||||
elif func == 'set_user_pwd':
|
||||
|
||||
@@ -36,7 +36,7 @@ if [ -f ${rootPath}/bin/activate ];then
|
||||
fi
|
||||
Install_app()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
echo '正在安装脚本文件...'
|
||||
mkdir -p $serverPath/source
|
||||
|
||||
# if id mongodb &> /dev/null ;then
|
||||
@@ -66,7 +66,7 @@ Install_app()
|
||||
if [ -f $shell_file ];then
|
||||
bash -x $shell_file
|
||||
else
|
||||
echo '不支持...' > $install_tmp
|
||||
echo '不支持...'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -767,6 +767,18 @@ function delDb(id, name){
|
||||
});
|
||||
}
|
||||
|
||||
function delDbTable( name, table_name){
|
||||
safeMessage('删除['+name+']','您真的要删除['+table_name+']吗?',function(){
|
||||
var data='name='+name+'&table_name='+table_name;
|
||||
mgPost('del_db_table', '', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
repTools(name);
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delDbBatch(){
|
||||
var arr = [];
|
||||
$('input[type="checkbox"].check:checked').each(function () {
|
||||
@@ -835,22 +847,10 @@ function setDbPass(id, username, password){
|
||||
}
|
||||
|
||||
function repTools(db_name, res){
|
||||
|
||||
mgPost('get_db_info', '', {name:db_name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var rdata = rdata.data;
|
||||
// console.log(rdata.collection_list);
|
||||
var tbody = '';
|
||||
for (var i = 0; i < rdata.collection_list.length; i++) {
|
||||
tbody += '<tr>\
|
||||
<td><span style="width:220px;"> ' + rdata.collection_list[i].collection_name + '</span></td>\
|
||||
<td><span style="width:220px;"> ' + rdata.collection_list[i].count + '</span></td>\
|
||||
<td>' + toSize(rdata.collection_list[i].size) + '</td>\
|
||||
<td><span style="width:90px;"> ' + toSize(rdata.collection_list[i].avg_obj_size) + '</span></td>\
|
||||
<td>' + toSize(rdata.collection_list[i].storage_size) + '</td>\
|
||||
<td>' + rdata.collection_list[i].nindexes + '</td>\
|
||||
<td>' + toSize(rdata.collection_list[i].total_index_size) + '</td>\
|
||||
</tr> '
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
@@ -858,7 +858,7 @@ function repTools(db_name, res){
|
||||
area: ['780px', '480px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
content: '<div class="pd15" id="mongodb_list">\
|
||||
<div class="db_list">\
|
||||
<span><a>数据库名称:'+ db_name + '</a>\
|
||||
<a>集合:'+ rdata.collections + '</a>\
|
||||
@@ -879,13 +879,51 @@ function repTools(db_name, res){
|
||||
<th>存储大小</th>\
|
||||
<th>索引数量</th>\
|
||||
<th>索引大小</th>\
|
||||
<th>操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody class="gztr">' + tbody + '</tbody>\
|
||||
<tbody class="gztr"></tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>'
|
||||
</div>',
|
||||
success:function(layer_id, layer_index){
|
||||
|
||||
var tbody = '';
|
||||
for (var i = 0; i < rdata.collection_list.length; i++) {
|
||||
tbody += '<tr>\
|
||||
<td><span style="width:220px;"> ' + rdata.collection_list[i].collection_name + '</span></td>\
|
||||
<td><span style="width:220px;"> ' + rdata.collection_list[i].count + '</span></td>\
|
||||
<td>' + toSize(rdata.collection_list[i].size) + '</td>\
|
||||
<td><span style="width:90px;"> ' + toSize(rdata.collection_list[i].avg_obj_size) + '</span></td>\
|
||||
<td>' + toSize(rdata.collection_list[i].storage_size) + '</td>\
|
||||
<td>' + rdata.collection_list[i].nindexes + '</td>\
|
||||
<td>' + toSize(rdata.collection_list[i].total_index_size) + '</td>\
|
||||
<td>' + '<a href="javascript:;" data-index="'+i+'" class="delete btlink" title="删除">删除</a>'+'</td>\
|
||||
</tr>';
|
||||
}
|
||||
|
||||
$('#mongodb_list tbody').html(tbody);
|
||||
|
||||
$('#mongodb_list .delete').click(function(){
|
||||
var index = $(this).data('index');
|
||||
|
||||
var name = db_name;
|
||||
var table_name = rdata.collection_list[index].collection_name;
|
||||
|
||||
safeMessage('删除['+name+']','您真的要删除['+table_name+']吗?',function(){
|
||||
var data='name='+name+'&table_name='+table_name;
|
||||
mgPost('del_db_table', '', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layer_index);
|
||||
repTools(name);
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
tableFixed('database_fix');
|
||||
});
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.9
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
|
||||
|
||||
if [ "$SYS_NAME_LEN" == "1" ];then
|
||||
SYS_NAME=${SYS_NAME}0
|
||||
fi
|
||||
|
||||
if [ "$SYS_ARCH" == "aarch64" ];then
|
||||
if [ "$SYS_NAME" -gt "90" ];then
|
||||
SYS_NAME="90"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "82" ];then
|
||||
SYS_NAME="82"
|
||||
fi
|
||||
else
|
||||
|
||||
if [ "$SYS_NAME" -gt "90" ];then
|
||||
SYS_NAME="90"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "70" ];then
|
||||
SYS_NAME="70"
|
||||
fi
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
#--------------- mongosh tool install ------------------ #
|
||||
TOOL_VERSION=2.2.5
|
||||
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-x64
|
||||
if [ "aarch64" == ${SYS_ARCH} ];then
|
||||
TOOL_FILE_NAME=mongosh-${TOOL_VERSION}-linux-arm64
|
||||
fi
|
||||
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
|
||||
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://downloads.mongodb.com/compass/${TOOL_FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
|
||||
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
|
||||
|
||||
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel90-aarch64-100.9.4.tgz
|
||||
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel90-x86_64-100.9.4.tgz
|
||||
# https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel83-s390x-100.9.4.tgz
|
||||
#--------------- mongodb database install ------------------ #
|
||||
TOOL_VERSION=100.9.4
|
||||
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-x86_64-${TOOL_VERSION}
|
||||
if [ "aarch64" == ${SYS_ARCH} ];then
|
||||
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-aarch64-${TOOL_VERSION}
|
||||
fi
|
||||
|
||||
if [ "arm64" == ${SYS_ARCH} ];then
|
||||
TOOL_FILE_NAME=mongodb-database-tools-rhel${SYS_NAME}-arm64-${TOOL_VERSION}
|
||||
fi
|
||||
|
||||
TOOL_FILE_NAME_TGZ=${TOOL_FILE_NAME}.tgz
|
||||
if [ ! -f $MG_DIR/${TOOL_FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${TOOL_FILE_NAME_TGZ} https://fastdl.mongodb.org/tools/db/${TOOL_FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${TOOL_FILE_NAME_TGZ} ];then
|
||||
cd $MG_DIR && tar -zxvf ${TOOL_FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
cd ${MG_DIR}/${TOOL_FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${TOOL_FILE_NAME}
|
||||
|
||||
@@ -103,7 +103,7 @@ secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
max_allowed_packet = 16M
|
||||
max_allowed_packet = 32M
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
@@ -106,7 +106,7 @@ secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
max_allowed_packet = 16M
|
||||
max_allowed_packet = 32M
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
@@ -62,9 +62,10 @@ http
|
||||
|
||||
# CACEH_BEGIN
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 4k;
|
||||
proxy_buffers 512 4k;
|
||||
proxy_busy_buffers_size 64k;
|
||||
proxy_buffer_size 1024k;
|
||||
proxy_buffers 16 1024k;
|
||||
proxy_busy_buffers_size 2048k;
|
||||
proxy_temp_file_write_size 2048k;
|
||||
proxy_cache_path {$SERVER_PATH}/openresty/nginx/proxy_cache_temp levels=1:2 keys_zone=mw_cache:512m inactive=5m max_size=2g use_temp_path=off;
|
||||
#proxy timeout
|
||||
proxy_connect_timeout 3s;
|
||||
|
||||
@@ -400,6 +400,10 @@ def initdUinstall():
|
||||
|
||||
|
||||
def runInfo():
|
||||
op_status = status()
|
||||
if op_status == 'stop':
|
||||
return mw.returnJson(False, "未启动!")
|
||||
|
||||
# 取Openresty负载状态
|
||||
try:
|
||||
url = 'http://127.0.0.1/nginx_status'
|
||||
@@ -429,7 +433,7 @@ def runInfo():
|
||||
data['Waiting'] = tmp[15]
|
||||
return mw.getJson(data)
|
||||
except Exception as e:
|
||||
return 'oprenresty not started'
|
||||
return mw.returnJson(False, "oprenresty not started!")
|
||||
|
||||
|
||||
def errorLogPath():
|
||||
|
||||
@@ -114,13 +114,14 @@ function orPluginOpServiceOp(a,b,c,d,a,v,request_callback){
|
||||
function getOpStatus() {
|
||||
var loadT = layer.msg('正在处理,请稍后...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'openresty', func:'run_info'}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
showMsg(data.msg, function(){}, null,3000);
|
||||
return;
|
||||
}
|
||||
layer.close(loadT);
|
||||
try {
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if ('status' in rdata && !rdata.status){
|
||||
showMsg(rdata.msg, function(){}, null,3000);
|
||||
return;
|
||||
}
|
||||
|
||||
var con = "<div><table class='table table-hover table-bordered'>\
|
||||
<tr><th>活动连接(Active connections)</th><td>" + rdata.active + "</td></tr>\
|
||||
<tr><th>总连接次数(accepts)</th><td>" + rdata.accepts + "</td></tr>\
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
LOG_FILE = '{$DATA_PATH}/pgadmin4/pgadmin4.log'
|
||||
SQLITE_PATH = '{$DATA_PATH}/pgadmin4/pgadmin4.db'
|
||||
SESSION_DB_PATH = '{$DATA_PATH}/pgadmin4/sessions'
|
||||
STORAGE_DIR = '{$DATA_PATH}/pgadmin4/storage'
|
||||
AZURE_CREDENTIAL_CACHE_DIR = '{$DATA_PATH}/pgadmin4/azurecredentialcache'
|
||||
SERVER_MODE = True
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
server
|
||||
{
|
||||
listen 5051;
|
||||
server_name 127.0.0.1;
|
||||
index index.html index.htm index.php;
|
||||
root {$SERVER_PATH}/pgadmin;
|
||||
|
||||
#error_page 404 /404.html;
|
||||
|
||||
#AUTH_START
|
||||
auth_basic "Authorization";
|
||||
auth_basic_user_file {$SERVER_PATH}/pgadmin/pg.pass;
|
||||
#AUTH_END
|
||||
|
||||
location / {
|
||||
proxy_pass http://unix:/tmp/pgadmin4.sock;
|
||||
}
|
||||
|
||||
access_log {$SERVER_PATH}/pgadmin/access.log;
|
||||
error_log {$SERVER_PATH}/pgadmin/error.log;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
Executable
+22
@@ -0,0 +1,22 @@
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('pgadmin');">服务</p>
|
||||
<p onclick="pluginConfig('pgadmin');">重写模版</p>
|
||||
<p onclick="homePage()">主页</p>
|
||||
<p onclick="safeConf();">安全设置</p>
|
||||
<p onclick="pluginLogs('pgadmin','','access_log');">访问日志</p>
|
||||
<p onclick="pluginLogs('pgadmin','','error_log');">错误日志</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinHeight(500);
|
||||
$.getScript( "/plugins/file?name=pgadmin&f=js/pgadmin.js", function(){
|
||||
pluginService('pgadmin');
|
||||
});
|
||||
</script>
|
||||
Executable
+418
@@ -0,0 +1,418 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
import site_api
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'pgadmin'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def getConf():
|
||||
return mw.getServerDir() + '/web_conf/nginx/vhost/pgadmin.conf'
|
||||
|
||||
|
||||
def getPort():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'listen\s*(.*);'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
|
||||
def getHomePage():
|
||||
try:
|
||||
port = getPort()
|
||||
ip = '127.0.0.1'
|
||||
if not mw.isAppleSystem():
|
||||
ip = mw.getLocalIp()
|
||||
|
||||
cfg = getCfg()
|
||||
auth = cfg['username']+':'+cfg['password']
|
||||
url = 'http://' + auth + '@' + ip + ':' + port + '/'
|
||||
return mw.returnJson(True, 'OK', url)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '插件未启动!')
|
||||
|
||||
|
||||
|
||||
def contentReplace(content):
|
||||
cfg = getCfg()
|
||||
service_path = mw.getServerDir()
|
||||
|
||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$APP_PATH}', service_path+'/'+getPluginName()+'/data')
|
||||
|
||||
port = cfg["port"]
|
||||
rep = 'listen\s*(.*);'
|
||||
content = re.sub(rep, "listen " + port + ';', content)
|
||||
return content
|
||||
|
||||
|
||||
def initCfg():
|
||||
cfg = getServerDir() + "/cfg.json"
|
||||
if not os.path.exists(cfg):
|
||||
data = {}
|
||||
data['port'] = '5051'
|
||||
data['path'] = ''
|
||||
data['username'] = 'admin'
|
||||
data['password'] = 'admin'
|
||||
|
||||
data['web_pg_username'] = 'mdserver-web@gmail.com'
|
||||
data['web_pg_password'] = 'admin'
|
||||
mw.writeFile(cfg, json.dumps(data))
|
||||
|
||||
|
||||
def setCfg(key, val):
|
||||
cfg = getServerDir() + "/cfg.json"
|
||||
data = mw.readFile(cfg)
|
||||
data = json.loads(data)
|
||||
data[key] = val
|
||||
mw.writeFile(cfg, json.dumps(data))
|
||||
|
||||
|
||||
def getCfg():
|
||||
cfg = getServerDir() + "/cfg.json"
|
||||
data = mw.readFile(cfg)
|
||||
data = json.loads(data)
|
||||
return data
|
||||
|
||||
|
||||
def returnCfg():
|
||||
cfg = getServerDir() + "/cfg.json"
|
||||
data = mw.readFile(cfg)
|
||||
return data
|
||||
|
||||
|
||||
def __release_port(port):
|
||||
from collections import namedtuple
|
||||
try:
|
||||
import firewall_api
|
||||
firewall_api.firewall_api().addAcceptPortArgs(port, 'pgAdmin默认端口', 'port')
|
||||
return port
|
||||
except Exception as e:
|
||||
return "Release failed {}".format(e)
|
||||
|
||||
|
||||
def __delete_port(port):
|
||||
from collections import namedtuple
|
||||
try:
|
||||
import firewall_api
|
||||
firewall_api.firewall_api().delAcceptPortArgs(port, 'tcp')
|
||||
return port
|
||||
except Exception as e:
|
||||
return "Release failed {}".format(e)
|
||||
|
||||
|
||||
def openPort():
|
||||
conf = getCfg()
|
||||
port = conf['port']
|
||||
for i in [port]:
|
||||
__release_port(i)
|
||||
return True
|
||||
|
||||
|
||||
def delPort():
|
||||
conf = getCfg()
|
||||
port = conf['port']
|
||||
for i in [port]:
|
||||
__delete_port(i)
|
||||
return True
|
||||
|
||||
|
||||
def cleanNginxLog():
|
||||
log_a = accessLog()
|
||||
log_e = errorLog()
|
||||
|
||||
for i in [log_a, log_e]:
|
||||
if os.path.exists(i):
|
||||
cmd = "echo '' > " + i
|
||||
mw.execShell(cmd)
|
||||
|
||||
def getPythonName():
|
||||
cmd = "ls /www/server/pgadmin/run/lib/ | grep python | cut -d \\ -f 1 | awk 'END {print}'"
|
||||
data = mw.execShell(cmd)
|
||||
return data[0].strip();
|
||||
|
||||
def initPgConfFile():
|
||||
file_tpl = getPluginDir() + '/conf/config_local.py'
|
||||
dst_file = getServerDir()+'/run/lib/python3.10/site-packages/pgadmin4/config_local.py'
|
||||
if not os.path.exists(dst_file):
|
||||
service_path = mw.getServerDir()
|
||||
content = mw.readFile(file_tpl)
|
||||
content = content.replace('{$DATA_PATH}', service_path+'/'+getPluginName()+'/data')
|
||||
mw.writeFile(dst_file, content)
|
||||
|
||||
|
||||
def initReplace():
|
||||
initPgConfFile()
|
||||
|
||||
file_tpl = getPluginDir() + '/conf/pgadmin.conf'
|
||||
file_run = getConf()
|
||||
if not os.path.exists(file_run):
|
||||
content = mw.readFile(file_tpl)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(file_run, content)
|
||||
|
||||
pass_path = getServerDir() + '/pg.pass'
|
||||
if not os.path.exists(pass_path):
|
||||
username = mw.getRandomString(8)
|
||||
password = mw.getRandomString(10)
|
||||
pass_cmd = username + ':' + mw.hasPwd(password)
|
||||
setCfg('username', username)
|
||||
setCfg('password', password)
|
||||
mw.writeFile(pass_path, pass_cmd)
|
||||
|
||||
# pg_conf = getCfg()
|
||||
judge_file = getServerDir()+'/data/pgadmin4/pgadmin4.db'
|
||||
if not os.path.exists(judge_file):
|
||||
pg_init_bash = getPluginDir()+'/pg_init.sh'
|
||||
pg_rand = mw.getRandomString(8)
|
||||
pg_username = "mw."+pg_rand+"@gmail.com"
|
||||
setCfg('web_pg_username', pg_username)
|
||||
pg_password = mw.getRandomString(10)
|
||||
setCfg('web_pg_password', pg_password)
|
||||
t = mw.execShell("bash "+ pg_init_bash + " " + pg_username + " " + pg_password)
|
||||
# print(t)
|
||||
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
systemService = systemDir + '/pgadmin.service'
|
||||
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
systemServiceTpl = getPluginDir() + '/init.d/pgadmin.service.tpl'
|
||||
service_path = mw.getServerDir()
|
||||
content = mw.readFile(systemServiceTpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$PY_VER}', getPythonName())
|
||||
|
||||
|
||||
mw.writeFile(systemService, content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
|
||||
def pgOp(method):
|
||||
file = initReplace()
|
||||
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
return 'ok'
|
||||
|
||||
if current_os.startswith("freebsd"):
|
||||
data = mw.execShell('service' + getPluginName() + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell('systemctl ' + method+ ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
def status():
|
||||
sock = '/tmp/pgadmin4.sock'
|
||||
if os.path.exists(sock):
|
||||
return 'start'
|
||||
return 'stop'
|
||||
|
||||
|
||||
def start():
|
||||
initCfg()
|
||||
openPort()
|
||||
|
||||
pgOp('start')
|
||||
|
||||
mw.restartWeb()
|
||||
return 'ok'
|
||||
|
||||
|
||||
def stop():
|
||||
pgOp('stop')
|
||||
|
||||
conf = getConf()
|
||||
if os.path.exists(conf):
|
||||
os.remove(conf)
|
||||
|
||||
delPort()
|
||||
mw.restartWeb()
|
||||
return 'ok'
|
||||
|
||||
|
||||
def restart():
|
||||
cleanNginxLog()
|
||||
state = pgOp('restart')
|
||||
mw.restartWeb()
|
||||
return state
|
||||
|
||||
|
||||
def reload():
|
||||
cleanNginxLog()
|
||||
return pgOp('reload')
|
||||
|
||||
def getPgOption():
|
||||
data = getCfg()
|
||||
return mw.returnJson(True, 'ok', data)
|
||||
|
||||
|
||||
def getPgPort():
|
||||
try:
|
||||
port = getPort()
|
||||
return mw.returnJson(True, 'OK', port)
|
||||
except Exception as e:
|
||||
# print(e)
|
||||
return mw.returnJson(False, '插件未启动!')
|
||||
|
||||
|
||||
def setPgPort():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['port'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
port = args['port']
|
||||
if port == '80':
|
||||
return mw.returnJson(False, '80端不能使用!')
|
||||
|
||||
file = getConf()
|
||||
if not os.path.exists(file):
|
||||
return mw.returnJson(False, '插件未启动!')
|
||||
content = mw.readFile(file)
|
||||
rep = r'listen\s*(.*);'
|
||||
content = re.sub(rep, "listen " + port + ';', content)
|
||||
mw.writeFile(file, content)
|
||||
|
||||
setCfg("port", port)
|
||||
mw.restartWeb()
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
|
||||
|
||||
def setPgUsername():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['username'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
username = args['username']
|
||||
setCfg('username', username)
|
||||
|
||||
cfg = getCfg()
|
||||
pma_path = getServerDir() + '/pg.pass'
|
||||
username = mw.getRandomString(10)
|
||||
pass_cmd = cfg['username'] + ':' + mw.hasPwd(cfg['password'])
|
||||
mw.writeFile(pma_path, pass_cmd)
|
||||
|
||||
mw.restartWeb()
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
|
||||
|
||||
def setPgPassword():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['password'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
password = args['password']
|
||||
setCfg('password', password)
|
||||
|
||||
cfg = getCfg()
|
||||
pma_path = getServerDir() + '/pg.pass'
|
||||
username = mw.getRandomString(10)
|
||||
pass_cmd = cfg['username'] + ':' + mw.hasPwd(cfg['password'])
|
||||
mw.writeFile(pma_path, pass_cmd)
|
||||
|
||||
mw.restartWeb()
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
|
||||
|
||||
def accessLog():
|
||||
return getServerDir() + '/access.log'
|
||||
|
||||
def errorLog():
|
||||
return getServerDir() + '/error.log'
|
||||
|
||||
|
||||
def installVersion():
|
||||
return mw.readFile(getServerDir() + '/version.pl')
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'version':
|
||||
print(installVersion())
|
||||
elif func == 'get_cfg':
|
||||
print(returnCfg())
|
||||
elif func == 'get_home_page':
|
||||
print(getHomePage())
|
||||
elif func == 'get_pg_port':
|
||||
print(getPgPort())
|
||||
elif func == 'set_pg_port':
|
||||
print(setPgPort())
|
||||
elif func == 'get_pg_option':
|
||||
print(getPgOption())
|
||||
elif func == 'set_pg_username':
|
||||
print(setPgUsername())
|
||||
elif func == 'set_pg_password':
|
||||
print(setPgPassword())
|
||||
elif func == 'access_log':
|
||||
print(accessLog())
|
||||
elif func == 'error_log':
|
||||
print(errorLog())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title":"pgadmin",
|
||||
"tip":"soft",
|
||||
"name":"pgadmin",
|
||||
"type":"运行环境",
|
||||
"ps":"全能Postgres数据库Web管理工具",
|
||||
"versions":["4"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/pgadmin",
|
||||
"path": "server/pgadmin",
|
||||
"author":"pgadmin",
|
||||
"home":"https://www.pgadmin.org/download/pgadmin-4-python/",
|
||||
"date":"2024-10-1",
|
||||
"pid": "2"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
# It's not recommended to modify this file in-place, because it
|
||||
# will be overwritten during upgrades. If you want to customize,
|
||||
# the best way is to use the "systemctl edit" command.
|
||||
# systemctl daemon-reload
|
||||
|
||||
[Unit]
|
||||
Description=pgadmin service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=gunicorn --bind unix:/tmp/pgadmin4.sock --workers=1 --threads=25 --chdir {$SERVER_PATH}/pgadmin/run/lib/{$PY_VER}/site-packages/pgadmin4 pgAdmin4:app
|
||||
ExecReload=/bin/kill -USR2 $MAINPID
|
||||
PrivateTmp=false
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
function version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }
|
||||
function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" == "$1"; }
|
||||
function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
P_VER=`python3 -V | awk '{print $2}'`
|
||||
echo "python:$P_VER"
|
||||
|
||||
# https://cn.linux-console.net/?p=6560
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/pgadmin && bash install.sh install 4
|
||||
# cd /www/server/mdserver-web/plugins/pgadmin && bash install.sh install 4
|
||||
|
||||
# source /www/server/pgadmin/run/bin/activate
|
||||
# python /www/server/pgadmin/run/lib/python3.10/site-packages/pgadmin4/setup.py --help
|
||||
# python /www/server/pgadmin/run/lib/python3.10/site-packages/pgadmin4/setup.py add-user mdserver-web@gmail.com 123123
|
||||
# cd /www/server/mdserver-web && python3 plugins/pgadmin/index.py start
|
||||
# cd /www/server/mdserver-web && python3 plugins/pgadmin/index.py stop
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
if [ "$sys_os" == "Darwin" ];then
|
||||
BAK='_bak'
|
||||
else
|
||||
BAK=''
|
||||
fi
|
||||
|
||||
sysName=`uname`
|
||||
echo "use system: ${sysName}"
|
||||
|
||||
if [ "${sysName}" == "Darwin" ]; then
|
||||
OSNAME='macos'
|
||||
elif grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
|
||||
OSNAME='centos'
|
||||
elif grep -Eqi "Fedora" /etc/issue || grep -Eq "Fedora" /etc/*-release; then
|
||||
OSNAME='fedora'
|
||||
elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/*-release; then
|
||||
OSNAME='debian'
|
||||
elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/*-release; then
|
||||
OSNAME='ubuntu'
|
||||
elif grep -Eqi "Raspbian" /etc/issue || grep -Eq "Raspbian" /etc/*-release; then
|
||||
OSNAME='raspbian'
|
||||
else
|
||||
OSNAME='unknow'
|
||||
fi
|
||||
|
||||
Install_pgadmin()
|
||||
{
|
||||
# if [ -d $serverPath/pgadmin ];then
|
||||
# exit 0
|
||||
# fi
|
||||
|
||||
if version_lt "$P_VER" "3.8.0" ;then
|
||||
echo 'Python版本太低,无法安装'
|
||||
exit 0
|
||||
fi
|
||||
PG_DIR=${serverPath}/pgadmin/run
|
||||
PG_DATA_DIR=${serverPath}/pgadmin/data
|
||||
mkdir -p $PG_DIR
|
||||
mkdir -p $PG_DATA_DIR
|
||||
echo "${1}" > ${serverPath}/pgadmin/version.pl
|
||||
|
||||
if [ ! -f $PG_DIR/bin/activate ];then
|
||||
if version_ge "$P_VER" "3.11.0" ;then
|
||||
echo "python3 > 3.11"
|
||||
cd $PG_DIR && python3 -m venv $PG_DIR
|
||||
else
|
||||
echo "python3 < 3.10"
|
||||
cd $PG_DIR && python3 -m venv .
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -f ${PG_DIR}/bin/activate ];then
|
||||
source ${PG_DIR}/bin/activate
|
||||
fi
|
||||
|
||||
# pip install https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v8.10/pip/pgadmin4-8.10-py3-none-any.whl
|
||||
pip install https://ftp.postgresql.org/pub/pgadmin/pgadmin4/v8.12/pip/pgadmin4-8.12-py3-none-any.whl
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/pgadmin/index.py start
|
||||
echo '安装完成'
|
||||
}
|
||||
|
||||
Uninstall_pgadmin()
|
||||
{
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/pgadmin/index.py stop
|
||||
|
||||
if [ -f /usr/lib/systemd/system/pgadmin.service ];then
|
||||
systemctl stop pgadmin
|
||||
systemctl disable pgadmin
|
||||
rm -rf /usr/lib/systemd/system/pgadmin.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/pgadmin.service ];then
|
||||
systemctl stop pgadmin
|
||||
systemctl disable pgadmin
|
||||
rm -rf /lib/systemd/system/pgadmin.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
rm -rf ${serverPath}/pgadmin
|
||||
# rm -rf /var/lib/pgadmin
|
||||
# rm -rf /var/log/pgadmin
|
||||
echo '卸载完成'
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_pgadmin $2
|
||||
else
|
||||
Uninstall_pgadmin $2
|
||||
fi
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
function pgPost(method,args,callback){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'pgadmin', func:method, args:_args}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
function pgAsyncPost(method,args){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
return syncPost('/plugins/run', {name:'pgadmin', func:method, args:_args});
|
||||
}
|
||||
|
||||
function homePage(){
|
||||
pgPost('get_home_page', '', function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (!rdata.status){
|
||||
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
var con = '<button class="btn btn-default btn-sm" onclick="window.open(\'' + rdata.data + '\')">主页</button>';
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//phpmyadmin安全设置
|
||||
function safeConf() {
|
||||
pgPost('get_pg_option', {}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
if (!rdata.status){
|
||||
layer.msg(rdata.msg,{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
var cfg = rdata.data;
|
||||
var con = '<div class="ver line">\
|
||||
<span class="tname">访问端口</span>\
|
||||
<input style="width:110px" class="bt-input-text phpmyadmindk mr20" name="Name" id="pmport" value="' + cfg['port'] + '" placeholder="pgadmin访问端口" maxlength="5" type="number">\
|
||||
<button class="btn btn-success btn-sm" onclick="setPgPort()">保存</button>\
|
||||
</div>\
|
||||
<div class="ver line">\
|
||||
<span class="tname">用户名</span>\
|
||||
<input style="width:110px" class="bt-input-text mr20" name="username" id="pmport" value="' + cfg['username'] + '" placeholder="认证用户名" type="text">\
|
||||
<button class="btn btn-success btn-sm" onclick="setPgUsername()">保存</button>\
|
||||
</div>\
|
||||
<div class="ver line">\
|
||||
<span class="tname">密码</span>\
|
||||
<input style="width:110px" class="bt-input-text mr20" name="password" id="pmport" value="' + cfg['password'] + '" placeholder="密码" type="text">\
|
||||
<button class="btn btn-success btn-sm" onclick="setPgPassword()">保存</button>\
|
||||
</div>\
|
||||
<hr/>\
|
||||
<div class="ver line">pgadmin登录信息</div>\
|
||||
<div class="ver line">\
|
||||
<span class="tname">PG登录用户名</span>\
|
||||
<input style="width:110px" class="bt-input-text mr20" name="username" id="pmport" value="' + cfg['web_pg_username'] + '" placeholder="PG登录用户名" type="text">\
|
||||
<button class="btn btn-success btn-sm" onclick="setPgUsername()">保存</button>\
|
||||
</div>\
|
||||
<div class="ver line">\
|
||||
<span class="tname">PG登录密码</span>\
|
||||
<input style="width:110px" class="bt-input-text mr20" name="password" id="pmport" value="' + cfg['web_pg_password'] + '" placeholder="PG登录密码" type="text">\
|
||||
<button class="btn btn-success btn-sm" onclick="setPgPassword()">保存</button>\
|
||||
</div>';
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
function setPgUsername(){
|
||||
var username = $("input[name=username]").val();
|
||||
pgPost('set_pg_username',{'username':username}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
|
||||
function setPgPassword(){
|
||||
var password = $("input[name=password]").val();
|
||||
pgPost('set_pg_password',{'password':password}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
|
||||
//修改phpmyadmin端口
|
||||
function setPgPort() {
|
||||
var pmport = $("#pmport").val();
|
||||
if (pmport < 80 || pmport > 65535) {
|
||||
layer.msg('端口范围不合法!', { icon: 2 });
|
||||
return;
|
||||
}
|
||||
var data = 'port=' + pmport;
|
||||
|
||||
pgPost('set_pg_port',data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
python_ver=`ls /www/server/pgadmin/run/lib/ | grep python | cut -d \ -f 1 | awk 'END {print}'`
|
||||
|
||||
email=$1
|
||||
email_pwd=$2
|
||||
|
||||
expect <<-EOF
|
||||
set time 10
|
||||
spawn gunicorn --bind unix:/tmp/pgadmin4.sock \
|
||||
--workers=1 \
|
||||
--threads=25 \
|
||||
--chdir /www/server/pgadmin/run/lib/${python_ver}/site-packages/pgadmin4 pgAdmin4:app
|
||||
expect {
|
||||
"Email address:" { send "${email}\r"; exp_continue }
|
||||
"Password" { send "${email_pwd}\r"; exp_continue }
|
||||
"Retype password" { send "${email_pwd}\r" }
|
||||
}
|
||||
expect eof
|
||||
EOF
|
||||
|
||||
pids=$(ps aux | grep 'pgAdmin4:app' | grep -v grep | awk '{print $2}')
|
||||
arr=($pids)
|
||||
for p in ${arr[@]}
|
||||
do
|
||||
kill -9 $p > /dev/null 2>&1
|
||||
done
|
||||
|
||||
|
||||
Executable
+154
@@ -0,0 +1,154 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import shutil
|
||||
|
||||
# reload(sys)
|
||||
# sys.setdefaultencoding('utf8')
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
if mw.isAppleSystem():
|
||||
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
||||
info = mw.execShell(cmd)
|
||||
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
||||
sys.path.append(p)
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'php'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return '/etc/opt/remi'
|
||||
|
||||
|
||||
def getInitDFile(version):
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return '/tmp/' + getPluginName()
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
return '/etc/rc.d/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName() + version
|
||||
|
||||
|
||||
def getConf(version):
|
||||
path = getServerDir() + '/php' + version + '/php.ini'
|
||||
return path
|
||||
|
||||
|
||||
def getFpmConfFile(version):
|
||||
return getServerDir() + '/php' + version + '/php-fpm.d/mw.conf'
|
||||
|
||||
|
||||
def getPhpSocket(version):
|
||||
path = getFpmConfFile(version)
|
||||
content = mw.readFile(path)
|
||||
rep = 'listen\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def status(version):
|
||||
# ps -ef|grep 'php/81' |grep -v grep | grep -v python | awk '{print $2}
|
||||
cmd = "ps -ef|grep 'remi/php" + version + "' |grep -v grep | grep -v python | awk '{print $2}'"
|
||||
data = mw.execShell(cmd)
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def getFpmAddress(version):
|
||||
fpm_address = '/var/opt/remi/php{}/run/php-fpm/www.sock'.format(version)
|
||||
php_fpm_file = getFpmConfFile(version)
|
||||
try:
|
||||
content = readFile(php_fpm_file)
|
||||
tmp = re.findall(r"listen\s*=\s*(.+)", content)
|
||||
if not tmp:
|
||||
return fpm_address
|
||||
if tmp[0].find('sock') != -1:
|
||||
return fpm_address
|
||||
if tmp[0].find(':') != -1:
|
||||
listen_tmp = tmp[0].split(':')
|
||||
if bind:
|
||||
fpm_address = (listen_tmp[0], int(listen_tmp[1]))
|
||||
else:
|
||||
fpm_address = ('127.0.0.1', int(listen_tmp[1]))
|
||||
else:
|
||||
fpm_address = ('127.0.0.1', int(tmp[0]))
|
||||
return fpm_address
|
||||
except:
|
||||
return fpm_address
|
||||
|
||||
|
||||
def getPhpinfo(version):
|
||||
stat = status(version)
|
||||
if stat == 'stop':
|
||||
return 'PHP[' + version + ']未启动,不可访问!!!'
|
||||
|
||||
sock_file = getFpmAddress(version)
|
||||
root_dir = mw.getRootDir() + '/phpinfo'
|
||||
|
||||
mw.execShell("rm -rf " + root_dir)
|
||||
mw.execShell("mkdir -p " + root_dir)
|
||||
mw.writeFile(root_dir + '/phpinfo.php', '<?php phpinfo(); ?>')
|
||||
sock_data = mw.requestFcgiPHP(sock_file, '/phpinfo.php', root_dir)
|
||||
os.system("rm -rf " + root_dir)
|
||||
phpinfo = str(sock_data, encoding='utf-8')
|
||||
return phpinfo
|
||||
|
||||
|
||||
def libConfCommon(version):
|
||||
fname = getConf(version)
|
||||
if not os.path.exists(fname):
|
||||
return mw.returnJson(False, '指定PHP版本不存在!')
|
||||
|
||||
phpini = mw.readFile(fname)
|
||||
|
||||
libpath = getPluginDir() + '/versions/phplib.conf'
|
||||
phplib = json.loads(mw.readFile(libpath))
|
||||
|
||||
libs = []
|
||||
tasks = mw.M('tasks').where(
|
||||
"status!=?", ('1',)).field('status,name').select()
|
||||
for lib in phplib:
|
||||
lib['task'] = '1'
|
||||
for task in tasks:
|
||||
tmp = mw.getStrBetween('[', ']', task['name'])
|
||||
if not tmp:
|
||||
continue
|
||||
tmp1 = tmp.split('-')
|
||||
if tmp1[0].lower() == lib['name'].lower():
|
||||
lib['task'] = task['status']
|
||||
lib['phpversions'] = []
|
||||
lib['phpversions'].append(tmp1[1])
|
||||
if phpini.find(lib['check']) == -1:
|
||||
lib['status'] = False
|
||||
else:
|
||||
lib['status'] = True
|
||||
libs.append(lib)
|
||||
return libs
|
||||
|
||||
|
||||
def get_php_info(args):
|
||||
return getPhpinfo(args['version'])
|
||||
|
||||
|
||||
def get_lib_conf(data):
|
||||
libs = libConfCommon(data['version'])
|
||||
return mw.returnData(True, 'OK!', libs)
|
||||
@@ -26,12 +26,13 @@ function phpPost(method, version, args,callback){
|
||||
},'json');
|
||||
}
|
||||
|
||||
function phpPostCallbak(method, version, args,callback){
|
||||
function phpPostCallback(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'php-yum';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_php_yum';
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
@@ -593,7 +594,7 @@ function getPHPInfo_old(version) {
|
||||
}
|
||||
|
||||
function getPHPInfo(version) {
|
||||
phpPostCallbak('get_php_info', version, {}, function(data){
|
||||
phpPostCallback('get_php_info', version, {}, function(data){
|
||||
if (!data.status){
|
||||
layer.msg(rdata.msg, { icon: 2 });
|
||||
return;
|
||||
|
||||
@@ -68,7 +68,7 @@ Install_lib()
|
||||
echo "[${LIBNAME}]" >> $extIni
|
||||
echo "zend_extension=${LIBNAME}.so" >> $extIni
|
||||
|
||||
systemctl restart php${version}-fpm
|
||||
systemctl restart php${version}-fpm
|
||||
echo '==========================================================='
|
||||
echo 'successful!'
|
||||
}
|
||||
@@ -80,7 +80,8 @@ Uninstall_lib()
|
||||
if [ -f $extIni ];then
|
||||
rm -rf $extIni
|
||||
fi
|
||||
|
||||
|
||||
systemctl restart php${version}-fpm
|
||||
echo '==============================================='
|
||||
echo 'successful!'
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH=$PATH:/opt/homebrew/bin
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sourcePath=${serverPath}/source/php
|
||||
|
||||
# https://www.sourceguardian.com/loaders.html
|
||||
|
||||
# support 52-83
|
||||
|
||||
LIBNAME=sg11
|
||||
LIBV=0
|
||||
|
||||
sysName=`uname`
|
||||
actionType=$1
|
||||
version=$2
|
||||
SG_VER=${version:0:1}.${version:1:2}
|
||||
|
||||
|
||||
SORT_LIBNAME="10-${LIBNAME}"
|
||||
extVer=`bash $curPath/lib.sh $version`
|
||||
extFile=/opt/remi/php${version}/root/usr/lib64/php
|
||||
extSoFile=$extFile/modules/${LIBNAME}.so
|
||||
cfgDir=/etc/opt/remi/php${version}/php.d
|
||||
extIni=${cfgDir}/10-${LIBNAME}.ini
|
||||
|
||||
|
||||
if [ "$sysName" == "Darwin" ];then
|
||||
BAK='_bak'
|
||||
else
|
||||
BAK=''
|
||||
fi
|
||||
|
||||
Install_lib()
|
||||
{
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
if [ "$OSNAME" == 'macos' ];then
|
||||
VERSION_ID=none
|
||||
else
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
fi
|
||||
|
||||
echo "${OSNAME}:${VERSION_ID}"
|
||||
|
||||
DEFAULT_OSNAME=linux-x86_64
|
||||
SUFFIX_NAME=lin
|
||||
if [ "$OSNAME" == 'macos' ];then
|
||||
DEFAULT_OSNAME=macosx
|
||||
SUFFIX_NAME=dar
|
||||
fi
|
||||
|
||||
if [ ! -f "$extFile" ];then
|
||||
|
||||
php_lib=$sourcePath/php_lib
|
||||
|
||||
mkdir -p $php_lib
|
||||
mkdir -p $php_lib/sg11
|
||||
|
||||
if [ ! -f $php_lib/sg11_loaders.tar.bz2 ];then
|
||||
curl -sSLo $php_lib/sg11_loaders.tar.bz2 https://www.sourceguardian.com/loaders/download/loaders.tar.bz2
|
||||
echo "cd $php_lib && tar -jxvf $php_lib/sg11_loaders.tar.bz2 -C $php_lib/sg11"
|
||||
cd $php_lib && tar -jxvf $php_lib/sg11_loaders.tar.bz2 -C $php_lib/sg11
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d $php_lib/sg11/macosx ];then
|
||||
cd $php_lib && tar -jxvf $php_lib/sg11_loaders.tar.bz2 -C $php_lib/sg11
|
||||
fi
|
||||
cd $php_lib/sg11
|
||||
|
||||
|
||||
if [ -f $php_lib/sg11/${DEFAULT_OSNAME}/ixed.${SG_VER}.${SUFFIX_NAME} ];then
|
||||
cp -rf $php_lib/sg11/${DEFAULT_OSNAME}/ixed.${SG_VER}.${SUFFIX_NAME} $extSoFile
|
||||
else
|
||||
echo 'Not supported temporarily'
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "$OSNAME" == 'macos' ];then
|
||||
xattr -c * $extSoFile
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "$extSoFile" ];then
|
||||
echo "ERROR!"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "" >> $extIni
|
||||
echo "[${LIBNAME}]" >> $extIni
|
||||
echo "extension=${LIBNAME}.so" >> $extIni
|
||||
|
||||
systemctl restart php${version}-fpm
|
||||
echo '==========================================================='
|
||||
echo 'successful!'
|
||||
}
|
||||
|
||||
|
||||
Uninstall_lib()
|
||||
{
|
||||
if [ -f $extIni ];then
|
||||
rm -rf $extIni
|
||||
fi
|
||||
|
||||
systemctl restart php${version}-fpm
|
||||
echo '==============================================='
|
||||
echo 'successful!'
|
||||
}
|
||||
|
||||
|
||||
if [ "$actionType" == 'install' ];then
|
||||
Install_lib
|
||||
elif [ "$actionType" == 'uninstall' ];then
|
||||
Uninstall_lib
|
||||
fi
|
||||
@@ -96,6 +96,20 @@
|
||||
"shell": "zend_optimizer.sh",
|
||||
"check": "ZendOptimizer"
|
||||
},
|
||||
{
|
||||
"name": "sg11",
|
||||
"versions": [
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "脚本解密",
|
||||
"msg": "用于解密SG11加密脚本!",
|
||||
"shell": "sg11.sh",
|
||||
"check": "sg11.so"
|
||||
},
|
||||
{
|
||||
"name": "ionCube",
|
||||
"versions": [
|
||||
|
||||
@@ -9,7 +9,7 @@ implicit_flush = Off
|
||||
unserialize_callback_func =
|
||||
serialize_precision = 17
|
||||
zend.enable_gc = On
|
||||
expose_php = On
|
||||
expose_php = Off
|
||||
max_execution_time = 30
|
||||
max_input_time = 60
|
||||
max_input_vars = 1000
|
||||
|
||||
@@ -9,7 +9,7 @@ implicit_flush = Off
|
||||
unserialize_callback_func =
|
||||
serialize_precision = 17
|
||||
zend.enable_gc = On
|
||||
expose_php = On
|
||||
expose_php = Off
|
||||
max_execution_time = 30
|
||||
max_input_time = 60
|
||||
max_input_vars = 1000
|
||||
|
||||
@@ -9,7 +9,7 @@ implicit_flush = Off
|
||||
unserialize_callback_func =
|
||||
serialize_precision = 17
|
||||
zend.enable_gc = On
|
||||
expose_php = On
|
||||
expose_php = Off
|
||||
max_execution_time = 30
|
||||
max_input_time = 60
|
||||
max_input_vars = 1000
|
||||
|
||||
@@ -16,7 +16,7 @@ function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)"
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
|
||||
version=8.2.21
|
||||
version=8.2.24
|
||||
PHP_VER=82
|
||||
Install_php()
|
||||
{
|
||||
@@ -57,7 +57,7 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=8cc44d51bb2506399ec176f70fe110f0c9e1f7d852a5303a2cd1403402199707
|
||||
md5_file_ok=80a5225746a9eb484475b312d4c626c63a88a037d8e56d214f30205e1ba1411a
|
||||
if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
|
||||
@@ -15,7 +15,7 @@ function version_le() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)"
|
||||
function version_lt() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"; }
|
||||
function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"; }
|
||||
|
||||
version=8.3.9
|
||||
version=8.3.12
|
||||
PHP_VER=83
|
||||
Install_php()
|
||||
{
|
||||
@@ -56,7 +56,7 @@ if [ ! -d $sourcePath/php/php${PHP_VER} ];then
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=bf4d7b8ea60a356064f88485278bd6f941a230ec16f0fc401574ce1445ad6c77
|
||||
md5_file_ok=f774e28633e26fc8c5197f4dae58ec9e3ff87d1b4311cbc61ab05a7ad24bd131
|
||||
if [ -f $sourcePath/php/php-${version}.tar.xz ];then
|
||||
md5_file=`sha256sum $sourcePath/php/php-${version}.tar.xz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
|
||||
@@ -87,8 +87,10 @@ Install_lib()
|
||||
--with-gd \
|
||||
--with-jpeg-dir \
|
||||
--with-png-dir \
|
||||
--with-freetype-dir=${serverPath}/lib/freetype_old
|
||||
# --enable-gd-jis-conv
|
||||
--with-webp-dir \
|
||||
--with-zlib-dir \
|
||||
--enable-gd-jis-conv
|
||||
# --with-freetype-dir=${serverPath}/lib/freetype_old
|
||||
# --enable-gd-native-ttf
|
||||
make clean && make && make install && make clean
|
||||
|
||||
|
||||
@@ -696,6 +696,8 @@ def setDbBackup():
|
||||
os.system(cmd)
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
def rootPwd():
|
||||
return pSqliteDb('config').where('id=?', (1,)).getField('pg_root')
|
||||
|
||||
def importDbBackup():
|
||||
args = getArgs()
|
||||
@@ -1589,6 +1591,8 @@ if __name__ == "__main__":
|
||||
print(getPgPort())
|
||||
elif func == 'set_pg_port':
|
||||
print(setPgPort())
|
||||
elif func == 'root_pwd':
|
||||
print(rootPwd())
|
||||
elif func == 'get_db_list':
|
||||
print(getDbList())
|
||||
elif func == 'add_db':
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"coexist": false,
|
||||
"install_pre_inspection":true,
|
||||
"uninstall_pre_inspection":true,
|
||||
"versions":["14","15","16"],
|
||||
"versions":["14","15","16","17"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/postgresql",
|
||||
"path":"server/postgresql",
|
||||
|
||||
@@ -7,12 +7,15 @@ rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/postgresql && bash install.sh install 16
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
action=$1
|
||||
type=$2
|
||||
|
||||
VERSION=(${type//./ })
|
||||
|
||||
pip install psycopg2-binary
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
@@ -25,7 +28,7 @@ if [ "${2}" == "" ];then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -d $curPath/versions/$2 ];then
|
||||
if [ ! -d $curPath/versions/$VERSION ];then
|
||||
echo '缺少安装脚本2...'
|
||||
exit 0
|
||||
fi
|
||||
@@ -40,7 +43,7 @@ if [ "${action}" == "uninstall" ];then
|
||||
fi
|
||||
fi
|
||||
|
||||
sh -x $curPath/versions/$2/install.sh $1
|
||||
sh -x $curPath/versions/$VERSION/install.sh $1
|
||||
|
||||
if [ "${action}" == "install" ] && [ -d $serverPath/postgresql ];then
|
||||
#初始化
|
||||
|
||||
@@ -34,10 +34,10 @@ Install_App()
|
||||
mkdir -p /home/postgres
|
||||
fi
|
||||
|
||||
if [ "$sysName" != "Darwin" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
fi
|
||||
# if [ "$sysName" != "Darwin" ];then
|
||||
# mkdir -p /var/log/mariadb
|
||||
# touch /var/log/mariadb/mariadb.log
|
||||
# fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
@@ -87,16 +87,38 @@ Install_App()
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
echo "${VERSION}" > $serverPath/postgresql/version.pl
|
||||
echo 'install successful' > $install_tmp
|
||||
echo '安装postgresql成功'
|
||||
else
|
||||
echo 'install fail' > $install_tmp
|
||||
echo '安装postgresql失败'
|
||||
rm -rf ${postgreDir}/postgresql-${VERSION}.tar.bz2
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/postgresql
|
||||
echo '卸载完成' > $install_tmp
|
||||
if [ -f /usr/lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /usr/lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/postgresql/initd/postgresql ];then
|
||||
$serverPath/postgresql/initd/postgresql stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
rm -rf $serverPath/postgresql
|
||||
fi
|
||||
|
||||
echo '卸载[postgresql]完成'
|
||||
}
|
||||
|
||||
action=$1
|
||||
|
||||
@@ -34,10 +34,10 @@ Install_App()
|
||||
mkdir -p /home/postgres
|
||||
fi
|
||||
|
||||
if [ "$sysName" != "Darwin" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
fi
|
||||
# if [ "$sysName" != "Darwin" ];then
|
||||
# mkdir -p /var/log/mariadb
|
||||
# touch /var/log/mariadb/mariadb.log
|
||||
# fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
@@ -87,16 +87,38 @@ Install_App()
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
echo "${VERSION}" > $serverPath/postgresql/version.pl
|
||||
echo 'install successful' > $install_tmp
|
||||
echo '安装postgresql成功'
|
||||
else
|
||||
echo 'install fail' > $install_tmp
|
||||
echo '安装postgresql失败'
|
||||
rm -rf ${postgreDir}/postgresql-${VERSION}.tar.bz2
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/postgresql
|
||||
echo '卸载完成' > $install_tmp
|
||||
if [ -f /usr/lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /usr/lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/postgresql/initd/postgresql ];then
|
||||
$serverPath/postgresql/initd/postgresql stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
rm -rf $serverPath/postgresql
|
||||
fi
|
||||
|
||||
echo '卸载[postgresql]完成'
|
||||
}
|
||||
|
||||
action=$1
|
||||
|
||||
@@ -13,7 +13,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
postgreDir=${serverPath}/source/postgresql
|
||||
|
||||
VERSION=16.3
|
||||
VERSION=16.4
|
||||
|
||||
# su - postgres -c "/www/server/postgresql/bin/pg_ctl start -D /www/server/postgresql/data"
|
||||
|
||||
@@ -34,10 +34,10 @@ Install_App()
|
||||
mkdir -p /home/postgres
|
||||
fi
|
||||
|
||||
if [ "$sysName" != "Darwin" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
fi
|
||||
# if [ "$sysName" != "Darwin" ];then
|
||||
# mkdir -p /var/log/mariadb
|
||||
# touch /var/log/mariadb/mariadb.log
|
||||
# fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
@@ -87,16 +87,38 @@ Install_App()
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
echo "${VERSION}" > $serverPath/postgresql/version.pl
|
||||
echo '安装成功'
|
||||
echo '安装postgresql成功'
|
||||
else
|
||||
echo '安装失败'
|
||||
echo '安装postgresql失败'
|
||||
rm -rf ${postgreDir}/postgresql-${VERSION}.tar.bz2
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/postgresql
|
||||
echo '卸载完成'
|
||||
if [ -f /usr/lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /usr/lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/postgresql/initd/postgresql ];then
|
||||
$serverPath/postgresql/initd/postgresql stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
rm -rf $serverPath/postgresql
|
||||
fi
|
||||
|
||||
echo '卸载[postgresql]完成'
|
||||
}
|
||||
|
||||
action=$1
|
||||
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
#https://www.postgresql.org/ftp/source/
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
postgreDir=${serverPath}/source/postgresql
|
||||
|
||||
VERSION=17.0
|
||||
|
||||
# su - postgres -c "/www/server/postgresql/bin/pg_ctl start -D /www/server/postgresql/data"
|
||||
|
||||
Install_App()
|
||||
{
|
||||
mkdir -p ${postgreDir}
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if id postgres &> /dev/null ;then
|
||||
echo "postgres uid is `id -u postgres`"
|
||||
echo "postgres shell is `grep "^postgres:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd postgres
|
||||
useradd -g postgres postgres
|
||||
fi
|
||||
|
||||
if [ ! -d /home/postgres ];then
|
||||
mkdir -p /home/postgres
|
||||
fi
|
||||
|
||||
# if [ "$sysName" != "Darwin" ];then
|
||||
# mkdir -p /var/log/mariadb
|
||||
# touch /var/log/mariadb/mariadb.log
|
||||
# fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ -f /proc/cpuinfo ];then
|
||||
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
|
||||
fi
|
||||
|
||||
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
|
||||
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
|
||||
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
|
||||
cpuCore="${MEM_INFO}"
|
||||
fi
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
# for stable installation
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
if [ ! -f ${postgreDir}/postgresql-${VERSION}.tar.bz2 ];then
|
||||
wget --no-check-certificate -O ${postgreDir}/postgresql-${VERSION}.tar.bz2 --tries=3 https://ftp.postgresql.org/pub/source/v${VERSION}/postgresql-${VERSION}.tar.bz2
|
||||
fi
|
||||
|
||||
if [ ! -d ${postgreDir}/postgresql-${VERSION} ];then
|
||||
cd ${postgreDir} && tar -jxvf ${postgreDir}/postgresql-${VERSION}.tar.bz2
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d $serverPath/postgresql ];then
|
||||
cd ${postgreDir}/postgresql-${VERSION} && ./configure \
|
||||
--prefix=$serverPath/postgresql \
|
||||
--with-openssl
|
||||
# --with-pgport=33206
|
||||
|
||||
echo "cd ${postgreDir}/postgresql-${VERSION} && ./configure \
|
||||
--prefix=$serverPath/postgresql \
|
||||
--with-openssl"
|
||||
# --with-pgport=33206
|
||||
make -j${cpuCore} && make install && make clean
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
echo "${VERSION}" > $serverPath/postgresql/version.pl
|
||||
echo '安装postgresql成功'
|
||||
else
|
||||
echo '安装postgresql失败'
|
||||
rm -rf ${postgreDir}/postgresql-${VERSION}.tar.bz2
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
if [ -f /usr/lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /usr/lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/postgresql.service ];then
|
||||
systemctl stop postgresql
|
||||
systemctl disable postgresql
|
||||
rm -rf /lib/systemd/system/postgresql.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/postgresql/initd/postgresql ];then
|
||||
$serverPath/postgresql/initd/postgresql stop
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/postgresql ];then
|
||||
rm -rf $serverPath/postgresql
|
||||
fi
|
||||
|
||||
echo '卸载[postgresql]完成'
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == "install" ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
@@ -15,10 +15,10 @@ databases 16
|
||||
|
||||
################################ SNAPSHOTTING #################################
|
||||
|
||||
save 900 100
|
||||
save 300 1000
|
||||
save 900 1000
|
||||
save 300 10000
|
||||
save 60 1000000
|
||||
stop-writes-on-bgsave-error yes
|
||||
stop-writes-on-bgsave-error no
|
||||
rdbcompression yes
|
||||
rdbchecksum yes
|
||||
dbfilename dump.rdb
|
||||
@@ -44,7 +44,6 @@ maxmemory-policy volatile-ttl
|
||||
|
||||
############################## APPEND ONLY MODE ###############################
|
||||
|
||||
|
||||
# appendonly no
|
||||
|
||||
# appendfsync always
|
||||
@@ -53,8 +52,7 @@ maxmemory-policy volatile-ttl
|
||||
|
||||
# appendfilename "appendonly.aof"
|
||||
|
||||
# no-appendfsync-on-rewrite no
|
||||
|
||||
no-appendfsync-on-rewrite no
|
||||
auto-aof-rewrite-percentage 100
|
||||
auto-aof-rewrite-min-size 64mb
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# sysctl -w fs.file-max=6553560
|
||||
fs.file-max = 6553560
|
||||
|
||||
net.ipv4.ip_forward = 0
|
||||
net.ipv4.conf.default.rp_filter = 1
|
||||
@@ -33,6 +35,7 @@ net.ipv4.tcp_keepalive_time = 30
|
||||
net.ipv4.ip_local_port_range = 1024 65000
|
||||
|
||||
vm.overcommit_memory=1
|
||||
vm.max_map_count = 262144
|
||||
|
||||
# error:table full, dropping packet.
|
||||
net.nf_conntrack_max = 25000000
|
||||
|
||||
@@ -42,7 +42,7 @@ def send_msg(bot, tag='ad', trigger_time=300):
|
||||
# 信号只在一个周期内执行一次|end
|
||||
|
||||
# https://t.me/gjgzs2022 | 22/m | @GJ_gzs
|
||||
# https://zhaoziyuan1.cc | web | 15/m | 2m | next,9/15 | @baleite
|
||||
# https://zhaoziyuan1.cc | web | 15/m | 2m | next,12/15 | @baleite
|
||||
# 综合包网/NG接口开户 | 28/m | 6m | next,10/28 | @aabbcx888
|
||||
# 实名认证/过人脸🕵️♀️各种账号处理✅ | 30/m| next,12/30 | @nngzs
|
||||
# 桃花资源采集| 13/m| next,1/13 | @xiaolizi1122
|
||||
|
||||
@@ -51,7 +51,7 @@ def send_msg(bot, tag='ad', trigger_time=300):
|
||||
# 信号只在一个周期内执行一次|end
|
||||
|
||||
# https://t.me/gjgzs2022 | 22/m | @GJ_gzs
|
||||
# https://zhaoziyuan1.cc | web | 15/m | 2m | next,9/15 | @baleite
|
||||
# https://zhaoziyuan1.cc | web | 15/m | 2m | next,12/15 | @baleite
|
||||
# 综合包网/NG接口开户 | 28/m | 6m | next,10/28 | @aabbcx888
|
||||
# 实名认证/过人脸🕵️♀️各种账号处理✅ | 30/m| next,12/30 | @nngzs
|
||||
# 桃花资源采集| 13/m| next,1/13 | @xiaolizi1122
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(1000);
|
||||
$.getScript( "/plugins/file?name=webhook&f=js/webhook.js",function() {
|
||||
getHookList();
|
||||
});
|
||||
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'webhook'
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getCfgFilePath():
|
||||
return getServerDir() + "/cfg.json"
|
||||
|
||||
|
||||
def getCfg():
|
||||
cfg = getCfgFilePath()
|
||||
if not os.path.exists(cfg):
|
||||
initCfg()
|
||||
|
||||
data = mw.readFile(cfg)
|
||||
data = json.loads(data)
|
||||
return data
|
||||
|
||||
|
||||
def runShellArgs(args):
|
||||
data = getCfg()
|
||||
for i in range(len(data)):
|
||||
if data[i]['access_key'] == args['access_key']:
|
||||
script_dir = getServerDir() + "/scripts"
|
||||
shellFile = script_dir + '/' + args['access_key']
|
||||
param = args['params']
|
||||
if param == '':
|
||||
param = 'no-parameters'
|
||||
|
||||
param = re.sub("\"", '', param)
|
||||
|
||||
cmd = "bash {} {} >> {}.log 2>&1 &".format(
|
||||
shellFile, param, shellFile)
|
||||
# print(cmd)
|
||||
os.system(cmd)
|
||||
data[i]['count'] += 1
|
||||
data[i]['uptime'] = int(time.time())
|
||||
mw.writeFile(getCfgFilePath(), json.dumps(data))
|
||||
return mw.returnJson(True, '运行成功!')
|
||||
return mw.returnJson(False, '指定Hook不存在!')
|
||||
@@ -945,7 +945,7 @@ function _M.match_spider(self, ua)
|
||||
end
|
||||
|
||||
-- Curl|Yahoo|HeadlessChrome|包含bot|Wget|Spider|Crawler|Scrapy|zgrab|python|java|Adsbot|DuckDuckGo
|
||||
find_spider, _ = ngx.re.match(ua, "(Yahoo|Slurp|DuckDuckGo|Semrush|Spider|Bot)", "ijo")
|
||||
find_spider, _ = ngx.re.match(ua, "(Yahoo|Slurp|DuckDuckGo|Semrush|Spider|Bot|crawler)", "ijo")
|
||||
if find_spider then
|
||||
spider_match = string.lower(find_spider[0])
|
||||
if string.find(spider_match, "yahoo", 1, true) then
|
||||
@@ -960,6 +960,8 @@ function _M.match_spider(self, ua)
|
||||
spider_name = "other"
|
||||
elseif string.find(spider_match, "bot", 1, true) then
|
||||
spider_name = "other"
|
||||
elseif string.find(spider_match, "crawler", 1, true) then
|
||||
spider_name = "other"
|
||||
end
|
||||
return true, spider_name, spider_table[spider_name]
|
||||
end
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS,POST' always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true' always;
|
||||
add_header 'Access-Control-Allow-Origin' $http_origin always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, X-Requested-With, Cache-Control' always;
|
||||
|
||||
|
||||
|
||||
#add_header Access-Control-Allow-Origin *;
|
||||
#add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
|
||||
|
||||
|
||||
#add_header Access-Control-Allow-Origin *;
|
||||
#add_header Access-Control-Allow-Methods *;
|
||||
#add_header Access-Control-Allow-Header *;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user